设计模式

设计模式是为了让程序具有更好的可读性可靠性可扩展性代码重用性使程序呈现高内聚低耦合的特性

软件设计原则

  • 单一职责原则一个类只负责一项职责并不是一个方法如果逻辑简单类中方法少可以在方法级别保持单一职责原则
  • 接口隔离原则一个类对另一个类的依赖应该建立在最小的接口上
  • 开闭原则它是最基础最重要的设计原则软件模块方法和函数应该对扩展提供方开放对修改使用方关闭用抽象构建框架用实现扩展细节
  • 里氏替换原则所有引用基类的地方必须能透明地使用其子类对象尽量少使用继承采用依赖聚合组合等关系代替
  • 依赖倒转原则底层模块尽量有抽象类或接口或者两个都有变量的声明类型尽量是抽象类或接口
  • 迪米特法则核心是降低类之间的耦合对自己依赖的类知道的越少越好
  • 合成复用原则尽量使用合成/聚合的方式不使用继承

类的关系与UML类图

  • 依赖虚线加箭头
  • 关联实线加箭头
  • 实现虚线加三角形
  • 泛化/继承实线加三角形
  • 聚合实线加实心菱形
  • 组合实线加空心菱形

创建者模式

这些设计模式提供了一种在创建对象的同时隐藏创建逻辑的方式而不是使用 new 运算符直接实例化对象这使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活

单例模式

单例模式Singleton Pattern是 Java 中最简单的设计模式之一这种类型的设计模式属于创建型模式它提供了一种创建对象的最佳方式

这种模式涉及到一个单一的类该类负责创建自己的对象同时确保只有单个对象被创建这个类提供了一种访问其唯一的对象的方式可以直接访问不需要实例化该类的对象

饿汉式静态常量

  • 私有化构造器
  • 在类的内部创建一个静态常量的对象实例
  • 提供一个静态的共有方法获取实例
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 class Singleton {
//构造器私有外部不能根据构造器创建对象
private Singleton() {}

//在类的内部创建一个对象实例
private static final Singleton instance = new Singleton();

//提供一个公有的静态方法返回该类的实例对象
public static Singleton getInstance() {
return instance;
}
}

public class Test {
public static void main(String[] args) {
Singleton instance1 = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance1.hashCode());
System.out.println(instance2.hashCode());
}
}

懒汉式线程不安全

  • 私有化构造器
  • 在类的内部定义一个静态对象
  • 提供一个静态的公有方法
  • 判断对象为空则创建对象返回对象不为空则直接返回
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
/**
* 单例模式懒汉式
* 优点使用时创建不会造成内存浪费
* 缺点线程不安全
* 总结不推荐使用
*/
public class Singleton {
//构造器私有外部不能根据构造器创建对象
private Singleton(){}

private static Singleton instance = null;

//提供一个静态的公有方法当使用该方法时再创建该对象
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}

public class Test {
public static void main(String[] args) {
Singleton instance1 = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance1.hashCode());
System.out.println(instance2.hashCode());
}
}

懒汉式同步方法线程安全

  • 私有化构造器
  • 在类的内部定义一个静态对象
  • 提供一个静态的公有方法方法加同步锁
  • 判断对象为空则创建对象并返回对象不为空则直接返回
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
/**
* 单例模式懒汉式
* 优点使用时创建不会造成内存浪费同步方法线程安全
* 缺点效率低
* 总结不推荐使用
*/
public class Singleton {
//构造器私有外部不能根据构造器创建对象
private Singleton(){}

private static Singleton instance = null;

//提供一个静态的公有方法当时用该方法时再创建该对象
//加入synchronized解决线程安全问题
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}

public class Test {
public static void main(String[] args) {
Singleton instance1 = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance1.hashCode());
System.out.println(instance2.hashCode());
}
}

懒汉式双重校检锁

  • 私有化构造器
  • 在类的内部定义一个静态对象
  • 提供一个静态的公有方法
  • 判断对象是否为空不为空直接返回
  • 对象为空添加同步锁->再次判断对象是否为空
  • 对象为空则创建对象并返回对象不为空则直接返回
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
/**
* 单例模式双重校检锁
* 优点使用时创建不会造成内存浪费同步方法线程安全
* 总结推荐使用
*/
public class Singleton {
//构造器私有外部不能根据构造器创建对象
private Singleton(){}

private static volatile Singleton instance = null;

//提供一个静态的公有方法当时用该方法时再创建该对象
//加入双重检查代码解决线程安全问题解决效率的问题
public static Singleton getInstance() {
if(instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}

public class Test {
public static void main(String[] args) {
Singleton instance1 = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance1.hashCode());
System.out.println(instance2.hashCode());
}
}

懒汉式静态内部类

  • 私有化构造器
  • 在类的内部创建一个私有的静态类类中有一个静态常量的对象实例
  • 在外部类中提供一个共有的静态方法调用该方法时返回静态内部类中的对象实例
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
/**
* 单例模式静态内部类
* 优点静态内部类在Singleton类装载时不会实例化调用getInstance方法时再会装载SingletonInstance类
* JVM装载SingletonInstance类时别的线程无法进入保证了线程安全
* 利用静态内部类特点实现延迟加载效率高
* 总结推荐使用
*/
public class Singleton {
//构造器私有外部不能根据构造器创建对象
private Singleton(){}

//创建一个静态内部类该类中有一个静态属性singleton
private static class SingletonInstance {
private static final Singleton INSTANCE = new Singleton();
}

//提供一个静态的公有方法当时用该方法时再创建该对象
public static Singleton getInstance() {
return SingletonInstance.INSTANCE;
}
}

public class Test {
public static void main(String[] args) {
Singleton instance1 = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance1.hashCode());
System.out.println(instance2.hashCode());
}
}

枚举类

  • 枚举类本身就有单例的特性初始化时线程安全
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
* 单例模式枚举
* 优点 JDK1.5 之后才加入 enum 特性 是它不仅能避免多线程同步问题而且还自动支持序列化机制防止反序列化重新创建新的对象绝对防止多次实例化
* 总结推荐使用
*/
enum Singleton {
INSTANCE;
}

public class Test {
public static void main(String[] args) {
Singleton instance1 = Singleton.INSTANCE;
Singleton instance2 = Singleton.INSTANCE;
System.out.println(instance1.hashCode());
System.out.println(instance2.hashCode());
}
}

原型模式

原型模式Prototype Pattern是用于创建重复的对象同时又能保证性能这种类型的设计模式属于创建型模式它提供了一种创建对象的最佳方式之一

这种模式是实现了一个原型接口该接口用于创建当前对象的克隆当直接创建对象的代价比较大时则采用这种模式例如一个对象需要在一个高代价的数据库操作之后被创建我们可以缓存该对象在下一个请求时返回它的克隆在需要的时候更新数据库以此来减少数据库调用

浅拷贝

  • 类继承Cloneable接口
  • 实现clone方法
  • 使用clone方法克隆出一个新的对象
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
public class Sheep implements Cloneable {

private String name;

private int age;

private Sheep friend;

public Sheep(String name, int age, Sheep friend) {
this.name = name;
this.age = age;
this.friend = friend;
}

public Sheep getFriend() {
return friend;
}

public void setFriend(Sheep friend) {
this.friend = friend;
}

@Override
public String toString() {
return "Sheep{" + "name='" + name + '\'' + ", age=" + age + ", friend=" + friend + '}';
}

@Override
public Sheep clone() {
try {
return (Sheep) super.clone();
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
}
}

public class Run {
public static void main(String[] args) {
Sheep harry = new Sheep("Harry", 1, null);
Sheep dolly = new Sheep("Dolly", 1, harry);

System.out.println(dolly.toString());

//克隆羊多莉1号
Sheep clone1 = dolly.clone();
Sheep clone2 = dolly.clone();

System.out.println("多莉1号克隆体:" + clone1.hashCode());
System.out.println("多莉2号克隆体:" + clone1.hashCode());
//可以发现克隆体的对象是不一样的
System.out.println(clone1 == clone2);

System.out.println("多莉1号克隆体朋友:" + clone1.getFriend().hashCode());
System.out.println("多莉2号克隆体朋友:" + clone2.getFriend().hashCode());
//但是内部属性指向的是同一个地址这是浅拷贝
System.out.println(dolly.getFriend() == clone1.getFriend());
System.out.println(clone1.getFriend() == clone2.getFriend());
}
}

深拷贝

  • 类继承Cloneable接口和Serializable接口
  • 实现clone方法方法中使用序列化反序列化返回对象
  • 使用clone方法克隆出一个新的对象
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
public class Sheep implements Cloneable, Serializable {

private String name;

private int age;

private Sheep friend;

public Sheep(String name, int age, Sheep friend) {
this.name = name;
this.age = age;
this.friend = friend;
}

public Sheep getFriend() {
return friend;
}

public void setFriend(Sheep friend) {
this.friend = friend;
}

@Override
public String toString() {
return "Sheep{" + "name='" + name + '\'' + ", age=" + age + ", friend=" + friend + '}';
}

@Override
public Sheep clone() {
//创建流对象
ByteArrayOutputStream bos = null;
ObjectOutputStream oos = null;
ByteArrayInputStream bis = null;
ObjectInputStream ois = null;
try {
bos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(bos);
//对象序列化
oos.writeObject(this);

//对象反序列化
bis = new ByteArrayInputStream(bos.toByteArray());
ois = new ObjectInputStream(bis);
return (Sheep) ois.readObject();
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
try {
if (bos != null) {bos.close();}
if (oos != null) {oos.close();}
if (bis != null) {bis.close();}
if (ois != null) {ois.close();}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

public class Run {
public static void main(String[] args) {
Sheep harry = new Sheep("Harry", 1, null);
Sheep dolly = new Sheep("Dolly", 1, harry);

System.out.println(dolly.toString());

//克隆羊多莉1号
Sheep clone1 = dolly.clone();
Sheep clone2 = dolly.clone();

System.out.println("多莉1号克隆体:" + clone1.hashCode());
System.out.println("多莉2号克隆体:" + clone1.hashCode());
//可以发现克隆体的对象是不一样的
System.out.println(clone1 == clone2);

System.out.println("多莉1号克隆体朋友:" + clone1.getFriend().hashCode());
System.out.println("多莉2号克隆体朋友:" + clone2.getFriend().hashCode());
//内部属性指向不同的地址这是深拷贝
System.out.println(dolly.getFriend() == clone1.getFriend());
System.out.println(clone1.getFriend() == clone2.getFriend());
}
}

简单工厂模式

工厂模式Factory Pattern是 Java 中最常用的设计模式之一这种类型的设计模式属于创建型模式它提供了一种创建对象的最佳方式

在工厂模式中我们在创建对象时不会对客户端暴露创建逻辑并且是通过使用一个共同的接口来指向新创建的对象

结构

  • 创建一个抽象类/接口
  • 新建几个类继承/实现
  • 创建一个工厂类
  • 工厂类中新建一个静态方法根据不同的值返回相对应类的实例
  • 客户端直接使用工厂类调用静态方法就可以获取需要的实例
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
public abstract class Color {

public String nameCN;

public String nameEN;

public abstract String getRGBString();

public abstract String getHexadecimalString();

}

public class Black extends Color {

public Black() {
nameCN = "黑色";
nameEN = "black";
}

@Override
public String getRGBString() {
return nameCN + " " + nameEN + " GRB: " + "255,255,255";
}

@Override
public String getHexadecimalString() {
return nameCN + " " + nameEN + " 十六进制: " + "#FFFFFF";
}
}

public class Blue extends Color {

public Blue() {
nameCN = "蓝色";
nameEN = "blue";
}

@Override
public String getRGBString() {
return nameCN + " " + nameEN + " GRB: " + "0,0,255";
}

@Override
public String getHexadecimalString() {
return nameCN + " " + nameEN + " 十六进制: " + "#0000FF";
}
}

public class Red extends Color {

public Red() {
nameCN = "红色";
nameEN = "red";
}

@Override
public String getRGBString() {
return nameCN + " " + nameEN + " GRB: " + "255,69,0";
}

@Override
public String getHexadecimalString() {
return nameCN + " " + nameEN + " 十六进制: " + "#FF0000";
}
}

public class White extends Color {

public White() {
nameCN = "白色";
nameEN = "white";
}

@Override
public String getRGBString() {
return nameCN + " " + nameEN + " GRB: " + "255,255,255";
}

@Override
public String getHexadecimalString() {
return nameCN + " " + nameEN + " 十六进制: " + "#FFFFFF";
}
}

public enum ColorType {
RED, BLUE, BLACK, WHITE
}

//简单工厂模式
public class ColorFactory {
public static Color getColor(ColorType colorType) {
if (colorType == null)
return null;
switch(colorType) {
case RED: return new Red();
case BLUE: return new Blue();
case BLACK: return new Black();
case WHITE: return new White();
default: return null;
}
}
}

public class Run {
public static void main(String[] args) {
ColorType[] values = ColorType.values();
for (ColorType colorType : values) {
Color color = ColorFactory.getColor(colorType);
if (color == null) return;
String rgbString = color.getRGBString();
System.out.println(rgbString);
String hexadecimalString = color.getHexadecimalString();
System.out.println(hexadecimalString);
}
}
}

抽象工厂模式

抽象工厂模式Abstract Factory Pattern是围绕一个超级工厂创建其他工厂该超级工厂又称为其他工厂的工厂这种类型的设计模式属于创建型模式它提供了一种创建对象的最佳方式

在抽象工厂模式中接口是负责创建一个相关对象的工厂不需要显式指定它们的类每个生成的工厂都能按照工厂模式提供对象

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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
public interface Color {
public void fill();
}

public class Black implements Color {
@Override
public void fill() {
System.out.println("填充黑色");
}
}

public class Blue implements Color {
@Override
public void fill() {
System.out.println("填充蓝色");
}
}

public class Red implements Color {
@Override
public void fill() {
System.out.println("填充红色");
}
}

public class White implements Color {
@Override
public void fill() {
System.out.println("填充白色");
}
}

public enum ColorType {
/**
* 红色
*/
RED,

/**
* 蓝色
*/
BLUE,

/**
* 黑色
*/
BLACK,

/**
* 白色
*/
WHITE
}

public interface Shape {
public void draw();
}

public class Circle implements Shape {
@Override
public void draw() {
System.out.println("绘制圆型");
}
}

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

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

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

public enum ShapeType {
/**
* 圆型
*/
CIRCLE,

/**
* 长方形
*/
RECTANGLE,

/**
* 正方形
*/
SQUARE,

/**
* 三角形
*/
TRIANGLE
}

public abstract class AbstractFactory {
//获取形状
public abstract Shape getShape(ShapeType shapeType);

//获取颜色
public abstract Color getColor(ColorType colorType);
}

public class ColorFactory extends AbstractFactory {
@Override
public Shape getShape(ShapeType shapeType) {
return null;
}

@Override
public Color getColor(ColorType colorType) {
if (colorType == null)
return null;
switch (colorType) {
case RED: return new Red();
case BLUE: return new Blue();
case BLACK: return new Black();
case WHITE: return new White();
default: return null;
}
}
}

public class ProducerFactory {
public static AbstractFactory getFactory(FactoryType factoryType) {
if (factoryType == null)
return null;
switch (factoryType) {
case SHAPE: return new ShapeFactory();
case COLOR: return new ColorFactory();
default: return null;
}
}
}

public class ShapeFactory extends AbstractFactory {
@Override
public Shape getShape(ShapeType shapeType) {
if (shapeType == null)
return null;
switch (shapeType) {
case CIRCLE: return new Circle();
case RECTANGLE: return new Rectangle();
case SQUARE: return new Square();
case TRIANGLE: return new Triangle();
default: return null;
}
}

@Override
public Color getColor(ColorType colorType) {
return null;
}
}

public enum FactoryType {
/**
* 图形工厂
*/
SHAPE,

/**
* 颜色工厂
*/
COLOR
}

public class Run {
public static void main(String[] args) {
//获取图形工厂
AbstractFactory shapeFactory = ProducerFactory.getFactory(FactoryType.SHAPE);
ShapeType[] shapeTypes = ShapeType.values();
for (ShapeType shapeType: shapeTypes) {
Shape shape = shapeFactory.getShape(shapeType);
shape.draw();
}

//获取颜色工厂
AbstractFactory colorFactory = ProducerFactory.getFactory(FactoryType.COLOR);
ColorType[] colorTypes = ColorType.values();
for (ColorType colorType: colorTypes) {
Color color = colorFactory.getColor(colorType);
color.fill();
}

Color color = shapeFactory.getColor(ColorType.RED);
System.out.println(color);
}
}

方法工厂模式

方法工厂模式Method Factory Pattern适用于同一属性产品不同的生产工厂

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
118
119
120
121
122
123
124
125
public abstract class Car {
public String name;

public abstract String getCarName();
}

public class BJ30 extends Car {
public String name = "BJ30";

@Override
public String getCarName() {
return name;
}
}

public class BJ40 extends Car {
public String name = "BJ40";

@Override
public String getCarName() {
return name;
}
}

public class BJ80 extends Car {
private String name = "BJ80";

@Override
public String getCarName() {
return name;
}
}

public class BM5X extends Car {
public String name = "宝马5X";

@Override
public String getCarName() {
return name;
}
}

public class BM7X extends Car {
public String name = "宝马7X";

@Override
public String getCarName() {
return name;
}
}

public class BM9X extends Car {
public String name = "宝马9X";

@Override
public String getCarName() {
return name;
}
}

public enum CarType {
BM5X, BM7X, BM9X, BJ30, BJ40, BJ80
}

public abstract class CarFactory {
public abstract Car createCar(CarType carType);

public static CarFactory getBMFactory() {
return new BMFactory();
}

public static CarFactory getBJFactory() {
return new BJFactory();
}
}

public class BJFactory extends CarFactory {
@Override
public Car createCar(CarType carType) {
if (carType == null)
return null;
switch (carType) {
case BJ30: return new BJ30();
case BJ40: return new BJ40();
case BJ80: return new BJ80();
default: return null;
}
}
}

public class BMFactory extends CarFactory {
@Override
public Car createCar(CarType carType) {
if (carType == null)
return null;
switch (carType) {
case BM5X: return new BM5X();
case BM7X: return new BM7X();
case BM9X: return new BM9X();
default: return null;
}
}
}

public class Run {
public static void main(String[] args) {
CarType[] values = CarType.values();

CarFactory bmFactory = CarFactory.getBMFactory();
for (CarType value : values) {
Car car = bmFactory.createCar(value);
if (car != null) {
System.out.println(car.getCarName());
}
}

CarFactory bjFactory = CarFactory.getBJFactory();
for (CarType value : values) {
Car car = bjFactory.createCar(value);
if (car != null) {
System.out.println(car.getCarName());
}
}
}
}

建造者模式

建造者模式Builder Pattern使用多个简单的对象一步一步构建成一个复杂的对象这种类型的设计模式属于创建型模式它提供了一种创建对象的最佳方式

一个 Builder 类会一步一步构造最终的对象该 Builder 类是独立于其他对象的

建造者模式有很多变种但是万变不离其宗

结构

  • 产品
  • 建造者抽象类
  • 建造者实现类
  • 指挥者/调用者(自由组合)

例一

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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/**
* 产品课程
*/
public class Course {
private String name;//课程名称

private String ppt;//课程PPT

private String video;//课程视频

private String note;//课程笔记

private String homework;//课后作业

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getPpt() {
return ppt;
}

public void setPpt(String ppt) {
this.ppt = ppt;
}

public String getVideo() {
return video;
}

public void setVideo(String video) {
this.video = video;
}

public String getNote() {
return note;
}

public void setNote(String note) {
this.note = note;
}

public String getHomework() {
return homework;
}

public void setHomework(String homework) {
this.homework = homework;
}

@Override
public String toString() {
return "Course{" +
"name='" + name + '\'' +
", ppt='" + ppt + '\'' +
", video='" + video + '\'' +
", note='" + note + '\'' +
", homework='" + homework + '\'' +
'}';
}
}

/**
* 建造者抽象类
*/
public interface Builder {
Course build();
}

/**
* 建造者实现类
*/
public class CourseBuilder implements Builder {

private Course course = new Course();

public CourseBuilder setName(String name) {
course.setName(name);
return this;
}

public CourseBuilder setPpt(String ppt) {
course.setPpt(ppt);
return this;
}

public CourseBuilder setVideo(String video) {
course.setVideo(video);
return this;
}

public CourseBuilder setNote(String note) {
course.setNote(note);
return this;
}

public CourseBuilder setHomework(String homework) {
course.setHomework(homework);
return this;
}

@Override
public Course build() {
return course;
}
}

/**
* 调用者
*/
public class Run {
public static void main(String[] args) {
CourseBuilder builder = new CourseBuilder();
builder.setName("Sketch-新建画布");
builder.setPpt("Sketch-PPT");
builder.setVideo("Sketch-Video");
builder.setNote("Sketch-快捷键A");
builder.setHomework("课后新建几张Mac不同尺寸的画布");
System.out.println(builder.build());

CourseBuilder builderSj = new CourseBuilder()
.setName("设计模式")
.setPpt("设计模式PPT")
.setVideo("设计模式视频")
.setNote("设计模式笔记")
.setHomework("设计模式课后作业");
System.out.println(builderSj.build());
}
}

例二

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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
/**
* 产品
*/
public class Computer {
private String name;//电脑名称

private String mainBoard;//主板

private String computerChip;//芯片

private String graphicsCard;//显卡

private String memoryModule;//内存

private String displayScreen;//显示屏

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getMainBoard() {
return mainBoard;
}

public void setMainBoard(String mainBoard) {
this.mainBoard = mainBoard;
}

public String getComputerChip() {
return computerChip;
}

public void setComputerChip(String computerChip) {
this.computerChip = computerChip;
}

public String getGraphicsCard() {
return graphicsCard;
}

public void setGraphicsCard(String graphicsCard) {
this.graphicsCard = graphicsCard;
}

public String getMemoryModule() {
return memoryModule;
}

public void setMemoryModule(String memoryModule) {
this.memoryModule = memoryModule;
}

public String getDisplayScreen() {
return displayScreen;
}

public void setDisplayScreen(String displayScreen) {
this.displayScreen = displayScreen;
}

@Override
public String toString() {
return "Computer{" +
"name='" + name + '\'' +
", mainBoard='" + mainBoard + '\'' +
", computerChip='" + computerChip + '\'' +
", graphicsCard='" + graphicsCard + '\'' +
", memoryModule='" + memoryModule + '\'' +
", displayScreen='" + displayScreen + '\'' +
'}';
}
}

/**
* 建造者抽象类
*/
public abstract class Builder {
protected Computer computer = new Computer();

public abstract Builder setName(String name);
public abstract Builder setMainBoard(String mainBoard);
public abstract Builder setComputerChip(String computerChip);
public abstract Builder setGraphicsCard(String graphicsCard);
public abstract Builder setMemoryModule(String memoryModule);
public abstract Builder setDisplayScreen(String displayScreen);

public Computer build() {
return computer;
};
}

public class HpBuilder extends Builder {
@Override
public Builder setName(String name) {
computer.setName(name);
return this;
}

@Override
public Builder setMainBoard(String mainBoard) {
System.out.println("去惠普代工厂拿" + mainBoard);
computer.setMainBoard(mainBoard);
return this;
}

@Override
public Builder setComputerChip(String computerChip) {
System.out.println("去惠普代工厂拿" + computerChip);
computer.setComputerChip(computerChip);
return this;
}

@Override
public Builder setGraphicsCard(String graphicsCard) {
System.out.println("去惠普代工厂拿" + graphicsCard);
computer.setGraphicsCard(graphicsCard);
return this;
}

@Override
public Builder setMemoryModule(String memoryModule) {
System.out.println("去惠普代工厂拿" + memoryModule);
computer.setMemoryModule(memoryModule);
return this;
}

@Override
public Builder setDisplayScreen(String displayScreen) {
System.out.println("去惠普代工厂拿" + displayScreen);
computer.setDisplayScreen(displayScreen);
return this;
}
}

public class MacBuilder extends Builder {
@Override
public Builder setName(String name) {
computer.setName(name);
return this;
}

@Override
public Builder setMainBoard(String mainBoard) {
System.out.println("去Mac代工厂拿" + mainBoard);
computer.setMainBoard(mainBoard);
return this;
}

@Override
public Builder setComputerChip(String computerChip) {
System.out.println("去Mac代工厂拿" + computerChip);
computer.setComputerChip(computerChip);
return this;
}

@Override
public Builder setGraphicsCard(String graphicsCard) {
System.out.println("去Mac代工厂拿" + graphicsCard);
computer.setGraphicsCard(graphicsCard);
return this;
}

@Override
public Builder setMemoryModule(String memoryModule) {
System.out.println("去Mac代工厂拿" + memoryModule);
computer.setMemoryModule(memoryModule);
return this;
}

@Override
public Builder setDisplayScreen(String displayScreen) {
System.out.println("去Mac代工厂拿" + displayScreen);
computer.setDisplayScreen(displayScreen);
return this;
}
}

public class Director {
Builder builder = null;

public Director(Builder builder) {
this.builder = builder;
}

public void setBuilder(Builder builder) {
this.builder = builder;
}

/**
* @param name 电脑名称
* @param mainBoard 电脑主板
* @param computerChip 电脑芯片
* @param graphicsCard 电脑显卡
* @param memoryModule 电脑内存
* @param displayScreen 电脑显示屏
* @return Computer
*/
public Computer buyComputer(String name, String mainBoard, String computerChip, String graphicsCard, String memoryModule, String displayScreen) {
builder.setName(name);
builder.setMainBoard(mainBoard);
builder.setComputerChip(computerChip);
builder.setGraphicsCard(graphicsCard);
builder.setMemoryModule(memoryModule);
builder.setDisplayScreen(displayScreen);
return builder.build();
}
}

public class Run {
public static void main(String[] args) {
HpBuilder hpBuilder = new HpBuilder();
Director director = new Director(hpBuilder);
Computer hp = director.buyComputer("暗夜精灵", "惠普主板", "i9", "RTX2060", "16G", "17英寸");
System.out.println(hp.toString());

MacBuilder macBuilder = new MacBuilder();
director.setBuilder(macBuilder);
Computer mac = director.buyComputer("MacBookPro", "Apple主板", "M2", "16核神经网络引擎", "16G", "14 英寸 Liquid 视网膜 XDR 显示屏²");
System.out.println(mac.toString());
}
}

例三

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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
public abstract class House {
public String door;//门

public String window;//窗

public String yard;//院子

public String getDoor() {
return door;
}

public void setDoor(String door) {
this.door = door;
}

public String getWindow() {
return window;
}

public void setWindow(String window) {
this.window = window;
}

public String getYard() {
return yard;
}

public void setYard(String yard) {
this.yard = yard;
}

@Override
public String toString() {
return "House{" +
"door='" + door + '\'' +
", window='" + window + '\'' +
", yard='" + yard + '\'' +
'}';
}
}

public class CommonHouse extends House{
public void other() {
System.out.println("其他功能");
}
}

public class VillaHouse extends House {
public void fun() {
System.out.println("别墅特殊功能");
}
}

public abstract class Builder {
public abstract Builder setDoor(String door);
public abstract Builder setWindow(String window);
public abstract Builder setYard(String yard);

public abstract Object build();
}

public class CommonHouseBuilder extends Builder {
private CommonHouse commonHouse;

public CommonHouseBuilder() {
this.commonHouse = new CommonHouse();
}

@Override
public Builder setDoor(String door) {
commonHouse.setDoor(door);
return this;
}

@Override
public Builder setWindow(String window) {
commonHouse.setWindow(window);
return this;
}

@Override
public Builder setYard(String yard) {
commonHouse.setYard(yard);
return this;
}

@Override
public CommonHouse build() {
return commonHouse;
}
}

public class VillaHouseBuilder extends Builder {
private VillaHouse villaHouse;

public VillaHouseBuilder() {
villaHouse = new VillaHouse();
}

@Override
public Builder setDoor(String door) {
villaHouse.setDoor(door);
return this;
}

@Override
public Builder setWindow(String window) {
villaHouse.setWindow(window);
return this;
}

@Override
public Builder setYard(String yard) {
villaHouse.setYard(yard);
return this;
}

@Override
public VillaHouse build() {
return villaHouse;
}
}

public class Director {
private Builder builder;

public Director(Builder builder) {
this.builder = builder;
}

public void buildHouse_2D_4W_1Y() {
builder.setDoor("两个门").setWindow("四个窗").setYard("一个院子");
}

public void buildHouse_4D_8W_2Y() {
builder.setDoor("四个门").setWindow("八个窗").setYard("两个院子");
}
}

public class Run {
public static void main(String[] args) {
CommonHouseBuilder commonHouseBuilder = new CommonHouseBuilder();
Director director = new Director(commonHouseBuilder);
director.buildHouse_2D_4W_1Y();
CommonHouse commonHouse = commonHouseBuilder.build();
System.out.println(commonHouse.toString());
commonHouse.other();

VillaHouseBuilder villaHouseBuilder = new VillaHouseBuilder();
Director director1 = new Director(villaHouseBuilder);
director1.buildHouse_4D_8W_2Y();
VillaHouse villaHouse = villaHouseBuilder.build();
System.out.println(villaHouse.toString());
villaHouse.fun();
}
}

结构型模式

这些设计模式关注类和对象的组合继承的概念被用来组合接口和定义组合对象获得新功能的方式

适配器模式

适配器模式Adapter Pattern是作为两个不兼容的接口之间的桥梁这种类型的设计模式属于结构型模式它结合了两个独立接口的功能

这种模式涉及到一个单一的类该类负责加入独立的或不兼容的接口功能举个真实的例子读卡器是作为内存卡和笔记本之间的适配器您将内存卡插入读卡器再将读卡器插入笔记本这样就可以通过笔记本来读取内存卡

类适配器模式

  • 适配器类继承被适配者类
  • 适配器类转化被适配者类中的方法
  • 使用者类调用适配器类中的方法获取想要的值
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
public class Voltage220V {
public int output220V() {
System.out.println("输出220V电压");
return 220;
}
}

public interface Voltage5V {
public int output5v();
}

public class VoltageAdapter extends Voltage220V implements Voltage5V {
@Override
public int output5v() {
int srcV = output220V();
int dstV = srcV / 44;
System.out.println("转化为5V的电压");
return dstV;
}
}

public class mobilePhone {
public void charging(Voltage5V voltage5V) {
if (voltage5V.output5v() == 5){
System.out.println("手机开始充电...");
}
}
}

public class Run {
public static void main(String[] args) {
mobilePhone mobilePhone = new mobilePhone();
mobilePhone.charging(new VoltageAdapter());
}
}

对象适配器模式

  • 适配器类聚合被适配者类
  • 适配器类转化被适配者类中的方法
  • 使用者类获取适配器类的实例时传入被适配器类的实例
  • 使用者类调用适配器类中的方法获取想要的值
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
public class Voltage220V {
public int output220V() {
System.out.println("输出220V电压");
return 220;
}
}

public interface Voltage5V {
public int output5v();
}

public class VoltageAdapter implements Voltage5V {
private Voltage220V voltage220V;

public VoltageAdapter(Voltage220V voltage220V) {
this.voltage220V = voltage220V;
}

@Override
public int output5v() {
if (voltage220V == null) return 0;
int srcV = voltage220V.output220V();
int dstV = srcV / 44;
System.out.println("转化为5V的电压");
return dstV;
}
}

public class mobilePhone {
public void charging(Voltage5V voltage5V) {
if (voltage5V.output5v() == 5){
System.out.println("手机开始充电...");
}
}
}

public class Run {
public static void main(String[] args) {
mobilePhone mobilePhone = new mobilePhone();
mobilePhone.charging(new VoltageAdapter(new Voltage220V()));
}
}

接口适配器模式

  • 某一个接口中有很多方法但是只想用其中一个或几个
  • 创建一个抽象类实现接口的全部方法空方法即可
  • 实例化抽象类重写想要使用的方法即可
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
public interface AdvancedMediaPlayer {
public void playVlc(String fileName);
public void playMp4(String fileName);
}

public class Mp4Player implements AdvancedMediaPlayer {
@Override
public void playVlc(String fileName) {
//什么也不做
}

@Override
public void playMp4(String fileName) {
System.out.println("Playing mp4 file. Name: "+ fileName);
}
}

public class VlcPlayer implements AdvancedMediaPlayer {
@Override
public void playVlc(String fileName) {
System.out.println("Playing vlc file. Name: "+ fileName);
}

@Override
public void playMp4(String fileName) {
//什么也不做
}
}

public interface MediaPlayer {
public void play(String audioType, String fileName);
}

public class MediaAdapter implements MediaPlayer {
AdvancedMediaPlayer advancedMusicPlayer;

public MediaAdapter(String audioType){
if(audioType.equalsIgnoreCase("vlc") ){
advancedMusicPlayer = new VlcPlayer();
} else if (audioType.equalsIgnoreCase("mp4")){
advancedMusicPlayer = new Mp4Player();
}
}

@Override
public void play(String audioType, String fileName) {
if(audioType.equalsIgnoreCase("vlc")){
advancedMusicPlayer.playVlc(fileName);
}else if(audioType.equalsIgnoreCase("mp4")){
advancedMusicPlayer.playMp4(fileName);
}
}
}

public class AudioPlayer implements MediaPlayer {
MediaAdapter mediaAdapter;

@Override
public void play(String audioType, String fileName) {
//播放 mp3 音乐文件的内置支持
if(audioType.equalsIgnoreCase("mp3")){
System.out.println("Playing mp3 file. Name: "+ fileName);
}
//mediaAdapter 提供了播放其他文件格式的支持
else if(audioType.equalsIgnoreCase("vlc")
|| audioType.equalsIgnoreCase("mp4")){
mediaAdapter = new MediaAdapter(audioType);
mediaAdapter.play(audioType, fileName);
}
else{
System.out.println("Invalid media. "+ audioType + " format not supported");
}
}
}

public class Run {
public static void main(String[] args) {
AudioPlayer audioPlayer = new AudioPlayer();

audioPlayer.play("mp3", "beyond the horizon.mp3");
audioPlayer.play("mp4", "alone.mp4");
audioPlayer.play("vlc", "far far away.vlc");
audioPlayer.play("avi", "mind me.avi");
}
}

桥接模式

桥接模式Bridge Pattern是用于把抽象化与实现化解耦使得二者可以独立变化这种类型的设计模式属于结构型模式它通过提供抽象化和实现化之间的桥接结构来实现二者的解耦

这种模式涉及到一个作为桥接的接口使得实体类的功能独立于接口实现类这两种类型的类可被结构化改变而互不影响

适用于双重维度的情况就是多对多的概念桥接类似于关联关系表的概念

  • 多种操作系统需要播放多种视频格式的文件
  • 多种图形需要填充多种颜色

结构

  • 实现化角色接口/抽象类
  • 具体的实现化角色实现类实现实现化角色中的方法
  • 抽象化角色抽象类聚合实现化角色
  • 扩展抽象化角色实现抽象化角色中的方法
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
public interface VideoFile {
public void decode(String fileName);
}

public class AviVideoFile implements VideoFile {
@Override
public void decode(String fileName) {
System.out.println("播放avi格式" + fileName);
}
}

public class Mp4VideoFile implements VideoFile {
@Override
public void decode(String fileName) {
System.out.println("播放mp4格式" + fileName);
}
}

public class WmVideoFile implements VideoFile {
@Override
public void decode(String fileName) {
System.out.println("播放wmv格式" + fileName);
}
}

public abstract class OperationSystem {
protected VideoFile videoFile;

public OperationSystem(VideoFile videoFile) {
this.videoFile = videoFile;
}

public abstract void play(String fileName);
}

public class Mac extends OperationSystem {
public Mac(VideoFile videoFile) {
super(videoFile);
}

@Override
public void play(String fileName) {
videoFile.decode(fileName);
}
}

public class Window extends OperationSystem {
public Window(VideoFile videoFile) {
super(videoFile);
}

@Override
public void play(String fileName) {
videoFile.decode(fileName);
}
}

public class Client {
public static void main(String[] args) {
Window window = new Window(new Mp4VideoFile());
window.play("岁月神偷");

Window window1 = new Window(new WmVideoFile());
window1.play("神话");

Mac mac = new Mac(new AviVideoFile());
mac.play("惜往事");
}
}

装饰者模式

装饰器模式Decorator Pattern允许向一个现有的对象添加新的功能同时又不改变其结构这种类型的设计模式属于结构型模式它是作为现有的类的一个包装

这种模式创建了一个装饰类用来包装原有的类并在保持类方法签名完整性的前提下提供了额外的功能

结构

  • 抽象构件角色定义一个抽象接口用以规范->准备接收附加责任的对象
  • 具体构件角色实现抽象构件通过装饰角色为其添加一些职责
  • 抽象装饰角色继承或实现抽象构件并包含具体构件角色的实例可以通过其子类扩展具体构建角色的功能
  • 具体装饰角色实现抽象装饰的相关放啊并给具体构件对象添加附加的责任
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/**
* 抽象构件角色
*/
public abstract class FastFood {
private String name;//面条名称

private float price;//价格

//获取价格
public abstract float cost();

public FastFood(String name, float price) {
this.name = name;
this.price = price;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public float getPrice() {
return price;
}

public void setPrice(float price) {
this.price = price;
}
}

/**
* 具体构件角色
*/
public class BanMian extends FastFood {
public BanMian() {
super("板面", 15f);
}

@Override
public float cost() {
return getPrice();
}
}

/**
* 具体构件角色
*/
public class MiXian extends FastFood {
public MiXian() {
super("米线", 16f);
}

@Override
public float cost() {
return getPrice();
}
}

/**
* 抽象装饰角色
*/
public abstract class Garnish extends FastFood {
private FastFood fastFood;

public void setFastFood(FastFood fastFood) {
this.fastFood = fastFood;
}

public FastFood getFastFood() {
return fastFood;
}

public Garnish(FastFood fastFood, String name, float price) {
super(name, price);
this.fastFood = fastFood;
}
}

/**
* 具体装饰角色
*/
public class Egg extends Garnish {
public Egg(FastFood fastFood) {
super(fastFood, "鸡蛋", 2f);
}

@Override
public float cost() {
return getPrice() + getFastFood().cost();
}

@Override
public String getName() {
return getFastFood().getName() + super.getName();
}
}

/**
* 具体装饰角色
*/
public class WanZi extends Garnish {
public WanZi(FastFood fastFood) {
super(fastFood, "丸子", 3f);
}

@Override
public float cost() {
return getPrice() + getFastFood().cost();
}

@Override
public String getName() {
return getFastFood().getName() + super.getName();
}
}

public class Client {
public static void main(String[] args) {
//点一份板面
FastFood foot = new BanMian();

//加一个鸡蛋
foot = new Egg(foot);

//加一个丸子
foot = new WanZi(foot);

System.out.println(foot.getName());
System.out.println(foot.cost() + "元");

}
}

代理模式

在代理模式Proxy Pattern一个类代表另一个类的功能这种类型的设计模式属于结构型模式

代理模式分为静态代理动态代理JDK代理cglib代理防火墙代理缓存代理远程代理同步代理

结构

  • 被代理类的接口类
  • 被代理类
  • 代理类

静态代理

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
/**
* 出售门票被代理类的接口类
*/
public interface SellTickets {
void sell();
}

/**
* 火车站被代理类
*/
public class TrainStation implements SellTickets {
@Override
public void sell() {
System.out.println("火车站卖票");
}
}

/**
* 代售点代理类
*/
public class ProxyPoint implements SellTickets {
private TrainStation trainStation = new TrainStation();

@Override
public void sell() {
System.out.println("代售点收取一些代理费用");
trainStation.sell();
}
}

public class Client {
public static void main(String[] args) {
//创建一个代售点类
ProxyPoint proxyPoint = new ProxyPoint();
//调用代收点卖火车票的方法
proxyPoint.sell();
}
}

JDK代理

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
/**
* 出售门票被代理类的接口类
*/
public interface SellTickets {
void sell();
}

/**
* 火车站被代理类
*/
public class TrainStation implements SellTickets {
@Override
public void sell() {
System.out.println("火车站卖票");
}
}

/**
* 获取运行中生成的代理类
*/
public class ProxyFactory {
public Object proxyObj;

public ProxyFactory(Object proxyObj) {
this.proxyObj = proxyObj;
}

public Object getProxyObject() {
return Proxy.newProxyInstance(
proxyObj.getClass().getClassLoader(),
proxyObj.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("使用JDK_Proxy动态代理");
return method.invoke(proxyObj, args);
}
});
}
}

public class Client {
public static void main(String[] args) {
ProxyFactory proxyFactory = new ProxyFactory(new TrainStation());
SellTickets proxyObject = (SellTickets) proxyFactory.getProxyObject();
proxyObject.sell();
}
}

cglib代理

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
/**
* 火车站被代理类
*/
public class TrainStation {
public void sell() {
System.out.println("火车站卖票");
}
}

/**
* 获取运行中生成的代理类
*/
public class ProxyFactory implements MethodInterceptor {
public Object proxyObj;

public ProxyFactory(Object proxyObj) {
this.proxyObj = proxyObj;
}

public Object getProxyObject() {
//创建Enhancer对象类似于JDK代理中Proxy对象
Enhancer enhancer = new Enhancer();
//设置父类的字节码对象
enhancer.setSuperclass(proxyObj.getClass());
//设置回调函数
enhancer.setCallback(this);
//创建代理对象
return enhancer.create();
}

@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("使用cglib动态代理");
return method.invoke(proxyObj, objects);
}
}

public class Client {
public static void main(String[] args) {
ProxyFactory proxyFactory = new ProxyFactory(new TrainStation());
TrainStation proxyObject = (TrainStation) proxyFactory.getProxyObject();
proxyObject.sell();
}
}

外观模式

外观模式Facade Pattern隐藏系统的复杂性并向客户端提供了一个客户端可以访问系统的接口这种类型的设计模式属于结构型模式它向现有的系统添加一个接口来隐藏系统的复杂性

这种模式涉及到一个单一的类该类提供了客户端请求的简化方法和对现有系统类方法的委托调用

结构

  • 功能角色
  • 外观角色
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
/**
* 功能角色空调
*/
public class AirCondition {
public void on() {
System.out.println("打开空调...");
}

public void off() {
System.out.println("关闭空调...");
}
}

/**
* 功能角色电灯类
*/
public class Light {
public void on() {
System.out.println("打开电灯...");
}

public void off() {
System.out.println("关闭电灯...");
}
}

/**
* 功能角色电视
*/
public class TV {
public void on() {
System.out.println("打开电视...");
}

public void off() {
System.out.println("关闭电视...");
}
}

/**
* 外观角色
*/
public class Facade {
private Light light;
private TV tv;
private AirCondition airCondition;

public Facade() {
this.light = new Light();
this.tv = new TV();
this.airCondition = new AirCondition();
}

public void say(String str) {
if (str.contains("打开")) {
on();
} else if (str.contains("关闭")) {
off();
} else {
System.out.println("暂时还没有这个功能...");
}
}

private void on() {
light.on();
tv.on();
airCondition.on();
}

private void off() {
light.off();
tv.off();
airCondition.off();
}
}

public class Client {
public static void main(String[] args) {
Facade facade = new Facade();

facade.say("打开家电");
facade.say("关闭家电");
}
}

享元模式

享元模式Flyweight Pattern主要用于减少创建对象的数量以减少内存占用和提高性能这种类型的设计模式属于结构型模式它提供了减少对象数量从而改善应用所需的对象结构的方式

享元模式尝试重用现有的同类对象如果未找到匹配的对象则创建新对象

结构

  • 抽象享元角色通常是一个接口或抽象类在抽象享元类中声明了具体享元类公共的方法这些方法可以向外界提供享元对象的内部数据内部状态同时也可以通过这些方法来设置外部数据外部状态
  • 具体享元角色它实现了抽象享元类称为享元对象在具体享元类中为内部状态提供了储存空间通常我们可以结合单例模式来设计具体享元类为每一个具体享元类提供唯一的享元对象
  • 非享元角色并不是所有的抽象享元类的子类都需要被共享不能被共享的子类可设计为非共享具体享元类当需要一个非共享具体享元类的对象时可以直接通过实例化创建
  • 享元工厂负责创建和管理享元角色当客户对象请求一个享元对象时享元工厂检查系统中是否存在符合要求的享元对象如果存在则提供给客户如果不存在的话则创建一个新的享元对象
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
/**
* 抽象享元角色
*/
public abstract class Box {
public abstract String getShape();

public void display(String color) {
System.out.println("方块形状" + getShape() + ", 颜色" + color);
}
}

/**
* 具体享元角色
*/
public class IBox extends Box{
@Override
public String getShape() {
return "I";
}
}

/**
* 具体享元角色
*/
public class LBox extends Box{
@Override
public String getShape() {
return "L";
}
}

/**
* 具体享元角色
*/
public class OBox extends Box{
@Override
public String getShape() {
return "O";
}
}

/**
* 享元工厂
*/
public class BoxFactory {
private HashMap<String, Box> map;

private BoxFactory() {
map = new HashMap<>();
map.put("I", new IBox());
map.put("L", new LBox());
map.put("O", new OBox());
}

private static BoxFactory factory = new BoxFactory();
public static BoxFactory getInstance() {
return factory;
}

public Box getShape(String name) {
return map.get(name);
}
}

public class Client {
public static void main(String[] args) {
BoxFactory instance = BoxFactory.getInstance();

Box i = instance.getShape("I");
i.display("灰色");

Box l = instance.getShape("L");
l.display("绿色");

Box o = instance.getShape("O");
o.display("蓝色");

Box o1 = instance.getShape("O");
o1.display("紫色");

System.out.println(o == o1);
}
}

组合模式

组合模式Composite Pattern又叫部分整体模式是用于把一组相似的对象当作一个单一的对象组合模式依据树形结构来组合对象用来表示部分以及整体层次这种类型的设计模式属于结构型模式它创建了对象组的树形结构

这种模式创建了一个包含自己对象组的类该类提供了修改相同对象组的方式

结构

  • 抽象根节点定义系统各个层次的共有方法和属性可以先定义一些默认行为和属性
  • 树枝节点定义数值节点的行为储存子节点组合树枝节点和叶子节点形成一个树形结构
  • 叶子节点叶子节点对象其 下再无分支是系统层次遍历的最小单位
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
/**
* 抽象根节点
*/
public abstract class MenuComponent {
protected String name;//名称

protected int type;//1文件夹2文件

public void add(MenuComponent menuComponent) {
throw new UnsupportedOperationException();
}

public void remove(MenuComponent menuComponent) {
throw new UnsupportedOperationException();
}

public MenuComponent getChild(int index) {
throw new UnsupportedOperationException();
}

public String getName() {
return name;
}

public abstract void print();
}

/**
* 树枝节点
*/
public class Menu extends MenuComponent {
private List<MenuComponent> menuComponentList = new ArrayList<>();

public Menu(String name, int type) {
this.name = name;
this.type = type;
}

@Override
public void add(MenuComponent menuComponent) {
menuComponentList.add(menuComponent);
}

@Override
public void remove(MenuComponent menuComponent) {
menuComponentList.remove(menuComponent);
}

@Override
public MenuComponent getChild(int index) {
return menuComponentList.get(index);
}

@Override
public void print() {
String s = type == 1 ? ">" : "-";
System.out.println(s + " " + name);
menuComponentList.forEach(MenuComponent::print);
}
}

/**
* 叶子节点
*/
public class MenuItem extends MenuComponent {
public MenuItem(String name, int type) {
this.name = name;
this.type = type;
}

@Override
public void print() {
String s = type == 1 ? ">" : "-";
System.out.println(s + " " + name);
}
}

public class Client {
public static void main(String[] args) {
MenuComponent menu1 = new Menu("菜单管理", 1);
menu1.add(new MenuItem("页面访问", 2));
menu1.add(new MenuItem("展开菜单", 2));
menu1.add(new MenuItem("编辑菜单", 2));
menu1.add(new MenuItem("删除菜单", 2));
menu1.add(new MenuItem("新增菜单", 2));

MenuComponent menu2 = new Menu("权限管理", 1);
menu2.add(new MenuItem("页面访问", 2));
MenuItem menuItem = new MenuItem("提交保存", 2);
menu2.add(menuItem);
menu2.remove(menuItem);

MenuComponent menu3 = new Menu("角色管理", 1);
menu3.add(new MenuItem("页面访问", 2));
menu3.add(new MenuItem("新增角色", 2));
menu3.add(new MenuItem("修改角色", 2));
menu3.add(new MenuItem("删除角色", 2));

MenuComponent menuSys = new Menu("系统管理", 1);
menuSys.add(menu1);
menuSys.add(menu2);
menuSys.add(menu3);

MenuComponent menuEmploy = new Menu("员工管理", 1);

MenuComponent company = new Menu("公司管理平台", 1);
company.add(menuSys);
company.add(menuEmploy);

company.print();

MenuComponent child = company.getChild(0).getChild(1);
child.print();
}
}

行为型模式

这些设计模式特别关注对象之间的通信

模板模式

在模板模式Template Pattern一个抽象类公开定义了执行它的方法的方式/模板它的子类可以按需要重写方法实现但调用将以抽象类中定义的方式进行这种类型的设计模式属于行为型模式

结构

  • 抽象类负责给出一个算法的轮廓和骨架它由一个模板方法和若干个基本方法构成
    • 模板方法定义了算法的骨架按某种顺序调用其包含的方法
    • 基本方法实现算法的各个步骤的方法是模板方法的组成部分基本方法可以分为三种
    • 抽象方法一个抽象方法有抽象类声明由其具体子类实现
    • 具体方法一个具体方法由一个抽象类或具体类声明实现其子类可以进行覆盖也可以直接继承
    • 钩子方法在抽象类中已经实现包括用于判断的逻辑方法和需要子类重写的空方法两种一般钩子方法是用于判断的逻辑方法返回值类型为Boolean
  • 具体子类实现抽象类中定义所定义的抽象方法和钩子方法他们是一个顶级逻辑的组成步骤
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
public abstract class SoyaMilk {
//模板方法,final修饰不让子类覆盖
public final void make() {
select();
if (isAddCondiments()) {
addCondiments();
}
soak();
beat();
}

//选材料
public void select() {
System.out.println("选材料选择新鲜的黄豆");
}

//添加不同的配料由子类去实现
public abstract void addCondiments();

//浸泡
public void soak() {
System.out.println("开始浸泡需要三个小时");
}

public void beat() {
System.out.println("放入豆浆机开始制作豆浆");
}

//钩子方法//是否需要添加配料
public boolean isAddCondiments() {
return true;
}
}

public class ChunSoyaMilk extends SoyaMilk {
@Override
public void addCondiments() {
//没有这个步骤可以空实现
}

@Override
public boolean isAddCondiments() {
return false;
}
}

public class HongdouSoyaMilk extends SoyaMilk {
@Override
public void addCondiments() {
System.out.println("添加红豆配料");
}
}

public class HongzaoSoyaMilk extends SoyaMilk {
@Override
public void addCondiments() {
System.out.println("添加红枣配料");
}
}

public class Client {
public static void main(String[] args) {
System.out.println("--- 制作红豆豆浆 ---");
SoyaMilk hongdouSoyaMilk = new HongdouSoyaMilk();
hongdouSoyaMilk.make();

System.out.println("--- 制作红枣豆浆 ---");
SoyaMilk hongzaoSoyaMilk = new HongzaoSoyaMilk();
hongzaoSoyaMilk.make();

System.out.println("--- 制作纯豆浆 ---");
SoyaMilk chunSoyaMilk = new ChunSoyaMilk();
chunSoyaMilk.make();
}
}

命令模式

命令模式Command Pattern是一种数据驱动的设计模式它属于行为型模式请求以命令的形式包裹在对象中并传给调用对象调用对象寻找可以处理该命令的合适的对象并把该命令传给相应的对象该对象执行命令

结构

  • 抽象命令类角色定义命令接口声明执行的方法
  • 具体命令角色具体的命令实现命令接口通常会持有接收者并调用接收者的功能来完成命令要执行的操作
  • 实现者/接收者角色真正执行命令的对象任何类都可能成为一个接收者只要它能够实现命令要求实现的相应功能
  • 调用者/请求者角色要求命令对象执行请求通常会持有命令对象可以持有很多的命令对象这个是客户端真正触发命令并要求命令执行相应操作的地方也就是说相当于使用命令对象的接口
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/**
* 抽象命令类角色
*/
public interface Command {
//执行命令
public void execute();

//撤销命令
public void undo();
}

/**
* 具体命令角色
*/
public class DengpaoOffCommand implements Command{
Dengpao dengpao;

public DengpaoOffCommand(Dengpao dengpao) {
this.dengpao = dengpao;
}

@Override
public void execute() {
dengpao.off();
}

@Override
public void undo() {
dengpao.on();
}
}

/**
* 具体命令角色
*/
public class DengpaoOnCommand implements Command{
Dengpao dengpao;

public DengpaoOnCommand(Dengpao dengpao) {
this.dengpao = dengpao;
}

@Override
public void execute() {
dengpao.on();
}

@Override
public void undo() {
dengpao.off();
}
}

/**
* 具体命令角色(空命令)用于初始化命令当调用空命令时对象什么都不做
*/
public class NoCommand implements Command{
@Override
public void execute() {

}

@Override
public void undo() {

}
}

/**
* 灯泡 实现者/接收者角色
*/
public class Dengpao {
public void on() {
System.out.println("灯泡打开了...");
}

public void off() {
System.out.println("灯泡关闭了...");
}
}

public class RemoteController {
//要执行的命令
Map<String, Command> onCommands;
Map<String, Command> offCommands;

//撤销命令
Command undoCommand;

public RemoteController() {
onCommands = new HashMap<>();
offCommands = new HashMap<>();
}

public void setCommand(String commandKey, Command onCommand, Command offCommand) {
onCommands.put(commandKey, onCommand);
offCommands.put(commandKey, offCommand);
}

public void onButtonPushed(String commandKey) {
Command command = onCommands.get(commandKey);
if (command != null) {
//执行命令
command.execute();
//用于撤销命令
undoCommand = command;
}
}

public void offButtonPushed(String commandKey) {
Command command = offCommands.get(commandKey);
if (command != null) {
//执行命令
command.execute();
//用于撤销命令
undoCommand = command;
}
}

public void undoButtonPushed() {
if (undoCommand != null) {
undoCommand.undo();
}
}
}

public class Client {
public static void main(String[] args) {
//灯泡实例实现者/接收者角色
Dengpao dengpao = new Dengpao();
//操作灯泡的命令具体命令角色
DengpaoOnCommand dengpaoOnCommand = new DengpaoOnCommand(dengpao);
DengpaoOffCommand dengpaoOffCommand = new DengpaoOffCommand(dengpao);

//遥控器调用者/请求者角色
RemoteController remoteController = new RemoteController();

//添加命令
String dengpaoCommandKey = "dengpao";
remoteController.setCommand(dengpaoCommandKey, dengpaoOnCommand, dengpaoOffCommand);

//执行命令
remoteController.onButtonPushed(dengpaoCommandKey);
remoteController.offButtonPushed(dengpaoCommandKey);
remoteController.undoButtonPushed();
}
}

策略模式

在策略模式Strategy Pattern一个类的行为或其算法可以在运行时更改这种类型的设计模式属于行为型模式

该模式定义了一系列算法并将每个算法封装起来使它们可以相互替换且算法的变化不会影响使用算法的客户

通过对算法进行封装把使用算法的责任和算法的实现分割开来并委派给不同的对象对这些算法进行管理

结构

  • 环境角色持有一个策略类的引用最终给客户端调用
  • 抽象策略角色通常由一个接口或者是抽象类实现此角色给出所有的具体策略类所需的接口
  • 具体策略角色实现了抽象策略定义的接口提供具体的算法实现或行为
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
/**
* 抽象策略角色
*/
public interface Strategy {
void show();
}

/**
* 具体策略角色
*/
public class StrategyA implements Strategy {
@Override
public void show() {
System.out.println("买一送一");
}
}

/**
* 具体策略角色
*/
public class StrategyB implements Strategy {
@Override
public void show() {
System.out.println("满二百减五十");
}
}

/**
* 具体策略角色
*/
public class StrategyC implements Strategy {
@Override
public void show() {
System.out.println("满加一千元加一元换购任意二百元以下商品");
}
}

/**
* 环境角色
*/
public class SaleMan {
private Strategy strategy;

public SaleMan(Strategy strategy) {
this.strategy = strategy;
}

public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}

public void show() {
strategy.show();
}
}

public class Client {
public static void main(String[] args) {
SaleMan saleMan = new SaleMan(new StrategyA());
saleMan.show();

saleMan.setStrategy(new StrategyB());
saleMan.show();

saleMan.setStrategy(new StrategyC());
saleMan.show();
}
}

责任链模式

责任链模式Chain of Responsibility Pattern又叫职责链模式该模式为请求创建了一个接收者对象的链这种模式给予请求的类型对请求的发送者和接收者进行解耦这种类型的设计模式属于行为型模式

在这种模式中通常每个接收者都包含对另一个接收者的引用如果一个对象不能处理该请求那么它会把相同的请求传给下一个接收者依此类推

为了避免请求发送者与多个请求处理者耦合在一起将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链 当有请求发生时可将请求沿着这条链传递直到有对象处理它为止

结构

  • 抽象处理者角色定义一个处理请求的接口包含抽象处理方法和一个后继连接
  • 具体处理者角色实现抽象处理者的处理方法判断是否可以处理本次请求如果可以处理请求则处理否则将该请求转给它的后继者
  • 客户类角色创建处理链并将链头的具体处理者对象提交请求它不关心处理细节和请求的传递过程
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/**
* 抽象处理者角色
*/
public abstract class Handler {
//请假天数
protected final static int NUM_ONE = 1;
protected final static int NUM_THREE = 3;
protected final static int NUM_SEVEN = 7;

//请假区间
private int numStart;
private int numEnd;

//下一个处理者
private Handler nextHandler;

public Handler(int numStart) {
this.numStart = numStart;
}

public Handler(int numStart, int numEnd) {
this.numStart = numStart;
this.numEnd = numEnd;
}

public void setNextHandler(Handler nextHandler) {
this.nextHandler = nextHandler;
}

//处理请假请求
protected abstract void handlerLeave(LeaveRequest leave);

//提交请假请求
public final void submit(LeaveRequest leave) {
if (this.numStart <= leave.getNum() && leave.getNum() <= this.numEnd) {
this.handlerLeave(leave);
} else if (this.nextHandler != null) {
this.nextHandler.submit(leave);
} else {
System.out.println("请假天数不符合规定");
}
}
}

/**
* 具体处理者角色总经理
*/
public class GeneralLeader extends Handler{
public GeneralLeader() {
super(NUM_THREE, NUM_SEVEN);
}

@Override
protected void handlerLeave(LeaveRequest leave) {
System.out.println(leave.getName() + "请假" + leave.getNum() + "天" + leave.getContent());
System.out.println("总经理审批同意");
}
}

/**
* 具体处理者角色部门经理
*/
public class ManagerLeader extends Handler{
public ManagerLeader() {
super(NUM_ONE, NUM_THREE);
}

@Override
protected void handlerLeave(LeaveRequest leave) {
System.out.println(leave.getName() + "请假" + leave.getNum() + "天" + leave.getContent());
System.out.println("部门经理审批同意");
}
}

/**
* 具体处理者角色小组长
*/
public class GroupLeader extends Handler{
public GroupLeader() {
super(0, NUM_ONE);
}

@Override
protected void handlerLeave(LeaveRequest leave) {
System.out.println(leave.getName() + "请假" + leave.getNum() + "天" + leave.getContent());
System.out.println("小组长审批同意");
}
}

/**
* 请假条实体
*/
public class LeaveRequest {
//姓名
private String name;

//天数
private int num;

//内容
private String content;

public LeaveRequest(String name, int num, String content) {
this.name = name;
this.num = num;
this.content = content;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getNum() {
return num;
}

public void setNum(int num) {
this.num = num;
}

public String getContent() {
return content;
}

public void setContent(String content) {
this.content = content;
}
}

public class Client {
public static void main(String[] args) {
LeaveRequest request = new LeaveRequest("小明", 8, "身体不适");

GroupLeader groupLeader = new GroupLeader();
ManagerLeader managerLeader = new ManagerLeader();
GeneralLeader generalLeader = new GeneralLeader();

groupLeader.setNextHandler(managerLeader);
managerLeader.setNextHandler(generalLeader);

groupLeader.submit(request);
}
}

状态模式

在状态模式State Pattern类的行为是基于它的状态改变的这种类型的设计模式属于行为型模式

对有状态的对象把复杂的判断逻辑提取到不同的状态对象中允许状态对象在其内部状态发生改变时改变其行为

结构

  • 环境角色也称为上下文它定义了客户程序需要的接口维护一个当前状态并将于状态相关的操作委托给当前状态对象来处理
  • 抽象状态角色定义一个接口用于封装环境对象中的特定状态所对应的行为
  • 具体状态角色实现抽象状态所对应的行为
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
/**
* 环境角色
*/
public class Context {
public final static OpenState OPEN_STATE = new OpenState();

public final static CloseState CLOSE_STATE = new CloseState();

public final static RunState RUN_STATE = new RunState();

public final static StopState STOP_STATE = new StopState();

private LiftState liftState;

public LiftState getLiftState() {
return liftState;
}

public void setLiftState(LiftState liftState) {
this.liftState = liftState;
this.liftState.setContext(this);
}

public void open(){
this.liftState.open();
};
public void close(){
this.liftState.close();
};
public void run(){
this.liftState.run();
};
public void stop(){
this.liftState.stop();
};
}

/**
* 抽象状态角色
*/
public abstract class LiftState {
protected Context context;

public void setContext(Context context) {
this.context = context;
}

public abstract void open();
public abstract void close();
public abstract void run();
public abstract void stop();
}

/**
* 具体状态角色
*/
public class CloseState extends LiftState {
@Override
public void open() {
super.context.setLiftState(Context.OPEN_STATE);
super.context.open();
}

@Override
public void close() {
System.out.println("电梯关闭...");
}

@Override
public void run() {
super.context.setLiftState(Context.RUN_STATE);
super.context.run();
}

@Override
public void stop() {
super.context.setLiftState(Context.STOP_STATE);
super.context.stop();
}
}

/**
* 具体状态角色
*/
public class OpenState extends LiftState {
@Override
public void open() {
System.out.println("电梯开启...");
}

@Override
public void close() {
super.context.setLiftState(Context.CLOSE_STATE);
super.context.close();
}

@Override
public void run() {

}

@Override
public void stop() {

}
}

/**
* 具体状态角色
*/
public class RunState extends LiftState {
@Override
public void open() {

}

@Override
public void close() {

}

@Override
public void run() {
System.out.println("电梯正在运行...");
}

@Override
public void stop() {
super.context.setLiftState(Context.STOP_STATE);
super.context.stop();
}
}

/**
* 具体状态角色
*/
public class StopState extends LiftState {
@Override
public void open() {
super.context.setLiftState(Context.OPEN_STATE);
super.context.open();
}

@Override
public void close() {
super.context.setLiftState(Context.CLOSE_STATE);
super.context.close();
}

@Override
public void run() {
super.context.setLiftState(Context.RUN_STATE);
super.context.run();
}

@Override
public void stop() {
System.out.println("电梯停止了...");
}
}

public class Client {
public static void main(String[] args) {
Context context = new Context();
context.setLiftState(new RunState());

context.open();
context.close();
context.run();
context.stop();

context.open();
}
}

观察者模式

观察者模式Observer Pattern又被称之为发布-订阅模式当一个对象被修改时则会自动通知依赖它的对象观察者模式属于行为型模式

它定义了一种一对多的依赖关系让多个观察者对象同时监听某一个主题对象这个主题对象在状态发生变化时会通知所有观察者对象使他们能够自动更新

JDK源码java.util.Observable

结构

  • 抽象主题抽象被观察者抽象主题角色把所有观察者对象保存在一个集合里每个主题都可以有任意数量的观察者抽象主题提供一个接口可以增加和删除观察者对象
  • 具体主题具体被观察者该角色将有关状态存入具体观察者对象在具体主题的内部状态发生改变时给所有注册过的观察者发送通知
  • 抽象观察者是观察者的抽象类它定义了一个更新接口使得在得到主题更改通知时更新自己
  • 具体观察者具体观察者实现抽象观察者定义的更新接口以便在得到主题更改通知时更新自己的状态
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
/**
* 抽象主题抽象被观察者
*/
public interface Subject {
//添加订阅者
public void add(Observer o);

//移除订阅者
public void remove(Observer o);

//发送通知
public void notify(String message);
}

/**
* 具体主题具体被观察者
*/
public class SubscriptionSubject implements Subject {
private ArrayList<Observer> observers = new ArrayList<>();

@Override
public void add(Observer o) {
observers.add(o);
}

@Override
public void remove(Observer o) {
observers.remove(o);
}

@Override
public void notify(String message) {
for (Observer observer : observers) {
observer.update(message);
}
}
}

/**
* 抽象观察者
*/
public interface Observer {
public void update(String message);
}

/**
* 具体观察者
*/
public class WeXinUser implements Observer {
private String name;

public WeXinUser(String name) {
this.name = name;
}

@Override
public void update(String message) {
System.out.println(name+"接到更新通知"+message);
}
}

public class Client {
public static void main(String[] args) {
SubscriptionSubject subscriptionSubject = new SubscriptionSubject();

subscriptionSubject.add(new WeXinUser("孙悟空"));
subscriptionSubject.add(new WeXinUser("猪悟能"));
subscriptionSubject.add(new WeXinUser("沙悟净"));

subscriptionSubject.notify("师傅被妖怪抓走了");
}
}

中介者模式

中介者模式Mediator Pattern又叫调停模式是用来降低多个对象和类之间的通信复杂性这种模式提供了一个中介类该类通常处理不同类之间的通信并支持松耦合使代码易于维护中介者模式属于行为型模式

定义一个中介角色来封装一系列对象之间的交互使原有对象之间的耦合松散且可以独立地改变它们之间的交互

结构

  • 抽象中介者角色它是中介者的接口提供了同事对象注册与转发同事对象信息的抽象方法
  • 具体中介者角色实现中介者接口定义一个List来管理同事对象协调各个同事角色之间的交互关系因此它依赖于同事角色
  • 抽象同事类角色定义同事类接口保存中介者对象提供同事对象交互的抽象方法实现所有相互影响的同事类的公共功能
  • 具体同事类角色是抽象同事类的实现者当需要与其他同事对象交互时由中介者对象负责后续的交互
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
/**
* 抽象中介者角色
*/
public abstract class Mediator {
public abstract void contact(String message, Person person);
}

/**
* 具体中介者角色
*/
public class MediatorStructure extends Mediator {
private HouseOwner houseOwner;

private Tenant tenant;

@Override
public void contact(String message, Person person) {
if (person == houseOwner) {
tenant.getMessage(message);
} else {
houseOwner.getMessage(message);
}
}

public HouseOwner getHouseOwner() {
return houseOwner;
}

public void setHouseOwner(HouseOwner houseOwner) {
this.houseOwner = houseOwner;
}

public Tenant getTenant() {
return tenant;
}

public void setTenant(Tenant tenant) {
this.tenant = tenant;
}
}

/**
* 抽象同事类角色
*/
public abstract class Person {
protected String name;

protected Mediator mediator;

public Person(String name, Mediator mediator) {
this.name = name;
this.mediator = mediator;
}
}

/**
* 具体同事类角色
*/
public class HouseOwner extends Person {
public HouseOwner(String name, Mediator mediator) {
super(name, mediator);
}

public void contact(String message) {
mediator.contact(message, this);
}

public void getMessage(String message) {
System.out.println("房主" + name + "获取到的信息是" + message);
}
}

/**
* 具体同事类角色
*/
public class Tenant extends Person {
public Tenant(String name, Mediator mediator) {
super(name, mediator);
}

public void contact(String message) {
mediator.contact(message, this);
}

public void getMessage(String message) {
System.out.println("租房者" + name + "获取到的信息是" + message);
}
}

public class Client {
public static void main(String[] args) {
MediatorStructure mediatorStructure = new MediatorStructure();
Tenant tenant = new Tenant("李四", mediatorStructure);
HouseOwner houseOwner = new HouseOwner("张三", mediatorStructure);

mediatorStructure.setTenant(tenant);
mediatorStructure.setHouseOwner(houseOwner);

tenant.contact("我要租三室的房子");
houseOwner.contact("我这里有三室的房子你要租吗");
}
}

迭代器模式

迭代器模式Iterator Pattern是 Java 和 .Net 编程环境中非常常用的设计模式这种模式用于顺序访问集合对象的元素不需要知道集合对象的底层表示迭代器模式属于行为型模式

提供一个对象来顺序访问聚合对象中的一系列数据而不暴露聚合对象的内部表示

结构

  • 抽象聚合角色定义储存添加删除聚合元素以及创建迭代器对象的接口
  • 具体聚合角色实现抽象聚合类返回一个具体迭代器的实例
  • 抽象迭代器角色定义访问和遍历聚合元素的接口通常包含hasNext()next()等方法
  • 具体迭代器角色实现抽象迭代器接口中所定义的方法完成对聚合对象的遍历记录遍历的当前位置
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
118
119
120
121
122
123
124
125
/**
* 实体
*/
public class Student {
private String name;

private String number;

public Student(String name, String number) {
this.name = name;
this.number = number;
}

@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", number='" + number + '\'' +
'}';
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getNumber() {
return number;
}

public void setNumber(String number) {
this.number = number;
}
}

/**
* 抽象聚合角色
*/
public interface StudentAggregate {
//添加
void addStudent(Student student);

//删除
void removeStudent(Student student);

//获取迭代器
StudentIterator getStudentIterator();
}

/**
* 具体聚合角色
*/
public class StudentAggregateImpl implements StudentAggregate {
private List<Student> list = new ArrayList<>();

@Override
public void addStudent(Student student) {
list.add(student);
}

@Override
public void removeStudent(Student student) {
list.remove(student);
}

@Override
public StudentIterator getStudentIterator() {
return new StudentIteratorImpl(list);
}
}


/**
* 抽象迭代器角色
*/
public interface StudentIterator {
//判断是否还有元素
boolean hasNext();

//获取下一个元素
Student next();
}

/**
* 具体迭代器角色
*/
public class StudentIteratorImpl implements StudentIterator {
private List<Student> list;
private int position = 0;

public StudentIteratorImpl(List<Student> list) {
this.list = list;
}

@Override
public boolean hasNext() {
return position < list.size();
}

@Override
public Student next() {
Student student = list.get(position);
position++;
return student;
}
}

public class Client {
public static void main(String[] args) {
StudentAggregateImpl aggregate = new StudentAggregateImpl();
aggregate.addStudent(new Student("张三", "001"));
aggregate.addStudent(new Student("李四", "002"));
aggregate.addStudent(new Student("王五", "003"));
aggregate.addStudent(new Student("赵六", "004"));

StudentIterator iterator = aggregate.getStudentIterator();
while (iterator.hasNext()){
Student next = iterator.next();
System.out.println(next.toString());
}
}
}

访问者模式

在访问者模式Visitor Pattern我们使用了一个访问者类它改变了元素类的执行算法通过这种方式元素的执行算法可以随着访问者改变而改变这种类型的设计模式属于行为型模式根据模式元素对象已接受访问者对象这样访问者对象就可以处理元素对象上的操作

封装一些作用于某种数据结构中的各元素的操作它可以在不改变这个数据结构的前提下定义作用于这些元素的新的操作

结构

  • 抽象访问者角色定义了对每一个元素访问的行为它的参数就是可以访问的元素它的方法个数理论上来讲与元素类个数是一样的访问者模式要求元素类的个数不能改变
  • 具体访问者角色给出对每一个元素类访问时所产生的具体行为
  • 抽象元素角色定义了一个接受访问者的方法其意义是指每一个元素都要可以被访问者访问
  • 具体元素角色提供接受访问方法的具体实现而这个具体的实现通常情况下是使用访问者提供的访问该元素类的方法
  • 对象结构角色定义当中所提到的对象结构对象结构是一个抽象表述具体点可以理解为一个具有容器性质或者复合对象特性的类它会含有一组元素并且可以迭代这些元素供访问者访问
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
/**
* 抽象访问者角色
*/
public interface Person {
//给宠物猫喂食
void feed(Cat cat);

//给宠物狗喂食
void feed(Dog cat);
}

/**
* 具体访问者角色
*/
public class Owner implements Person {
@Override
public void feed(Cat cat) {
System.out.println("主人给猫咪喂食...");
}

@Override
public void feed(Dog cat) {
System.out.println("主人给狗狗喂食...");
}
}

/**
* 具体访问者角色
*/
public class Someone implements Person {
@Override
public void feed(Cat cat) {
System.out.println("其他人给猫咪喂食...");
}

@Override
public void feed(Dog cat) {
System.out.println("其他人给狗狗喂食...");
}
}

/**
* 抽象元素角色
*/
public interface Animal {
//接受访问者访问的功能
void accept(Person person);
}

/**
* 具体元素角色
*/
public class Cat implements Animal {
@Override
public void accept(Person person) {
person.feed(this);
System.out.println("喵喵喵...");
}
}

/**
* 具体元素角色
*/
public class Dog implements Animal {
@Override
public void accept(Person person) {
person.feed(this);
System.out.println("汪汪汪...");
}
}

/**
* 对象结构角色
*/
public class Home {
//声明一个集合对象用来储存元素对象
private List<Animal> animals = new ArrayList<>();

//添加元素对象
public void add(Animal animal) {
animals.add(animal);
}

//访问每个元素
public void action(Person person) {
for (Animal animal:animals) {
animal.accept(person);
}
}
}

public class Client {
public static void main(String[] args) {
Home home = new Home();
home.add(new Cat());
home.add(new Dog());

Owner owner = new Owner();
home.action(owner);
}
}

备忘录模式

备忘录模式Memento Pattern又叫快照模式在不破坏封装性的前提下捕获一个对象的内部状态并在该对象之外保存这个状态以便以后当需要时能将该对象恢复到原先保存的状态备忘录模式属于行为型模式

结构

  • 发起人角色记录当前时刻的内部状态信息提供创建备忘录和恢复备忘录数据的功能实现其他业务功能它可以访问备忘录里的所有信息
  • 备忘录角色负责存储发起人的内部状态在需要的时候提供这些内部状态给发起人
  • 管理者角色对备忘录进行管理提供保存与获取备忘录功能但其不能对备忘录的内容进行访问与修改
  • 备忘录有两个等效的接口
    • 窄接口管理者对象和其他发起人对象之外的任何对象看到的都是备忘录的窄接口这个窄接口只允许它把备忘录对象传给其他对象
    • 宽接口与管理者看到的窄接口相反发起人对象可以看到一个宽接口这个宽接口允许它读取所有的数据以便根据这些数据恢复这个发起人对象的内部状态

例一

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
/**
* 备忘录角色对外提供的窄接口
*/
public interface Memento {
}

/**
* 发起人角色
*/
public class GameRole {
private int vit;//生命力
private int atk;//攻击力
private int def;//防御力

private class RoleStateMemento implements Memento {
private int vit;//生命力
private int atk;//攻击力
private int def;//防御力

public RoleStateMemento(int vit, int atk, int def) {
this.vit = vit;
this.atk = atk;
this.def = def;
}

public int getVit() {
return vit;
}

public int getAtk() {
return atk;
}

public int getDef() {
return def;
}
}

//初始化对象
public void initState() {
this.vit = 100;
this.atk = 100;
this.def = 100;
}

//死亡
public void fight() {
this.vit = 0;
this.atk = 0;
this.def = 0;
}

//保存
public Memento savaState() {
return new RoleStateMemento(this.vit, this.atk, this.def);
}

//恢复
public void recoverState(Memento memento) {
RoleStateMemento roleStateMemento = (RoleStateMemento) memento;
this.vit = roleStateMemento.getVit();
this.atk = roleStateMemento.getAtk();
this.def = roleStateMemento.getDef();
}

//展示
public void stateDisplay() {
System.out.println("======角色面板======");
System.out.println("角色生命力"+this.vit);
System.out.println("角色攻击力"+this.atk);
System.out.println("角色防御力"+this.def);
System.out.println("===================");
}
}

/**
* 管理者角色
*/
public class RoleStateCaretaker {
private Memento memento;

public Memento getMemento() {
return memento;
}

public void setMemento(Memento memento) {
this.memento = memento;
}
}

public class Client {
public static void main(String[] args) {
System.out.println("初始化角色");
GameRole gameRole = new GameRole();
gameRole.initState();
gameRole.stateDisplay();

//存档
RoleStateCaretaker roleStateCaretaker = new RoleStateCaretaker();
Memento roleStateMemento = gameRole.savaState();
roleStateCaretaker.setMemento(roleStateMemento);

System.out.println("角色死亡");
gameRole.fight();
gameRole.stateDisplay();

System.out.println("回档");
gameRole.recoverState(roleStateCaretaker.getMemento());
gameRole.stateDisplay();
}
}

例二

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
118
119
/**
* 发起人角色
*/
public class GameRole {
private int vit;//生命力
private int atk;//攻击力
private int def;//防御力

//初始化对象
public void initState() {
this.vit = 100;
this.atk = 100;
this.def = 100;
}

//死亡
public void fight() {
this.vit = 0;
this.atk = 0;
this.def = 0;
}

//保存
public RoleStateMemento savaState() {
return new RoleStateMemento(this.vit, this.atk, this.def);
}

//恢复
public void recoverState(RoleStateMemento roleStateMemento) {
this.vit = roleStateMemento.getVit();
this.atk = roleStateMemento.getAtk();
this.def = roleStateMemento.getDef();
}

//展示
public void stateDisplay() {
System.out.println("======角色面板======");
System.out.println("角色生命力"+this.vit);
System.out.println("角色攻击力"+this.atk);
System.out.println("角色防御力"+this.def);
System.out.println("===================");
}
}

/**
* 备忘录角色
*/
public class RoleStateMemento {
private int vit;
private int atk;
private int def;

public RoleStateMemento(int vit, int atk, int def) {
this.vit = vit;
this.atk = atk;
this.def = def;
}

public int getVit() {
return vit;
}

public void setVit(int vit) {
this.vit = vit;
}

public int getAtk() {
return atk;
}

public void setAtk(int atk) {
this.atk = atk;
}

public int getDef() {
return def;
}

public void setDef(int def) {
this.def = def;
}
}

/**
* 管理者角色
*/
public class RoleStateCaretaker {
private RoleStateMemento roleStateMemento;

public RoleStateMemento getRoleStateMemento() {
return roleStateMemento;
}

public void setRoleStateMemento(RoleStateMemento roleStateMemento) {
this.roleStateMemento = roleStateMemento;
}
}

public class Client {
public static void main(String[] args) {
System.out.println("初始化角色");
GameRole gameRole = new GameRole();
gameRole.initState();
gameRole.stateDisplay();

//存档
RoleStateCaretaker roleStateCaretaker = new RoleStateCaretaker();
RoleStateMemento roleStateMemento = gameRole.savaState();
roleStateCaretaker.setRoleStateMemento(roleStateMemento);

System.out.println("角色死亡");
gameRole.fight();
gameRole.stateDisplay();

System.out.println("回档");
gameRole.recoverState(roleStateCaretaker.getRoleStateMemento());
gameRole.stateDisplay();
}
}

解释器模式

解释器模式Interpreter Pattern提供了评估语言的语法或表达式的方式它属于行为型模式这种模式实现了一个表达式接口该接口解释一个特定的上下文这种模式被用在 SQL 解析符号处理引擎等

给定一个语言定义它的文法表示并定义一个解释器这个解释器使用该标识来解释语言中的句子

结构

  • 抽象表达式角色定义解释器接口约定解释器的解释操作
  • 终结符表达式角色抽象表达式的子类用来实现文法中与终结符相关的操作文法中的每一个终结符都有一个具体终结表达式与之相对应
  • 非终结符表达式角色抽象表达式的子类用来实现文法中与非终结符相关的操作文法中的每条规则都对应一个非终结符表达式
  • 环境角色通常包含各个解释器需要的数据或是公共的功能一般用来传递被所有解释器共享的数据后面的解释器可以从这里获取这些值
  • 客户端主要任务是将需要分析的句子或者表达式转换成使用解释器对象描述的抽象语法树然后调用解释器的解释方法也可以通过环境角色间接访问解释器的解释方法
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
118
119
120
121
122
123
124
125
126
127
128
129
/**
* 抽象表达式角色
*/
public abstract class AbstractExpression {
//解释器的解释方法
public abstract int interpret(Context context);
}

/**
* 封装变量类终结符表达式角色
*/
public class Variable extends AbstractExpression {
//声明储存变量名的成员变量
private String name;

public Variable(String name) {
this.name = name;
}

@Override
public int interpret(Context context) {
//返回变量的值
return context.getValue(this);
}

@Override
public String toString() {
return name;
}
}

/**
* 减法表达式类非终结符表达式角色
*/
public class Minus extends AbstractExpression{
//-号左边的表达式
private AbstractExpression left;

//-号右边的表达式
private AbstractExpression right;

public Minus(AbstractExpression left, AbstractExpression right) {
this.left = left;
this.right = right;
}

@Override
public int interpret(Context context) {
return this.left.interpret(context) - this.right.interpret(context);
}

@Override
public String toString() {
return "(" + this.left.toString() + " - " + this.right.toString() + ")";
}
}

/**
* 加法表达式类非终结符表达式角色
*/
public class Plus extends AbstractExpression{
//+号左边的表达式
private AbstractExpression left;

//+号右边的表达式
private AbstractExpression right;

public Plus(AbstractExpression left, AbstractExpression right) {
this.left = left;
this.right = right;
}

@Override
public int interpret(Context context) {
return this.left.interpret(context) + this.right.interpret(context);
}

@Override
public String toString() {
return "(" + this.left.toString() + " + " + this.right.toString() + ")";
}
}

/**
* 环境角色
*/
public class Context {
//定义一个map集合用来储存变量及对应的值
private Map<Variable, Integer> map;

public Context() {
map = new HashMap<>();
}

//添加变量的功能
public void assign(Variable variable, Integer value) {
map.put(variable, value);
}

//根据变量获取对应的值
public Integer getValue(Variable variable) {
return map.get(variable);
}
}

public class Client {
public static void main(String[] args) {
//创建环境对象
Context context = new Context();

//创建变量对象
Variable a = new Variable("a");
Variable b = new Variable("b");
Variable c = new Variable("c");
Variable d = new Variable("d");

//将变量存储到环境对象中
context.assign(a, 1);
context.assign(b, 2);
context.assign(c, 3);
context.assign(d, 4);

//获取抽象语法树 a + b - c + d
AbstractExpression abstractExpression = new Plus(a, new Plus(new Minus(b, c), d));
//解释执行
int result = abstractExpression.interpret(context);
System.out.println(abstractExpression + " = " + result);
}
}

学习资源