工厂模式
[toc]
简单工厂模式
假设我们要制造小米和苹果的笔记本, 我们声明一个 Computer 抽象类, 然后派生 MiComputer 和 MacComputer 两个子类. 但是直接用new的话, 就无法将装配工作统一接口. 维护起来就会很麻烦.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public abstract class Computer {
public abstract void setOperationSystem();
}
public class MacComputer extends Computer {
@Override
public void setOperationSystem() {
System.out.println("Mac笔记本安装Mac系统");
}
}
public class MiComputer extends Computer {
@Override
public void setOperationSystem() {
System.out.println("小米笔记本安装Win10系统");
}
}
简单工厂模式是说, 我们将构建过程也抽象出来, 我们传给工厂不同的参数, 以命令其生产不同的电脑, 而内部其生产过程其实是用各个电脑子类的构造方式, 我们无需关心.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class SimpleComputerFactory {
public static Computer makeComputer(String brand) {
Computer computer=null;
switch (brand) {
case "mac":
computer=new MacComputer();
break;
case "mi":
computer=new MiComputer();
break;
default:
break;
}
return computer;
}
}
// 使用方法,如果要修改,直接将 mi 改为 mac 即可
// Computer computer= SimpleComputerFactory.makeComputer("mi");
// computer.setOperationSystem();
工厂模式
工厂模式是简单工厂模式的升级版. 简单工厂模式虽然解决了构建的问题, 但是带来了严重的耦合, 一旦我们新加产品, 需要不停改动工厂类. 我们引入工厂模式, 是将工厂本身也抽象出来, 让工厂成为接口, 各自的产品分别使用各自的工厂(都是继承自工厂接口) 将简单工厂模式的工厂修改如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public interface ComputerFactory {
Computer makeComputer();
}
public class MacComputerFactory implements ComputerFactory {
@Override
public Computer makeComputer() {
return new MacComputer();
}
}
public class MiComputerFactory implements ComputerFactory {
@Override
public Computer makeComputer() {
return new MiComputer();
}
}
// 生产Mac电脑
// ComputerFactory macFactory=new MacComputerFactory();
// macFactory.makeComputer().setOperationSystem();
// 生产小米电脑
// ComputerFactory miFactory=new MiComputerFactory();
// miFactory.makeComputer().setOperationSystem();
// 如果后面要修改电脑的类型的话,只需要改 new 后面的构造函数名称即可,具有很好的扩展性.
抽象工厂模式
抽象工厂其实是另一种模式了. 这个是面向更大的问题, 比如上文中的苹果和小米, 如果它们不仅仅生产电脑, 还生产手机, 那么就需要更多的工厂. 我们可以考虑将一些相关的产品组成一个”产品族”,
新增手机类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public abstract class MobilePhoto {
public abstract void setOperationSystem();
}
public class IPhoto extends MobilePhoto {
@Override
public void setOperationSystem() {
System.out.println("苹果手机安装IOS系统");
}
}
public class MiPhoto extends MobilePhoto {
@Override
public void setOperationSystem() {
System.out.println("小米手机安装Android系统");
}
}
然后修改工厂, 让一个工厂既能建造电脑, 又能建造手机.
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 AbstractFactory {
Computer makeComputer();
MobilePhoto makeMobilePhoto();
}
public class AppleFactory implements AbstractFactory {
@Override
public Computer makeComputer() {
return new MacComputer();
}
@Override
public MobilePhoto makeMobilePhoto() {
return new IPhoto();
}
}
public class XiaoMiFactory implements AbstractFactory {
@Override
public Computer makeComputer() {
return new MiComputer();
}
@Override
public MobilePhoto makeMobilePhoto() {
return new MiPhoto();
}
}
但是抽象工厂模式有个缺陷就是: 对于添加产品族容易, 直接实现抽象工厂接口即可, 比如新增戴尔的手机和电脑工厂. 但是对于产品类的扩展比较困难, 比如我们新增鼠标类, 那么就必须修改所有的工厂, 包括抽象工厂. 这叫对开闭原则的倾斜性.