Luckylau's Blog

设计模式之工厂模式

​ 工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一,这种类型的设计模式属于创建型模式,它提供了一种创建对象很好的方式包括简单工厂模式(simple factory)、工厂方法模式(factory method)和抽象工厂模式(abstract factory)。

简单工厂模式

1
2
3
public interface Shape {
void draw();
}
1
2
3
4
5
6
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Draw a rectangle.");
}
}
1
2
3
4
5
6
public class Triangle implements Shape {
@Override
public void draw() {
System.out.println("Draw a triangle.");
}
}
1
2
3
4
5
6
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("Draw a circle.");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class ShapeFactory {
//使用 getShape 方法获取形状类型的对象
public static Shape getShape(String shapeType){
if(shapeType == null){
return null;
}
if(shapeType.equalsIgnoreCase("CIRCLE")){
return new Circle();
} else if(shapeType.equalsIgnoreCase("RECTANGLE")){
return new Rectangle();
} else if(shapeType.equalsIgnoreCase("TRIANGLE")){
return new Triangle();
}
return null;
}
}
1
2
3
4
5
6
7
8
9
//画矩形时:
Shape r = ShapeFactory.getShape("RECTANGLE");
r.draw();
//画圆形时:
Shape c = ShapeFactory.getShape("CIRCLE");
c.draw();
//画三角形时:
Shape t = ShapeFactory.getShape("TRIANGLE");
t.draw();

使用场景

日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方。

数据库访问:当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化时。

设计一个连接服务器的框架,需要三个协议,”POP3”、”IMAP”、”HTTP”,可以把这三个作为产品类,共同实现一个接口。

优点

一个调用者想创建一个对象,只要提出要求就可以了;屏蔽产品的具体实现,调用者只关心产品的接口;一定程度上提高了扩展性。

缺点

每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。可见,简单工厂模式对”开-闭”原则的支持还不够,因为如果有新的产品加入到系统中去,就需要修改工厂类,将必要的逻辑加入到工厂类中。

工厂方法模式

​ 工厂方法模式同 简单工厂模式 一样,也是创建类模式,又叫做虚拟构造(Virtual Constructor)模式或多态工厂(Polymorphic Factory)模式。其用意是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类中。

继续用上面的例子

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
public interface ShapeFactory {
Shape getShape();
}
public class RectangleFactory implements ShapeFactory {
public Shape getShape() {
return new Rectangle();
}
}
public class CircleFactory implements ShapeFactory{
public Shape getShape() {
return new Circle();
}
}
public class CircleFactory implements ShapeFactory{
public Shape getShape() {
return new Circle();
}
}
public class Client {
public static void main(String[] args) {
ShapeFactory factory = new CircleFactory();
Shape c = factory.getShape();
c.draw();
}
}

做到了完全的“开闭原则”,因为增加新的“产品”和相应的“工厂”均不需修改现有代码;

抽象工厂模式

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
public interface PhoneFactory {
Phone producePhone();
Cable produceCable();
Charger produceCharger();
}
public class IPhoneFactory implements PhoneFactory {
public Phone producePhone() {
return new IPhone();
}
public Cable produceCable() {
return new IPhoneCable();
}
public Charger produceCharger() {
return new IPhoneCharger();
}
}
public class XiaomiFactory implements PhoneFactory {
public Phone producePhone() {
return new XiaomiPhone();
}
public Cable produceCable() {
return new AndroidCable();
}
public Charger produceCharger() {
return new XiaomiCharger();
}
}
public class Client {
public static void main(String[] args) {
PhoneFactory factory = new IPhoneFactory();
factory.produceCable().transmit();
factory.produceCharger().charge();
factory.producePhone().use();
}
}

抽象工厂的作用是将“抽象组件”组合成“抽象产品”。所以我们看到,PhoneFactory的产出是一个一个的接口。所以,抽象工厂并不关心具体组件的实现,而是只关心接口。

参考

https://github.com/Luckylau/design-patterns

Luckylau wechat
如果对您有价值,看官可以打赏的!