温馨提示:查看本手记请先查看上一次发布的《工厂模式_简单工厂模式》
http://www.imooc.com/article/8661
简介
定义了一个创建对象的抽象方法,由子类决定要实例化的类
工厂方法的模式将对象的实例化推迟到子类
组成角色
- 抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。
- 具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。在java中它由具体的类来实现。
- 抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。
- 具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。
优缺点
-
优点
- 一个调用者想创建一个对象,只要知道其名称就可以了。
- 扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。
- 屏蔽产品的具体实现,调用者只关心产品的接口。
- 缺点
- 每次增加一个产品时,都需要增加一个具体类和对应的实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。
适用场景
- 当一个类不知道它所必须创建的对象的类的时候。
- 当一个类希望由它的子类来指定它所创建的对象的时候。
- 当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。
注意事项
- 作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式。有一点需要注意的地方就是复杂对象适合使用工厂模式,而简单对象,特别是只需要通过 new 就可以完成创建的对象,无需使用工厂模式。如果使用工厂模式,就需要引入一个工厂类,会增加系统的复杂度。
案例
四则运算表
大牛:“小鸟,你又没有发现,使用简单工厂去设计四则运算表的时候,其实对于LowTableFactory
类来说是违背了开闭原则的。”
小鸟:“发现了,如果我要增加其它的算法表的类,那么同时我也要去修改LowTableFactory类,给其添加一个case。”
大牛:“说的不错,对于这个问题,你有什么好的解决思路呢?”
小鸟:“我的解决方法就是,使用工厂方法模式,以下就是我的代码(以加法表和乘法表为例
)”
抽象产品角色:AFourOperations
四则运算法则
public abstract class AFourOperations {
public abstract void operations();
}
具体产品角色1:AddOperations
加法表
public class AddOperations extends AFourOperations {
@Override
public void operations() {
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= i; j++) {
System.out.print(String.format("%d+%d=%d\t", j, i, i + j));
}
System.out.println("");
}
}
}
具体产品角色2:MultiplicationOperations
乘法表
public class MultiplicationOperations extends AFourOperations {
@Override
public void operations() {
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= i; j++) {
System.out.print(String.format("%d*%d=%d\t", j, i, i * j));
}
System.out.println("");
}
}
}
抽象工厂角色:IFourOperationsFactory
工厂类
public abstract class AFourOperationsFactory {
public abstract AFourOperations createFourOperations();
}
具体工厂角色1:AddOperationsFactory
加法工厂
public class AddOperationsFactory extends AFourOperationsFactory {
@Override
public AFourOperations createFourOperations() {
return new AddOperations();
}
}
具体工厂角色2:MultiplicationOperationsFactory
乘法工厂
public class MultiplicationOperationsFactory extends AFourOperationsFactory {
@Override
public AFourOperations createFourOperations() {
return new MultiplicationOperations();
}
}
客户端调用
AFourOperationsFactory factory = new MultiplicationOperationsFactory();
AFourOperations aFourOperations = factory.createFourOperations();
aFourOperations.operations();
大牛:“嗯嗯,不错,结构很清晰!”
小鸟:“牛哥,我发现这个还不如简单工厂好用呢!这里每创建一个类,就得为其创建对应的工厂,感觉无形中增加了好多类啊!
”
大牛:“确实,这就是工厂方法模式和简单工厂的一个最大区别,工厂方法模式虽然增加了很多类,但它更符合开-闭原则,降低了客户端与后台的耦合度
”