前言
简单工厂模式(静态工厂模式),最为一个出镜率比较高的设计模式,相对来说比较简单,大家可以很快上手,我觉得还是举例子给大家会比较好理解也记忆。
我们首先看看它的优缺点:
- 优点是比较好理解,简单易操作
- 缺点是违反了设计模式的 OCP 原则,即对扩展开放,对修改关闭。即当我们给类增加新功能的时候,尽量不修改代码或者尽量少修改代码
理想小镇的聪明面包达人
我们想象一下,一个理想小镇上有个面包达人,他教会了好几个徒弟,徒弟们也准守传承按照指定的配方去做面包,每当想到一个新的做法面包达人都要挨个徒弟的教会他们。
我们就先模拟一下这个远古笨办法,我们定义一个面包的抽象类,每种面包我们都可以继承这个基础类,然后两个徒弟都开始要做面包就会有以下的代码:
1 | package com.yubulang.simplefactory; |
2 | |
3 | // 我们要生产一个相机,是要准备不同的 |
4 | public abstract class Bread { |
5 | // 准备材料 |
6 | public abstract void prepare(); |
7 | |
8 | // 制作 |
9 | public abstract void make(); |
10 | |
11 | // 包装 |
12 | public abstract void pack(); |
13 | } |
14 | |
15 | public class ButterBread extends Bread { |
16 | public void prepare() { |
17 | System.out.println("准备奶油面包的材料"); |
18 | } |
19 | |
20 | public void make() { |
21 | System.out.println("制作奶油面包"); |
22 | } |
23 | |
24 | public void pack() { |
25 | System.out.println("包装奶油面包"); |
26 | } |
27 | } |
28 | |
29 | public class MeatLoaf extends Bread { |
30 | public void prepare() { |
31 | System.out.println("准备肉松面包的材料"); |
32 | } |
33 | |
34 | public void make() { |
35 | System.out.println("制作肉松面包"); |
36 | } |
37 | |
38 | public void pack() { |
39 | System.out.println("包装肉松面包"); |
40 | } |
41 | } |
42 | |
43 | class Apprentice01 { |
44 | public static void makeBread(String name) { |
45 | Bread bread = null; |
46 | switch (name) { |
47 | case "肉松面包": |
48 | bread = new MeatLoaf(); |
49 | break; |
50 | case "奶油面包": |
51 | bread = new ButterBread(); |
52 | break; |
53 | } |
54 | |
55 | if (bread != null) { |
56 | System.out.println("徒弟一:"); |
57 | bread.make(); |
58 | bread.pack(); |
59 | System.out.println("徒弟一卖面包"); |
60 | } |
61 | } |
62 | } |
63 | |
64 | class Apprentice02 { |
65 | public static void makeBread(String name) { |
66 | Bread bread = null; |
67 | switch (name) { |
68 | case "肉松面包": |
69 | bread = new MeatLoaf(); |
70 | break; |
71 | case "奶油面包": |
72 | bread = new ButterBread(); |
73 | break; |
74 | } |
75 | |
76 | if (bread != null) { |
77 | System.out.println("徒弟二:"); |
78 | bread.make(); |
79 | bread.pack(); |
80 | System.out.println("徒弟二卖面包"); |
81 | } |
82 | } |
83 | } |
84 | |
85 | public class Main { |
86 | public static void main(String[] args) { |
87 | Apprentice01.makeBread("奶油面包"); |
88 | Apprentice02.makeBread("奶油面包"); |
89 | } |
90 | } |
这个时候我们还有香肠面包、香肠面包要交给徒弟,那么我们代码要改的地方是不是有很多地方了。这个时候面包达人看出问题了,每个徒弟都要教一遍怎么做新面包是不是很累,那我们把他们叫一起来,一锅烩了岂不是更快。
统一课堂(及工厂)分开教的小灶变成了大课堂。这个大课堂我们可以把它看成一个规范的工厂。代码升级:
1 | package com.yubulang.simplefactory; |
2 | |
3 | // 我们要生产一个相机,是要准备不同的 |
4 | public abstract class Bread { |
5 | // 准备材料 |
6 | public abstract void prepare(); |
7 | |
8 | // 制作 |
9 | public abstract void make(); |
10 | |
11 | // 包装 |
12 | public abstract void pack(); |
13 | } |
14 | |
15 | public class ButterBread extends Bread { |
16 | public void prepare() { |
17 | System.out.println("准备奶油面包的材料"); |
18 | } |
19 | |
20 | public void make() { |
21 | System.out.println("制作奶油面包"); |
22 | } |
23 | |
24 | public void pack() { |
25 | System.out.println("包装奶油面包"); |
26 | } |
27 | } |
28 | |
29 | public class MeatLoaf extends Bread { |
30 | public void prepare() { |
31 | System.out.println("准备肉松面包的材料"); |
32 | } |
33 | |
34 | public void make() { |
35 | System.out.println("制作肉松面包"); |
36 | } |
37 | |
38 | public void pack() { |
39 | System.out.println("包装肉松面包"); |
40 | } |
41 | } |
42 | |
43 | // 大课堂教授徒弟们做面包 |
44 | public class SimpleFactory { |
45 | public static Bread createBread(String name) { |
46 | Bread bread = null; |
47 | switch (name) { |
48 | case "肉松面包": |
49 | bread = new MeatLoaf(); |
50 | break; |
51 | case "奶油面包": |
52 | bread = new ButterBread(); |
53 | break; |
54 | } |
55 | |
56 | return bread; |
57 | } |
58 | } |
59 | |
60 | class Apprentice01 { |
61 | public static void makeBread(String name) { |
62 | Bread bread = SimpleFactory.createBread(name); |
63 | |
64 | if (bread != null) { |
65 | System.out.println("徒弟一:"); |
66 | bread.make(); |
67 | bread.pack(); |
68 | System.out.println("徒弟一卖面包"); |
69 | } |
70 | } |
71 | } |
72 | |
73 | class Apprentice02 { |
74 | public static void makeBread(String name) { |
75 | Bread bread = SimpleFactory.createBread(name); |
76 | |
77 | if (bread != null) { |
78 | System.out.println("徒弟二:"); |
79 | bread.make(); |
80 | bread.pack(); |
81 | System.out.println("徒弟二卖面包"); |
82 | } |
83 | } |
84 | } |
85 | |
86 | public class Main { |
87 | public static void main(String[] args) { |
88 | Apprentice01.makeBread("奶油面包"); |
89 | Apprentice02.makeBread("奶油面包"); |
90 | } |
91 | } |
这样我们的面包达人是不是就省事儿了不少。教一次两个徒弟都会了,如果要挨个挨个教(挨个挨个的改代码就太累了)。所以我们把这些共有的部分抽离出来,节省大家的时间。
总结
这里我们已经看出简单工厂模式的简单强大之处了吧——其实就是把创建对象的公用部抽取独立出来了。
但是这个不是一个好方式,因为你每次添加新对象的时候都要去修改这个类,逻辑上是没问题,但是从代码上来说这不是一个好办法。
别急后面还有好几种工厂模式,可以为我们提供解决的思路。