工厂方法模式概述
工厂方法模式是为了弥补简单工厂模式的不足并且继承它的优点而延生出的一种设计模式,属于GoF中的一种。其好处是可以使系统在不修改原来代码的情况下引进新的产品,即满足开闭原则。
- 定义:定义了一个用于创建对象的接口,但是让子类决定将哪一个类实例化。即让类的实例化延迟到子类
- 举例:大众汽车公司想必大家都不陌生,它旗下也有不少汽车品牌。大众汽车公司就好比一个汽车工厂,负责生产和销售汽车。它可以为客户提供一个客户需要的汽车。但是,如果客户需要的汽车大众公司目前还没有,但是公司想要盈利,就必须为此而设计汽车,在这种情况下,大众公司就要新添加一种汽车,同时要修改公司内部的生产环境(也就是工厂类的代码)。这就是简单工厂模式的运行情况。简单而言,就是工厂类(汽车公司)什么都要干,要修改必须大动干戈。因而一定程度上违背了开闭原则。而工厂方法模式则不一样,大众汽车公司不在总公司生产汽车,而是成立分公司,收购别的公司,成立具有针对性的汽车工厂专门生产对应的汽车。若客户的大量需求得不到满足,则总公司就另外成立新的二级公司(新品牌汽车的工厂)生产汽车,从而在不修改具体工厂的情况下引进新的产品。正如大众集团的收购一样。
- 以下为简单工厂模式和工厂方法模式的区别:
优点和缺点
优点
- 用户只需要关心产品对应的工厂,甚至无需关心创建细节或具体产品类的类名
- 基于工厂角色和产品的多态性设计是工厂模式的关键。它能自主决定如何创建哪种产品对象,而创建细节都封装在具体工厂内部
- 在系统要添加新的产品时,无需修改抽象工厂和抽象产品提供的接口,无需修改客户端,也无需修改其他的具体工厂和具体产品,只要添加一个具体工厂和具体产品即可,从而提高系统的可扩展性(符合开闭原则)
抽象工厂类通过子类来指定创建那哪个对象。即抽象工厂类只需要提供一个创建产品的接口,而由其子类确定具体要创建的对象,利用多态性和里氏代换原则,子类对象将覆盖父类对象,从而使系统更容易扩展
缺点
在添加新产品时,要编写新的具体产品类,并要提供与之对应的具体工厂类。系统软件个数也成对增加,从而增加了系统的复杂度,带来更多开销
由于系统的可扩展性,在客户端中要引入抽象层进行定义,从而增加了系统的抽象性和理解难度
应用场景
客户只知道创建产品的工厂名,而不知道具体的产品名。如 TCL 电视工厂、海信电视工厂等。
- 创建对象的任务由多个具体子工厂中的某一个完成,而抽象工厂只提供创建产品的接口。
- 客户不关心创建产品的细节,只关心产品的品牌
模式的结构与实现
工厂方法模式的主要角色如下。
- 抽象工厂(Abstract Factory):它声明了工厂方法,用于返回一个产品。工厂方法模式的核心,所有创建对象的工厂必须实现该接口(创建生产汽车的工厂)
- 具体工厂(ConcreteFactory):抽象工厂类的子类,实现了抽象工厂中声明的工厂方法,返回一个具体产品类的实例(对应具体的某一个汽车工厂)
- 抽象产品(Product):定义产品的接口,是工厂方法模式所创建对象的公共父类(生产汽车)
- 具体产品(ConcreteProduct):实现了抽象产品的接口,某类型的具体产品由专门的工厂创建(如具体类型的汽车)


