点击进入我的博客
2.2 工厂方法模式
2.2.1 工厂方法模式简介
- 工厂方法模式是类的创建模式,又叫做虚拟构造子模式或多态性工厂模式。
- 在工厂方法模式中,核心的工厂类不再负责所有的产品的创建,而是将具体创建的工作交给子类去做。该核心类成为一个抽象工厂角色,仅负责给出具体工厂子类必须实现的接口,而不接触哪一个产品类应当被实例化这种细节。
2.2.2 工厂方法的结构
工厂方法模式- 抽象工厂(Creator)角色:担任这个角色的是工厂方法模式的核心,它是与应用程序无关的。任何在模式中创建对象的工厂类必须实现这个接口。在实际的系统中,这个角色也常常使用抽象类实现。
- 具体工厂(Concrete Creator)角色:担任这个角色的是实现了抽象工厂接口的具体JAVA类。具体工厂角色含有与业务密切相关的逻辑,并且受到应用程序的调用以创建导出类。
- 抽象产品(Product)角色:工厂方法模式所创建的对象的超类,也就是所有产品对象的共同父类或共同拥有的接口。在实际的系统中,这个角色也常常使用抽象类实现。
- 具体产品(Concrete Product)角色:这个角色实现了抽象产品(Product)角色所声明的接口,工厂方法模式所创建的每一个对象都是某个具体产品角色的实例。
abstract class Fruit {}
abstract class FruitFactory {
public abstract Fruit newInstance();
}
class Apple extends Fruit {}
class Banana extends Fruit {}
class AppleFactory extends FruitFactory {
@Override
public Fruit newInstance() {
return new Apple();
}
}
class BananaFactory extends FruitFactory {
@Override
public Fruit newInstance() {
return new Banana();
}
}
2.2.3 工厂方法模式的细节
Java中的应用
java.util.Collection
接口继承来Iterable
接口,所有其子类都必须实现Iterator<T> iterator()
方法,这个iterator()
方法就是一个工厂方法。
使用接口或者抽象类
抽象工厂角色和抽象产品角色都可以选择由Java接口或者Java抽象类来实现。
如果具体工厂角色由共同的逻辑,那么这些共同的逻辑就可以向上移动到抽象工厂角色中,这也意味着抽象工厂角色应该由抽象类实现;反之就应当由接口实现。
使用多个工厂方法
抽象工厂角色可以规定出多于一个的工厂方法,从而使具体工厂角色实现这些不同的工厂方法。
工厂方法模式的优点
- 隐藏细节:在工厂方法模式中,工厂方法用来创建客户所需要的产品,同时还向客户隐藏了哪种具体产品类将被实例化这一细节,用户只需要关心所需产品对应的工厂,无须关心创建细节,甚至无须知道具体产品类的类名。
- 多态性设计:工厂方法模式之所以又被称为多态工厂模式,是因为所有的具体工厂类都具有同一抽象父类。基于工厂角色和产品角色的多态性设计是工厂方法模式的关键,它能够使工厂可以自主确定创建何种产品对象,而如何创建这个对象的细节则完全封装在具体工厂内部。
- 完全符合开闭原则:在系统中加入新产品时,无须修改抽象工厂和抽象产品提供的接口,无须修改客户端,也无须修改其他的具体工厂和具体产品,而只要添加一个具体工厂和具体产品就可以了。
工厂方法模式的缺点
- 类数量太多:在添加新产品时,需要编写新的具体产品类,而且还要提供与之对应的具体工厂类,系统中类的个数将成对增加,在一定程度上增加了系统的复杂度,有更多的类需要编译和运行,会给系统带来一些额外的开销。
- 系统的抽象性和复杂性:由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度,且在实现时可能需要用到DOM、反射等技术,增加了系统的实现难度。
模式适用环境
- 一个类不知道它所需要的对象的类:在工厂方法模式中,客户端不需要知道具体产品类的类名,只需要知道所对应的工厂即可,具体的产品对象由具体工厂类创建;客户端需要知道创建具体产品的工厂类。
- 一个类通过其子类来指定创建哪个对象:在工厂方法模式中,对于抽象工厂类只需要提供一个创建产品的接口,而由其子类来确定具体要创建的对象,利用面向对象的多态性和里氏代换原则,在程序运行时,子类对象将覆盖父类对象,从而使得系统更容易扩展。
- 动态指定:将创建对象的任务委托给多个工厂子类中的某一个,客户端在使用时可以无须关心是哪一个工厂子类创建产品子类,需要时再动态指定,可将具体工厂类的类名存储在配置文件或数据库中。
2.2.4 工厂方法模式与其他模式
简单工厂模式
- 工厂方法模式和简单工厂模式在结构上的不同很明显。工厂方法模式的核心是一个抽象工厂类,而简单工厂模式把核心放在一个具体类上。
- 如果系统需要加入一个新的导出类型,那么所需要的就是向系统中加入一个这个导出类以及所对应的工厂类。没有必要修改客户端,也没有必要修改抽象工厂角色或者其他已有的具体工厂角色。对于增加新的导出类型而言,这个系统完全支持“开-闭原则”。
模板方法模式
工厂方法模式常常与模版方法模式一起联合使用。原因其实不难理解:第一,两个模式都是基于方法的,工厂方法模式是基于多态性的工厂方法的,而模版方法模式是基于模版方法和基本方法的;第二,两个模式都将具体工作交给子类。工厂方法模式将创建工作推延给子类,模版方法模式将剩余逻辑交给子类。
MVC模式
MVC工厂方法模式总是涉及到两个等级结构中的对象,而这两个等级结构可以分别是MVC中的控制器和试图。一个MVC模式可以有多个控制器和多个视图。
如果系统内只需要一个控制器,那么可以简化为简单工厂模式。
享元模式
享元模式使用了带有循环逻辑的工厂方法。
网友评论