创建型模式之工厂模式

in HandbookDesign Patterns with 24 comments, viewed 229867 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. Game LIFE 遊戲情報

    https://gamelife.tw/portal.php

    Reply
  2. 日本片商合法授權 極道光碟屋 台中AV女優光碟店 日本片商合法授權 – AV女優光碟.名器專賣(未滿18歲禁止)

    http://avgood-store.com/

    Reply
  3. 點子數位科技有限公司

    https://spot-digital.com.tw/

    Reply
  4. XYZ專業光碟教學網站

    http://xyz.net.tw/

    Reply
  5. ロレックス デイトナ レプリカn 級 品 おすすめ サイトロレックス デイトナ レプリカs 級 スーパー コピーrolex 偽物 通販

    Reply
  6. アメ横 ロレックス コピーアメ横 ロレックス コピーロレックス 激安 怪しいロレックス スーパー コピー 買っ て みた

    Reply
  7. XYZ 國中基測

    http://xyz.net.tw/

    Reply
  8. ロレックス M116515LN レプリカロレックス M116506 偽物 116519ln スーパーコピーサブマリーナ コピー 激安

    Reply
  9. gucci風 ベルトgucciベルトコピー通販 ヴィトン ベルト コピールイ ヴィトン ベルト 激安

    Reply
  10. ロレックス 新作rolex デイトナコピーコスモグラフデイトナコピーコスモグラフデイトナコピー

    Reply
  11. エルメス iphone ケース 偽物gucci iphone ケース 偽物iphone ケース ブランド コピー

    Reply
  12. n 級 品 時計 ロレックス 偽物 買っ て み

    Reply
  13. 腕時計 レプリカ ロレックス コスモ グラフ デイトナ コピー 新品仕上げ OH済 ROLEX ロレックス DATEJUST デイトジャスト 16233G X番 10Pダイヤ SS 自動巻

    Reply
  14. outlets ロレックス 偽物 ロレックス 偽物 通販 url:https://www.iy304.com/111.html

    Reply
  15. 歐客佬精品咖啡

    https://blog.oklaocoffee.tw/

    Reply
  16. 点击"立即下载"按钮下载 Passport Photo Maker crack serial number.
    这个过程只需要几分钟。

    简单易用和直接的应用程序,使您能够快速生成并根据某些ID类型打印照片

    镜子 ---> Passport Photo Maker Full Patched

    · 版本: 9.0
    · 生成日期: February 19 2020
    · 开发人员: AMS Software
    · 下载: 8580
    · 下载类型:安全(没有洪流/没有病毒)
    · 状态:清洁(截至最后一次分析)
    · 文件大小:未知
    · 价格:免费
    · 特殊要求:无要求
    · 系统: Win 10 64 bit / Win 10 / Win 8 / Win 7 64 bit / Win 7 / Win Vista / Win XP
    · 用户评分:

    更多的软件钥匙: this way

    Reply
  17. XYZ專業光碟教學網站

    http://xyz.net.tw/

    Reply
  18. 歐客佬精品咖啡 |OKLAO COFFEE|蝦皮商城|咖啡豆|掛耳|精品咖啡|咖啡禮盒 專賣|精品麵包

    https://first-cafe.com/

    Reply
  19. XYZ專業光碟教學網站

    http://xyz.net.tw/

    Reply
  20. 按下"立即下载"按钮下载 X-VPN serial number.
    这将只是需要一些时间。

    通过一个安全的虚拟专用网络,可以隐藏您的真实IP地址和您的地理位置,重新路由您的互联网流量

    镜子 ---> X-VPN Crack Latest Version

    · 版本: 19.1.199.0
    · 生成日期: April 28 2021
    · 公司简介: Free Connected Limited
    · 下载: 25018
    · 下载类型:安全(没有洪流/没有病毒)
    · 文件状态:清理(截至最后一次分析)
    · 文件大小:未知
    · 价格:免费
    · 特殊要求:无
    · 支持的系统: Windows 10 64 bit, Windows 10, Windows 8 64 bit, Windows 8, Windows 7 64 bit, Windows 7
    · 评级:

    常用软件: here

    其他有用资源:
    Готові відповіді та знання для підручників та робочих тетрадям за предметами школьного курсу за 5-11 клас

    Reply
  21. 按"立即下载"按钮下载 Sofeh Music Studio Keygen Serial.
    这个过程只需要几秒钟。

    A rich-featured audio software utility that helps you create musical compositions, write notes on a staff, play the virtual piano, and apply filters

    镜子 ---> Sofeh Music Studio + Full Crack

    · 发布版本: 6.5.5
    · 补丁日期: February 12 2021
    · 开发人员: Ramin Jafari
    · 下载: 11417
    · 下载类型:安全(没有洪流/没有病毒)
    · 状态:清洁(截至最后一次分析)
    · 文件大小:小
    · 价格:免费
    · 特殊要求:无要求
    · 系统: Windows All
    · 评级:

    更多的软件钥匙: this way

    它可能是有趣的:
    готовые домашние задания

    Reply
  22. dvd 販売 dvd 通販 dvd 購入 アイドル dvd 販売 dvd 販売 店舗 激安 dvd 販売 映画 dvd 販売

    Reply
  23. XEvil-最好的验证码求解工具,具有无限数量的解决方案,没有线程数限制和最高精度!
    XEvil5.0支持超过12.000类型的图像验证码,包括ReCaptcha,Google captcha,Yandex captcha,Microsoft captcha,Steam captcha,SolveMedia,ReCaptcha-2和(是的!!!)ReCaptcha-3了。

    1.) 灵活: 您可以调整非标准验证码的逻辑
    2.) 简单: 只需启动XEvil,按1按钮-它将自动接受来自您的应用程序或脚本的验证码
    3.) 快: 0,01对于简单的验证码秒,关于20..40秒的ReCaptcha-2,约5。..8秒的ReCaptcha-3

    您可以将XEvil与任何SEO/SMM软件,密码检查器的任何解析器,任何分析应用程序或任何自定义脚本一起使用:
    XEvil支持大多数知名的反验证码服务 API: 2Captcha, RuCaptcha, AntiGate.com (Anti-Captcha), DeathByCaptcha, etc.

    有兴趣吗? 只需在Google"XEvil"中搜索即可获取更多信息
    你读这个-那么它的工作原理! ;)))

    http://xrumersale.site/

    问候, LolitaTip7894

    Reply
  24. ロレックス デイトナ コピー ロレックス デイトナ 偽物 ロレックス デイトナ スーパー コピー ロレックス デイトナ レプリカ

    Reply