工厂模式

简单工厂模式

和名字一样简单,非常简单。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class FoodFactory {

public static Food makeFood(String name) {
if (name.equals("noodle")) {
Food noodle = new LanZhouNoodle();
noodle.addSpicy("more");
return noodle;
} else if (name.equals("chicken")) {
Food chicken = new HuangMenChicken();
chicken.addCondiment("potato");
return chicken;
} else {
return null;
}
}
}

其中,LanZhouNoodle 和 HuangMenChicken 都继承自 Food。

简单地说,简单工厂模式通常就是这样,一个工厂类 XxxFactory,里面有一个静态方法,根据我们不同的参数,返回不同的派生自同一个父类(或实现同一接口)的实例对象。

工厂方法模式

简单工厂模式很简单,如果它能满足我们的需要,我觉得就不要折腾了。之所以需要引入工厂方法模式,是因为我们往往需要使用两个或两个以上的工厂。

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
28
29
30
31
public interface FoodFactory {
Food makeFood(String name);
}

public class ChineseFoodFactory implements FoodFactory {

@Override
public Food makeFood(String name) {
if (name.equals("A")) {
return new ChineseFoodA();
} else if (name.equals("B")) {
return new ChineseFoodB();
} else {
return null;
}
}
}

public class AmericanFoodFactory implements FoodFactory {

@Override
public Food makeFood(String name) {
if (name.equals("A")) {
return new AmericanFoodA();
} else if (name.equals("B")) {
return new AmericanFoodB();
} else {
return null;
}
}
}

其中,ChineseFoodA、ChineseFoodB、AmericanFoodA、AmericanFoodB 都派生自 Food。

客户端调用:

1
2
3
4
5
6
7
8
public class APP {
public static void main(String[] args) {
// 先选择一个具体的工厂
FoodFactory factory = new ChineseFoodFactory();
// 由第一步的工厂产生具体的对象,不同的工厂造出不一样的对象
Food food = factory.makeFood("A");
}
}

虽然都是调用 makeFood(“A”) 制作 A 类食物,但是,不同的工厂生产出来的完全不一样。

抽象工厂模式

当涉及到产品族的时候,就需要引入抽象工厂模式了。

一个经典的例子是造一台电脑。

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public interface ComputerFactory {
Cpu makeCPU();
MainBoard makeMainBoard();
HardDisk makeHardDisk();
}

public class IntelFactory implements ComputerFactory {

@Override
public CPU makeCPU() {
return new IntelCPU();
}

@Override
public MainBoard makeMainBoard() {
return new IntelMainBoard();
}

@Override
public HardDisk makeHardDisk() {
return new IntelHardDisk();
}
}

public class AmdFactory implements ComputerFactory {

@Override
public CPU makeCPU() {
return new AmdCPU();
}

@Override
public MainBoard makeMainBoard() {
return new AmdMainBoard();
}

@Override
public HardDisk makeHardDisk() {
return new AmdHardDisk();
}
}

客户端调用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class APP {
public static void main(String[] args) {
// 第一步就要选定一个"大厂"
ComputerFactory cf = new AmdFactory();
// 从这个大厂造 CPU
CPU cpu = cf.makeCPU();
// 从这个大厂造主板
MainBoard board = cf.makeMainBoard();
// 从这个大厂造硬盘
HardDisk hardDisk = cf.makeHardDisk();
// 将同一个厂子出来的 CPU、主板、硬盘组装在一起
Computer result = new Computer(cpu, board, hardDisk);
}
}

当然,抽象工厂的问题也是显而易见的,比如我们要加个显示器,就需要修改所有的工厂,给所有的工厂都加上制造显示器的方法。

参考