工厂方法模式

工厂方法模式


概念

简单工厂模式已经了解过了,它的缺点也很明显:违背开闭原则,容易造成Factory类复杂度过大。工厂方法模式可以适当解决这些问题。

  • 定义:工厂方法模式(Factory Method Pattern),定义一个创建对象的接口,让其子类来创建对象。结构图如下:

工厂方法模式

实例

下面让我们将简单工厂中的例子改写下,将GirlFactory改为接口,额外添加三个工厂类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public interface GirlFactory {
public Girl createGirl();
}
public class XiaoCaoFactory implements GirlFactory {
@Override
public Girl createGirl() {
Girl xiaoCao = new XiaoCao();
return xiaoCao;
}
}
public class XiaoHuaFactory implements GirlFactory {
@Override
public Girl createGirl() {
Girl xiaoHua = new XiaoHua();
return xiaoHua;
}
}
public class XiaoYeFactory implements GirlFactory {
@Override
public Girl createGirl() {
Girl xiaoYe = new XiaoYe();
return xiaoYe;
}
}

同时将客户端类Mother调用方式改写下

1
2
3
4
5
6
7
8
9
10
11
public class Mother {
public static void main(String[] args) {
GirlFactory factory= new XiaoCaoFactory();//可引入配置文件通过反射来实现
Girl girl = factory.createGirl();
girl.name();
girl.character();
}
}
运行结果:
我是一个漂亮的,身材棒的女孩!
我的名字是小花!

可以看到运行结果不变,不过类的数目增加了3个(项目结构复杂了),这样做的好处在哪里?答案是解耦。我们可以想想,如果需要添加新的concreteProduct时,需要怎么做。

1.建立新的Girl类(concreteProduct),比如XiaoHong、XiaoJing,让它继承于Girl接口。
2.建立新的Factory类(concreteFactory),让它继承于GirlFactory接口,通过这个Factory类来建立Girl对象。
3.改写客户端Mother,将Factory更换。

注意:在这个过程中我们并没有对原有的服务端类Factory和Product进行修改(Mother类属于客户端),而是通过java的多态特性根据需求对进行扩展(增加了concreteProduct类和concreteFactory类,没有改动原来服务端的代码,符合开闭原则,对修改关闭,对扩展开放)。

总结

缺点
  • 新增产品类时系统的类成对增加(concreteProduct与concreteFactory),增加系统的复杂度,额外的编译开销
适用场景
  • 客户端不需知道类名,只需要知道工厂就可以
  • 系统后续扩展趋势较大,用来保证系统解耦度