创建型模式之工厂模式

in HandbookDesign Patterns with 50 comments, viewed 159126 times

1 概述

创建型模式,提供了一种创建对象的最佳实践。工厂方法模式(Factory Method Pattern)的核心思想,是通过统一的工厂类来获取对象,而不需要调用类的构造方法。

2 优点

  1. 可以将类的实例化过程延缓到子类。调用者无需知道接口/抽象类的具体实现是什么,利用工厂方法即可获取类的实例,降低与调用者的耦合度。
  2. 隐藏类的构造细节,降低类创建的复杂度,提高程序可读性。
  3. 可以根据不同环境/参数,从工厂构造不同的方法。

3 案例

有一个饭店的接口,饭店里有厨师和服务员。我们定义KFCPizzaHut两个饭店:

interface Restaurant {
    void getCook();
    void getWaiter();
}

public class KFC implements Restaurant {

    @Override
    public void getCook() {
        System.out.println("I'm KFC cook.");
    }

    @Override
    public void getWaiter() {
        System.out.println("I'm KFC waiter.");
    }
}

class PizzaHut implements Restaurant {

    @Override
    public void getCook() {
        System.out.println("I'm PizzaHut cook.");
    }

    @Override
    public void getWaiter() {
        System.out.println("I'm PizzaHut waiter.");
    }
}

3.1 工厂类型1

再定义一个工厂方法RestaurantFactory,从工厂中,很容易就能根据类型获取对应的饭店:

public class Test {
    public static void main(String[] args) {
        RestaurantFactory factory = new RestaurantFactory();
        Restaurant kfc = factory.createRestaurant(RestaurantFactory.RestaurantType.KFC);
        Restaurant pizzaHut = factory.createRestaurant(RestaurantFactory.RestaurantType.PizzaHut);
        kfc.getCook();
        pizzaHut.getWaiter();
    }
}

class RestaurantFactory {
    enum RestaurantType {
        KFC, PizzaHut
    }

    Restaurant createRestaurant(RestaurantType type) {
        switch (type) {
            case KFC: return new KFC();
            case PizzaHut: return new PizzaHut();
            default: System.out.format("Invalid restaurant %s", type); return null;
        }
    }
}

输出:

I'm KFC cook.
I'm PizzaHut waiter.

UML:
UML for factory type1

比如Spring中的BeanFactory使用的就是这种模式:getBean方法用Bean类型/名字作为参数,返回对应的Bean
JDK中的Calendar类,也是用的这种模式:

public static Calendar getInstance(TimeZone zone, Locale aLocale) {
    ...
    // 根据参数创建不同的Calendar实例
    if (aLocale.hasExtensions()) {
        String caltype = aLocale.getUnicodeLocaleType("ca");
        if (caltype != null) {
            switch (caltype) {
            case "buddhist":
            cal = new BuddhistCalendar(zone, aLocale);
                break;
            case "japanese":
                cal = new JapaneseImperialCalendar(zone, aLocale);
                break;
            case "gregory":
                cal = new GregorianCalendar(zone, aLocale);
                break;
            }
        }
    }
    ...
}

如果实例类型相对固定,那么上述模式能很好的满足需求。但是如果实例类型不确定,那么每当需要新增类型的时候,都需要改动原先的方法,对开闭原则遵循得不好。于是有了第二种类型。

3.2 工厂类型2

依然是饭店的例子,我们通过如下方式定义工厂:

public class Test {
    public static void main(String[] args) {
        KFCFactory kfcFactory = new KFCFactory();
        PizzaHutFactory pizzaHutFactory = new PizzaHutFactory();
        Restaurant kfc = kfcFactory.createRestaurant();
        Restaurant pizzaHut = pizzaHutFactory.createRestaurant();
        kfc.getCook();
        pizzaHut.getWaiter();
    }
}

class KFCFactory {
    Restaurant createRestaurant() {
        return new KFC();
    }
}

class PizzaHutFactory {
    Restaurant createRestaurant() {
        return new PizzaHut();
    }
}

输出:

I'm KFC cook.
I'm PizzaHut waiter.

UML:
UML for factory type2

上述方式,每新增一个类别,只需要新增一个对应的工厂即可,原先的工厂方法以及实例无需做任何修改。如LoggerFactory)就是这种类型的工厂模式:

public static Logger getLogger(String name) {
    // getLogger最终是委托给ILoggerFactory去做的。
    // 新增Logger获取方式,只需新增ILoggerFactory的实现类,扩展性很强。
    ILoggerFactory iLoggerFactory = getILoggerFactory();
    return iLoggerFactory.getLogger(name);
}

但是这种方式,对每一种类别,都要有一个工厂类,复杂度相对较高。实际中,还是第一种类型使用比较频繁。

4 总结

工厂方法模式是使用很广泛的一种创建型模式,几乎能在所有的开源框架中见到。很典型的特点就是,工厂类以Factory字样结尾:-)。

文中例子的github地址

Responses
  1. 让你的钱成长为资本与这个机器人。
    链接 - https://moneylinks.page.link/6SuK

    Reply
  2. 在线工作可以为您带来梦幻般的利润。
    链接 - https://moneylinks.page.link/6SuK

    Reply
  3. 每个需要钱的人都应该尝试这个机器人。
    链接 - https://moneylinks.page.link/6SuK

    Reply
  4. 没有钱? 这很容易在网上earn他们在这里。
    链接 - https://moneylinks.page.link/6SuK

    Reply
  5. 小额投资可以快速带来大量美元。
    链接 - https://moneylinks.page.link/6SuK

    Reply
  6. 现在在网上making钱更容易。
    链接 - - https://moneylinks.page.link/6SuK

    Reply
  7. 搪瓷浴在波多利斯克价格

    Reply
  8. 在线工作可以为您带来梦幻般的利润。
    链接 - - https://moneylinks.page.link/6SuK

    Reply
  9. 相信你的美元的机器人,看看它是如何增长到$100。
    链接 - - https://moneylinks.page.link/6SuK

    Reply
  10. 尝试自动机器人,以保持整天的收入。
    链接 - https://moneylinks.page.link/6SuK

    Reply
  11. 只需点击一下鼠标就可以把你的美元变成1000美元。
    链接 - https://moneylinks.page.link/6SuK

    Reply
  12. 多莫杰多沃恢复浴场

    Reply
  13. 没有投资的巨额收入是可用的,现在!
    链接 - https://cloud.mail.ru/public/3aiX/3nmSXD3HL

    Reply
  14. 金融机器人是你的成功公式被发现。 了解更多关于它。
    链接 - https://moneylinks.page.link/6SuK

    Reply
  15. 让你的钱包厚的最快方法就在这里。
    链接 - - http://www.google.com/url?q=%68%74%74%70%73%3A%2F%2F%68%64%72%65%64%74%75%62%65%33%2e%6d%6f%62%69%2F%62%74%73%6d%61%72%74%23%58%46%67%4b%76%49%58%56%56%44%52%55%68%50%6e%65%53&sa=D&sntz=1&usg=AFQjCNHYDN8-riQChlXWiJOFmJgZUuju0Q

    Reply
  16. 赚取额外的钱没有努力.
    链接 - https://moneylinks.page.link/6SuK

    Reply
  17. 赚钱是很容易的,如果你使用金融机器人。
    链接 - - https://moneylinks.page.link/6SuK

    Reply
  18. 金融机器人是#1投资工具永远。 发射!
    链接 - https://moneylinks.page.link/6SuK

    Reply
  19. 每一个你的美元可以变成$100你午饭后这个机器人。
    链接 - - http://www.google.com/url?q=%68%74%74%70%73%3A%2F%2F%68%64%72%65%64%74%75%62%65%33%2e%6d%6f%62%69%2F%62%74%73%6d%61%72%74%23%70%65%4c%62%5a%4d%46%4d%59%49%69%6a%6a%44%57%63%73&sa=D&sntz=1&usg=AFQjCNHD62BMkoM6sT_Cv6lyYttsZ8c4JA

    Reply
  20. 额外的收入现在可用于世界各地的任何人。
    链接 - https://moneylinks.page.link/6SuK

    Reply
  21. 启动金融机器人,做你的生意。
    链接 - - https://moneylinks.page.link/6SuK

    Reply
  22. 相信你的美元的机器人,看看它是如何增长到$100。
    链接 - https://moneylinks.page.link/6SuK

    Reply
  23. 看看机器人如何使$1000从$1投资.
    链接 - - https://moneylinks.page.link/6SuK

    Reply
  24. 额外的收入是提供给大家使用这个机器人。
    链接 - https://moneylinks.page.link/6SuK

    Reply
  25. 没有必要再找一份工作。 在线工作。
    链接 - - https://moneylinks.page.link/6SuK

    Reply
  26. 在线工作可以为您带来梦幻般的利润。
    链接 - - https://moneylinks.page.link/6SuK

    Reply
  27. 找到最快的方法,使你的钱包厚。
    链接 - https://moneylinks.page.link/6SuK

    Reply
  28. 我们已经找到了致富的最快方法。 在这里找到它。
    链接 - - https://moneylinks.page.link/6SuK

    Reply
  29. 额外的收入是提供给大家使用这个机器人。
    链接 - https://moneylinks.page.link/6SuK

    Reply
  30. 为你的家人提供这笔钱的年龄。 启动机器人!
    链接 - - https://moneylinks.page.link/6SuK

    Reply
  31. 有钱人是有钱的,因为他们使用这个机器人。
    链接 - - https://moneylinks.page.link/6SuK

    Reply
  32. 我们知道如何变得富有,你呢?
    链接 - http://www.google.com/url?q=%68%74%74%70%3A%2F%2F%72%65%69%64%61%69%66%6f%73%74%69%68%69%6e%2e%6d%6c%23%69%56%53%59%57%6b%4d%53%78%4f%6a%55%72%74%45&sa=D&sntz=1&usg=AFQjCNHCbxOEE2MYjDoJY5T673h-UaG-Ig

    Reply
  33. 每一个你的美元可以变成$100你午饭后这个机器人。
    链接 - http://www.google.com/url?q=%68%74%74%70%3A%2F%2F%72%65%69%64%61%69%66%6f%73%74%69%68%69%6e%2e%6d%6c%23%70%70%61%61%71%6d%65%73%55%63%65%74%59%4e%45&sa=D&sntz=1&usg=AFQjCNGCi_60ZBUd_EXFrt1gxfKcBwnwaQ

    Reply
  34. 让你的笔记本电脑与此程序的金融工具。
    链接 - http://www.google.com/url?q=%68%74%74%70%3A%2F%2F%72%65%69%64%61%69%66%6f%73%74%69%68%69%6e%2e%6d%6c%23%57%4f%67%49%42%6b%6c%64%71%79%67%62%52%6e%4b&sa=D&sntz=1&usg=AFQjCNGtVY-aSB1fgJCwmOpEt65dgttqvw

    Reply
  35. 金融机器人是富人的最佳伴侣。
    链接 - http://www.google.com/url?q=%68%74%74%70%3A%2F%2F%72%65%69%64%61%69%66%6f%73%74%69%68%69%6e%2e%6d%6c%23%4c%62%6a%45%77%76%64%59%57%57%42%78%77%78%62&sa=D&sntz=1&usg=AFQjCNE2TVUIsakTdnNa18sLeA00AzmXDQ

    Reply
  36. 哇塞! 这个机器人是一个在线职业生涯的良好开端。
    链接 - http://www.google.com/url?q=%68%74%74%70%3A%2F%2F%72%65%69%64%61%69%66%6f%73%74%69%68%69%6e%2e%6d%6c%23%4f%50%4f%64%71%4a%69%56%66%4c%68%63%55%79%4f&sa=D&sntz=1&usg=AFQjCNEAzNIu5IrSSGPQipGbBAzLCYrI_Q

    Reply
  37. 你的钱工作,即使你睡觉。
    链接 - http://www.google.com/url?q=%68%74%74%70%3A%2F%2F%72%65%69%64%61%69%66%6f%73%74%69%68%69%6e%2e%6d%6c%23%6c%66%67%67%4e%74%57%4f%4e%65%66%52%4b%6e%6b&sa=D&sntz=1&usg=AFQjCNGNOMCT6pfzSg-DGkODgy5nJUbyTw

    Reply
  38. 相信你的美元的机器人,看看它是如何增长到$100。
    链接 - http://www.google.com/url?q=%68%74%74%70%3A%2F%2F%72%65%69%64%61%69%66%6f%73%74%69%68%69%6e%2e%6d%6c%23%4a%54%4d%42%4c%6e%5a%50%64%56%41%6f%77%46%4b&sa=D&sntz=1&usg=AFQjCNHvCHQSaUj0E9JQrtn9e9e5fWc6Hw

    Reply
  39. 钱,钱! 赚更多的钱与金融机器人!
    链接 - - https://moneylinks.page.link/6SuK

    Reply
  40. 让成千上万的每周在线工作在这里。
    链接 - http://www.google.com/url?q=%68%74%74%70%3A%2F%2F%72%65%69%64%61%69%66%6f%73%74%69%68%69%6e%2e%6d%6c%23%71%69%67%53%43%6c%59%54%44%50%53%41%51%79%65&sa=D&sntz=1&usg=AFQjCNFR7NvvWLP_QhgE0nh2TVqwgfJ5AA

    Reply
  41. 随意购买你想要的额外收入的一切。
    链接 - http://www.google.com/url?q=%68%74%74%70%3A%2F%2F%72%65%69%64%61%69%66%6f%73%74%69%68%69%6e%2e%6d%6c%23%51%6d%79%68%6d%49%71%79%52%77%63%6a%74%56%56&sa=D&sntz=1&usg=AFQjCNGQi0lwUMjn1OEWAFSzpsZiArRn6g

    Reply
  42. 期待收入? 上网吧
    链接 - http://www.google.com/url?q=%68%74%74%70%3A%2F%2F%72%65%69%64%61%69%66%6f%73%74%69%68%69%6e%2e%6d%6c%23%56%70%67%6d%7a%7a%73%6e%79%55%76%78%72%5a%47&sa=D&sntz=1&usg=AFQjCNGCXLtlIZwlZYvyisJmt58l6q5V8Q

    Reply
  43. 这个机器人可以给你带来钱24/7。
    链接 - http://www.google.com/url?q=%68%74%74%70%3A%2F%2F%72%65%69%64%61%69%66%6f%73%74%69%68%69%6e%2e%6d%6c%23%5a%64%54%43%61%51%57%46%4d%55%51%42%6c%42%75&sa=D&sntz=1&usg=AFQjCNEWRH2d21fO3kAd6T7m2J9kVPFIvA

    Reply
  44. 在线工作可以为您带来梦幻般的利润。
    链接 - - http://www.google.com/url?q=%68%74%74%70%3A%2F%2F%72%65%69%64%61%69%66%6f%73%74%69%68%69%6e%2e%6d%6c%23%47%78%67%6f%53%74%4e%79%57%53%4e%63%6c%6a%57&sa=D&sntz=1&usg=AFQjCNHND3DPFe6Ec9hLntlO5vkqOAou1Q

    Reply
  45. 这个机器人可以给你带来钱24/7。
    链接 - http://www.google.com/url?q=%68%74%74%70%3A%2F%2F%72%65%69%64%61%69%66%6f%73%74%69%68%69%6e%2e%6d%6c%23%7a%6b%6c%79%56%49%64%7a%79%51%67%50%4f%48%44&sa=D&sntz=1&usg=AFQjCNGFbouCEQEUh75bgfD83M0tQbGEoQ

    Reply
  46. 金融机器人保证每个人的稳定性和收入。
    链接 - https://moneylinks.page.link/6SuK

    Reply
  47. 即使是一个孩子知道如何使$100今天这个机器人的帮助。
    链接 - - https://moneylinks.page.link/6SuK

    Reply
  48. 这是启动机器人以获得更多的钱的最佳时机。
    链接 - https://moneylinks.page.link/6SuK

    Reply
  49. 了解财务独立的最快方法。
    链接 - - https://moneylinks.page.link/6SuK

    Reply
  50. 了解money钱的最简单的方法。
    链接 - https://moneylinks.page.link/6SuK

    Reply