1.工厂方法模式
定义一个用于创建对象的接口,让子类决定实例化哪个类。工厂方法模式使一个类的实例化延迟到其子类。
2.结构图
我们先看看标准的工厂方法结构图:
![](https://img-blog.csdn.net/20170310164213401?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveHVlbWVuZ3J1aTEy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
工厂方法模式的结构中包括四种角色:
● 抽象产品(Product):抽象类或接口,负责定义具体产品必须实现的方法。
● 具体产品(ConcreteProduct):如果Product是一个抽象类,那么具体产品是Product的子类;如果Product是一个接口,那么具体产品是实现Product接口的类。
● 构造者(Creator):一个接口或抽象类,构造者负责定义一个称作工厂方法的抽象方法,该方法返回具体产品类的实例。
● 具体构造者(ConcreteCreator):如果构造者是抽象类,具体构造者是构造者的子类;如果构造者是接口,具体构造者是实现构造者接口的类。具体构造者重写工厂方法,使该方法返回具体产品的实例。
3.简单工厂vs.工厂方法
我们前面说过简单工厂模式,简单工厂模式的最大优点在于工厂类中包含了必要逻辑判断,根据客户端的选择条件动态实例化相关类,对于客户端来说,去除了与具体产品的依赖;然而缺点就是当我们要添加功能类时,就必须修改工厂类,这违反了“开放-封闭”原则,使得具体产品与工厂类之间的耦合度过高,严重影响了系统的灵活性和扩展性。而在工厂方法模式中,我们不再提供一个统一的工厂类来创建所有的产品对象,而是针对不同的产品提供不同的工厂,这导致增加了很多类和方法,客户端的复杂性增加了,但是有失就有所得,这样整个工厂和产品体系都没有修改的变化,而只是扩展的变化,这完全符合“开放-封闭”原则。
某种程度上,工厂方法模式改变了我们直接用new创建对象的方式。
4.Java集合框架与工厂模式
Java集合框架中有一个重要的接口Collection,该接口中的iterator()方法就是一个工厂方法。iterator()方法返回一个实现Iterator接口类的实例,按照工厂方法模式的角色分类,Iterator接口是抽象产品角色,Collection接口是构造者,而所有实现Collection接口的类,即集合都是具体构造者。
下面写个例子
总结
工厂方法模式的主要优点如下:
● 在工厂方法模式中,工厂方法用来创建客户化产品,向客户隐藏产品实例化细节,用户只需要关心所需产品对应的工厂,无须关心创建细节。
● 基于工厂角色和产品角色的多态性设计是工厂方法模式的关键,它能够让工厂可以自主确定创建何种产品对象,而如何创建这个对象的细节则完全封装在具体工厂内部。
● 在系统中加入新产品时,无须修改抽象工厂和抽象产品提供的接口,无须修改客户端,也无须修改其他的具体工厂和具体产品,完全符合“开闭原则”。
工厂方法模式的主要缺点如下:
● 在添加新产品时,需要编写新的具体产品类,而且还要提供与之对应的具体工厂类,系统中类的个数将成对增加,在一定程度上增加了系统的复杂度,有更多的类需要编译和运行,会给系统带来一些额外的开销。
定义一个用于创建对象的接口,让子类决定实例化哪个类。工厂方法模式使一个类的实例化延迟到其子类。
2.结构图
我们先看看标准的工厂方法结构图:
工厂方法模式的结构中包括四种角色:
● 抽象产品(Product):抽象类或接口,负责定义具体产品必须实现的方法。
● 具体产品(ConcreteProduct):如果Product是一个抽象类,那么具体产品是Product的子类;如果Product是一个接口,那么具体产品是实现Product接口的类。
● 构造者(Creator):一个接口或抽象类,构造者负责定义一个称作工厂方法的抽象方法,该方法返回具体产品类的实例。
● 具体构造者(ConcreteCreator):如果构造者是抽象类,具体构造者是构造者的子类;如果构造者是接口,具体构造者是实现构造者接口的类。具体构造者重写工厂方法,使该方法返回具体产品的实例。
3.简单工厂vs.工厂方法
我们前面说过简单工厂模式,简单工厂模式的最大优点在于工厂类中包含了必要逻辑判断,根据客户端的选择条件动态实例化相关类,对于客户端来说,去除了与具体产品的依赖;然而缺点就是当我们要添加功能类时,就必须修改工厂类,这违反了“开放-封闭”原则,使得具体产品与工厂类之间的耦合度过高,严重影响了系统的灵活性和扩展性。而在工厂方法模式中,我们不再提供一个统一的工厂类来创建所有的产品对象,而是针对不同的产品提供不同的工厂,这导致增加了很多类和方法,客户端的复杂性增加了,但是有失就有所得,这样整个工厂和产品体系都没有修改的变化,而只是扩展的变化,这完全符合“开放-封闭”原则。
某种程度上,工厂方法模式改变了我们直接用new创建对象的方式。
4.Java集合框架与工厂模式
Java集合框架中有一个重要的接口Collection,该接口中的iterator()方法就是一个工厂方法。iterator()方法返回一个实现Iterator接口类的实例,按照工厂方法模式的角色分类,Iterator接口是抽象产品角色,Collection接口是构造者,而所有实现Collection接口的类,即集合都是具体构造者。
下面写个例子
public class Application {
public static void main(String[] args) {
Collection<String> list=new ArrayList<>();
for (int i=0;i<8;i++)
list.add("list"+i);
Iterator<String> iterator=list.iterator();
while (iterator.hasNext())
System.out.println(iterator.next());
Collection<Integer> list1=new LinkedList<>();
for (int i=0;i<8;i++)
list1.add(new Integer(i));
Iterator<Integer> iterator1=list1.iterator();
while (iterator1.hasNext())
System.out.println(iterator1.next());
}
}
上例中ArrayList和LinkedList类就是具体的构造者, Iterator<String>和Iterator<Integer>是对应的产品类。
总结
工厂方法模式的主要优点如下:
● 在工厂方法模式中,工厂方法用来创建客户化产品,向客户隐藏产品实例化细节,用户只需要关心所需产品对应的工厂,无须关心创建细节。
● 基于工厂角色和产品角色的多态性设计是工厂方法模式的关键,它能够让工厂可以自主确定创建何种产品对象,而如何创建这个对象的细节则完全封装在具体工厂内部。
● 在系统中加入新产品时,无须修改抽象工厂和抽象产品提供的接口,无须修改客户端,也无须修改其他的具体工厂和具体产品,完全符合“开闭原则”。
工厂方法模式的主要缺点如下:
● 在添加新产品时,需要编写新的具体产品类,而且还要提供与之对应的具体工厂类,系统中类的个数将成对增加,在一定程度上增加了系统的复杂度,有更多的类需要编译和运行,会给系统带来一些额外的开销。
● 由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度。
参考: