为什么要学习和使用设计模式?设计模式是开发前辈们总结出来的代码设计经验,使用设计模式的目的就是提升代码的可扩展性和可维护性

常用的设计模式有23中,可归为3类:创建型模式、结构型模式和行为模式。

注意:学习设计模式的本质其实是学习其设计思想,不能简单的生搬硬套,也不能为了使用设计模式而过度设计,要带有自己的思考,合理平衡的去设计才是我们学习的目的。

创建型模式

关注对象是如何创建的。将对象创建和使用相分离,使两者可以相对独立地变换。

工厂方法

核心思想

定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到其子类。

大白话

  • 产品提供者:对于多个同一性质的不同实现的对象,通过提炼出一个产品接口,通过接口来体现这些对象是同一层次的产品关系。同时创建一个抽象的工厂类来提供创建产品的抽象方法(每个产品的生产细节不同,下放至具体实现类)和提炼出来的公共方法(实现完全相同的功能)。对于每个对象,都要有相对应的实现工厂抽象类的工厂来创建。产品和工厂是一对一关系
  • 产品使用者:通过调用具体要使用的产品的工厂类提供的接口来获取具体的产品即可,而不需要关心产品是如何创建的,就算产品的创建很复杂,那也是工厂内部自己解决。

具体例子

车辆工厂为例

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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/**
* 产品接口
*/
interface Vehicle {
void drive();
void honk();
}

/**
* 具体产品类
*/
class Car implements Vehicle {
@Override
public void drive() {
System.out.println("驾驶小汽车:平稳舒适");
}

@Override
public void honk() {
System.out.println("小汽车:滴滴!");
}
}

class Motorcycle implements Vehicle {
@Override
public void drive() {
System.out.println("驾驶摩托车:风驰电掣");
}

@Override
public void honk() {
System.out.println("摩托车:嘟嘟!");
}
}

class Truck implements Vehicle {
@Override
public void drive() {
System.out.println("驾驶卡车:威武霸气");
}

@Override
public void honk() {
System.out.println("卡车:叭叭!");
}
}

/**
* 创建者抽象类
*/
abstract class VehicleFactory {
// 工厂方法,不同的工厂类的具体实现不同
public abstract Vehicle createVehicle();

// 其他业务逻辑,所有工厂类通用的方法
public void deliveryVehicle() {
Vehicle vehicle = createVehicle();
System.out.println("正在准备交付车辆...");
vehicle.drive();
System.out.println("车辆交付完成!");
}
}

/**
* 具体创建者类
*/
class CarFactory extends VehicleFactory {
@Override
public Vehicle createVehicle() {
System.out.println("制造小汽车...");
// 这里可以有复杂的创建逻辑
return new Car();
}
}

class MotorcycleFactory extends VehicleFactory {
@Override
public Vehicle createVehicle() {
System.out.println("制造摩托车...");
return new Motorcycle();
}
}

class TruckFactory extends VehicleFactory {
@Override
public Vehicle createVehicle() {
System.out.println("制造卡车...");
return new Truck();
}
}

/**
* 客户端代码
*/
public class FactoryMethodExample {
public static void main(String[] args) {
System.out.println("=== 工厂方法模式示例 ===\n");

// 创建汽车
VehicleFactory carFactory = new CarFactory();
Vehicle car = carFactory.createVehicle();
car.drive();
car.honk();
System.out.println();

// 创建摩托车
VehicleFactory motorcycleFactory = new MotorcycleFactory();
motorcycleFactory.deliveryVehicle();
System.out.println();

// 创建卡车
VehicleFactory truckFactory = new TruckFactory();
Vehicle truck = truckFactory.createVehicle();
truck.drive();
truck.honk();
}
}

抽象工厂

核心思想

提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

大白话

一个工厂可以生产同一类型范围内的多个不同的产品。本质上就是工厂方法的扩增,从一个工厂对应一个产品 变成了 对应一系列产品。比如说各大手机厂商,既都生产手机,又都生产平板电脑、电脑。那么手机、平板、电脑就可以归为同一系列的产品。不可能说荣耀厂商既生产荣耀手机,又生产苹果电脑。

具体例子

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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// 抽象产品系列
interface Button {
void render();
}

interface Checkbox {
void paint();
}

// 具体产品 - Windows风格
class WindowsButton implements Button {
@Override
public void render() {
System.out.println("渲染Windows风格按钮");
}
}

class WindowsCheckbox implements Checkbox {
@Override
public void paint() {
System.out.println("绘制Windows风格复选框");
}
}

// 具体产品 - Mac风格
class MacButton implements Button {
@Override
public void render() {
System.out.println("渲染Mac风格按钮");
}
}

class MacCheckbox implements Checkbox {
@Override
public void paint() {
System.out.println("绘制Mac风格复选框");
}
}

// 抽象工厂
interface GUIFactory {
Button createButton();
Checkbox createCheckbox();
}

// 具体工厂
class WindowsFactory implements GUIFactory {
@Override
public Button createButton() {
return new WindowsButton();
}


@Override
public Checkbox createCheckbox() {
return new WindowsCheckbox();
}

}

class MacFactory implements GUIFactory {
@Override
public Button createButton() {
return new MacButton();
}


@Override
public Checkbox createCheckbox() {
return new MacCheckbox();
}

}

// 客户端代码
class Application {
private Button button;
private Checkbox checkbox;


public Application(GUIFactory factory) {
button = factory.createButton();
checkbox = factory.createCheckbox();
}

public void render() {
button.render();
checkbox.paint();
}

}

// 使用示例
public class AbstractFactoryDemo {
public static void main(String[] args) {
// 创建Windows风格的UI
GUIFactory windowsFactory = new WindowsFactory();
Application windowsApp = new Application(windowsFactory);
windowsApp.render();
// 输出:
// 渲染Windows风格按钮
// 绘制Windows风格复选框


// 创建Mac风格的UI
GUIFactory macFactory = new MacFactory();
Application macApp = new Application(macFactory);
macApp.render();
// 输出:
// 渲染Mac风格按钮
// 绘制Mac风格复选框
}
}

简单工厂

简单工厂并不是一个标准的设计模式,而是一种编程习惯或编码技巧。

核心思想

把对象的创建逻辑集中在一个地方,客户端只需要传入一个参数,工厂就能返回对应的对象。

优点:实现简单,对象少时容易维护。当确定产品种类基本固定,不会频繁变化时使用简单工厂很合适。

缺点:对象集中管理,当对象很多时不好维护。

具体例子

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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
// 产品接口
interface Shape {
void draw();
}

// 具体产品类
class Circle implements Shape {
@Override
public void draw() {
System.out.println("绘制圆形");
}
}

class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("绘制矩形");
}
}

class Square implements Shape {
@Override
public void draw() {
System.out.println("绘制正方形");
}
}

// 简单工厂
class ShapeFactory {
public Shape createShape(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("SQUARE")) {
return new Square();
}

return null;
}

}

// 使用示例
public class SimpleFactoryDemo {
public static void main(String[] args) {
ShapeFactory factory = new ShapeFactory();

Shape circle = factory.createShape("CIRCLE");
circle.draw(); // 输出: 绘制圆形

Shape rectangle = factory.createShape("RECTANGLE");
rectangle.draw(); // 输出: 绘制矩形
}

}