0%

设计模式之简单工厂(静态工厂模式)

前言

简单工厂模式(静态工厂模式),最为一个出镜率比较高的设计模式,相对来说比较简单,大家可以很快上手,我觉得还是举例子给大家会比较好理解也记忆。

我们首先看看它的优缺点:

  • 优点是比较好理解,简单易操作
  • 缺点是违反了设计模式的 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
}

这样我们的面包达人是不是就省事儿了不少。教一次两个徒弟都会了,如果要挨个挨个教(挨个挨个的改代码就太累了)。所以我们把这些共有的部分抽离出来,节省大家的时间。

总结

这里我们已经看出简单工厂模式的简单强大之处了吧——其实就是把创建对象的公用部抽取独立出来了。

但是这个不是一个好方式,因为你每次添加新对象的时候都要去修改这个类,逻辑上是没问题,但是从代码上来说这不是一个好办法。

别急后面还有好几种工厂模式,可以为我们提供解决的思路。