23种设计模式示例

23种设计模式


设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。

总体来说设计模式分为三大类:

创建型模式,共五种:单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式
结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式
行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代器模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式

创建型模式


对象实例化的模式,创建型模式用于解耦对象的实例化过程.


单例模式


一个类仅有一个实例,提供一个全局访问点。


饿汉式

类加载时就创建实例:

1
2
3
4
5
6
7
8
9
10
public class HungrySingle {
private static HungrySingle INSTANCE = new HungrySingle();

private HungrySingle() {
}

public static HungrySingle getInstance() {
return INSTANCE;
}
}

懒汉式

访问时创建类的实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class LazySingle {
private static LazySingle INSTANCE = null;

private LazySingle() {
}

public static LazySingle getInstance() {
if (INSTANCE == null) {
INSTANCE = new LazySingle();
}
return INSTANCE;
}
}

注:在多线程环境下可能实例不止一个,可能出现线程安全问题


双重校验锁

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class DoubleCheckSingle {
private static volatile DoubleCheckSingle INSTANCE = null;

private DoubleCheckSingle() {

}

public static DoubleCheckSingle getInstance() {
if (INSTANCE == null) {
synchronized (DoubleCheckSingle.class) {
if (INSTANCE == null) {
INSTANCE = new DoubleCheckSingle();
}
}
}
return INSTANCE;
}
}

枚举单例

1
2
3
public enum EnumSingle {
INSTANCE
}

工厂方法模式


定义产品接口

1
2
3
interface Product {
String getProductName();
}

定义产品A

1
2
3
4
5
6
public class ProductA implements Product {
@Override
public String getProductName() {
return ProductA.class.getSimpleName();
}
}

定义产品B

1
2
3
4
5
6
public class ProductB implements Product {
@Override
public String getProductName() {
return ProductB.class.getSimpleName();
}
}

定义工厂接口

1
2
3
interface Factory {
Product getProduct();
}

A工厂生产产品A

1
2
3
4
5
6
public class FactoryA implements Factory {
@Override
public Product getProduct() {
return new ProductA();
}
}

B工厂生产产品B

1
2
3
4
5
6
public class FactoryB implements Factory {
@Override
public Product getProduct() {
return new ProductB();
}
}

抽象工厂模式


围绕一个超级工厂创建其他工厂。

抽象工厂

定义形状类型

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
public interface Shape {
int SHAPE_RECTANGLE = 1;
int SHAPE_SQUARE = 2;
int SHAPE_CIRCLE = 3;

/**
* 形状
*/
int getShapeType();

/**
* 面积
*/
float getArea();

/**
* 周长
*/
float getPerimeter();
}

// 矩形
public class RectangleShape implements Shape {
private float width;
private float height;

public RectangleShape(float width, float height) {
this.width = width;
this.height = height;
}

@Override
public int getShapeType() {
return SHAPE_RECTANGLE;
}

@Override
public float getArea() {
return width * height;
}

@Override
public float getPerimeter() {
return (width + height) * 2;
}
}

// 正方形
public class SquareShape implements Shape {
private float length;

public SquareShape(float length) {
this.length = length;
}

@Override
public int getShapeType() {
return SHAPE_SQUARE;
}

@Override
public float getArea() {
return length * length;
}

@Override
public float getPerimeter() {
return length * 4;
}
}

// 圆形
public class CircleShape implements Shape {
private float radius;

public CircleShape(float radius) {
this.radius = radius;
}

@Override
public int getShapeType() {
return SHAPE_SQUARE;
}

@Override
public float getArea() {
return (float) Math.PI * radius * radius;
}

@Override
public float getPerimeter() {
return (float) Math.PI * 2 * radius;
}
}

定义颜色类型

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 Color {
String COLOR_RED = "red";
String COLOR_BLACK = "black";
String COLOR_WHITE = "white";

String getColorType();

int getColor();
}

// 红色
public class Red implements Color {
@Override
public String getColorType() {
return COLOR_RED;
}

@Override
public int getColor() {
return 0xff0000;
}
}

// 黑色
public class Black implements Color {
@Override
public String getColorType() {
return COLOR_BLACK;
}

@Override
public int getColor() {
return 0x000000;
}
}

// 白色
public class White implements Color {
@Override
public String getColorType() {
return COLOR_WHITE;
}

@Override
public int getColor() {
return 0xffffff;
}
}

抽象出工厂接口

1
2
3
4
5
6
public interface AbstractFactory {
// 获取形状
Shape getShape(int shapeType, float... args);
// 获取颜色
Color getColor(String colorType);
}

形状工厂实现

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
public class ShapeFactory implements AbstractFactory {

@Override
public Shape getShape(int shapeType, float... args) {
if (shapeType == Shape.SHAPE_RECTANGLE) {
float width = 0, height = 0;
if (args != null && args.length == 2) {
width = args[0];
height = args[1];
}
return new RectangleShape(width, height);
} else if (shapeType == Shape.SHAPE_SQUARE) {
float length = 0;
if (args != null && args.length == 1) {
length = args[0];
}
return new SquareShape(length);
} else if (shapeType == Shape.SHAPE_CIRCLE) {
float radius = 0;
if (args != null && args.length == 1) {
radius = args[0];
}
return new CircleShape(radius);
}
return null;
}

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

颜色工厂实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class ColorFactory implements AbstractFactory {
@Override
public Shape getShape(int shapeType, float... args) {
return null;
}

@Override
public Color getColor(String colorType) {
if (Color.COLOR_RED.equals(colorType)) {
return new Red();
} else if (Color.COLOR_BLACK.equals(colorType)) {
return new Black();
} else if (Color.COLOR_WHITE.equals(colorType)) {
return new White();
}
return null;
}
}

通过工厂生成器来创建其他工厂

1
2
3
4
5
6
7
8
9
10
11
12
13
public class FactoryProducer {
public static final String FACTORY_SHAPE = "shape_factory";
public static final String FACTORY_COLOR = "color_factory";

public static AbstractFactory getFactory(String factoryType) {
if (FACTORY_SHAPE.equals(factoryType)) {
return new ShapeFactory();
} else if (FACTORY_COLOR.equals(factoryType)) {
return new ColorFactory();
}
return null;
}
}

建造者模式


在不知道对象的建造过程和细节的情况下就可以直接创建复杂的对象,将部件和其组装过程分开,一步一步创建一个复杂的对象。

用于构造复杂对象,或者多个参数传递且有默认值的情况。

例如 Retrofit 和 OKHTTP 实例的创建

1
2
3
4
5
6
7
8
9
10
11
 val client = OkHttpClient.Builder().connectTimeout(DEFAULT_TIME_OUT, TimeUnit.SECONDS)
.writeTimeout(DEFAULT_TIME_OUT, TimeUnit.SECONDS)
.readTimeout(DEFAULT_READ_TIME_OUT, TimeUnit.SECONDS)
.retryOnConnectionFailure(true)
.addInterceptor(logging)
.build()

mRetrofit = Retrofit.Builder().client(client)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.baseUrl(baseUrl)
.build()

OkHttpClient.java源码

Retrofit.java源码


原型模式


用于创建重复的对象,同时又能保证性能。

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Shape implements Cloneable {

@Override
protected Shape clone() {
Shape clone = null;
try {
clone = (Shape) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return clone;
}
}

结构型模式


把类或对象结合在一起形成一个更大的结构.


适配器模式


将一个接口转换成客户希望的另一个接口,使接口不兼容的那些类可以一起工作.

适配器模式类图

假设引入的第三方模块的实现如下:

1
2
3
4
5
6
7
8
public class ThirdProduct {

public Object dealSomething(Object... args) {
// 三方模块处理
// ......
return new Object();
}
}

我们业务所需要的接口为:

1
2
3
public interface IAdapter {
Object dealMine(String... args);
}

我们可构建如下是配置器:

1
2
3
4
5
6
7
8
9
10
11
12
public class MyProductAdapter implements IAdapter {
private ThirdProduct thirdProduct = new ThirdProduct();

@Override
public Object dealMine(String... args) {
// 前置处理
Object result = thirdProduct.dealSomething(args);
// 后置处理
return result;
}

}

装饰器模式


向一个现有的对象添加新的功能,同时又不改变其结构。

例:给图形添加红色边框

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
public interface Shape {
void draw();
}

public class CircleShape implements Shape {
@Override
public void draw() {
System.out.println("circle draw");
}
}

public abstract class ShapeDecorator {
protected Shape shape;

public ShapeDecorator(Shape shape) {
this.shape = shape;
}

public void draw() {
shape.draw();
}
}

public class RedShapeDecorator extends ShapeDecorator {
private Color color;

public RedShapeDecorator(Shape shape) {
super(shape);
}

@Override
public void draw() {
setBorderColor(Color.RED);
super.draw();
}

private void setBorderColor(Color red) {
color = red;
}
}

代理模式


一个类代理另一个类的功能。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public interface IProxy {
void deal(Object... args);
}

public class RealObj implements IProxy {
@Override
public void deal(Object... args) {
System.out.println("我是处理类");
}
}

public class ProxyObj implements IProxy {
private RealObj realObj;

@Override
public void deal(Object... args) {
if (realObj == null) {
realObj = new RealObj();
}
System.out.println("我是代理类,现在要调用具体类处理数据");
realObj.deal(args);
}
}

外观模式


提供了一个访问系统的接口,隐藏系统的复杂性。

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 interface IShape {
void draw();
}

public class Circle implements IShape {
@Override
public void draw() {
System.out.println("draw circle shape.");
}
}

public class Square implements IShape {
@Override
public void draw() {
System.out.println("draw square shape.");
}
}

public class ShapeMaker {
private IShape circle = new Circle();
private IShape square = new Square();

public void drawCircle() {
circle.draw();
}

public void drawSquare() {
square.draw();
}
}

注:通过 ShapeMaker 提供一个访问图形绘制的入口,对外部隐藏图形的构造过程。


桥接模式


把抽象与实现解耦,使得二者可以独立变化。

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
public interface DrawAPI {
void drawCircle(float x, float y, float radius);
}

public class DrawBlueCircle implements DrawAPI {
@Override
public void drawCircle(float x, float y, float radius) {
System.out.println("draw blue circle");
}
}

public class DrawRedCircle implements DrawAPI {
@Override
public void drawCircle(float x, float y, float radius) {
System.out.println("draw red circle");
}
}

public abstract class Shape {
protected DrawAPI mDrawAPI;

public Shape(DrawAPI mDrawAPI) {
this.mDrawAPI = mDrawAPI;
}

public abstract void draw();
}

public class Circle extends Shape {
private float x;
private float y;
private float radius;

public Circle(float x, float y, float radius, DrawAPI mDrawAPI) {
super(mDrawAPI);
this.x = x;
this.y = y;
this.radius = radius;
}

@Override
public void draw() {
mDrawAPI.drawCircle(x, y, radius);
}
}

注:将圆的绘制方法抽象与具体绘制逻辑分离


组合模式


部分整体模式,是用于把一组相似的对象当作一个单一的对象。

创建 Employee 类,该类带有 Employee 对象的列表:

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
public class Employee {
private String name;
private String dept;
private int salary;
private List<Employee> subordinates;

//构造函数
public Employee(String name, String dept, int sal) {
this.name = name;
this.dept = dept;
this.salary = sal;
subordinates = new ArrayList<>();
}

public void add(Employee e) {
subordinates.add(e);
}

public void remove(Employee e) {
subordinates.remove(e);
}

public List<Employee> getSubordinates() {
return subordinates;
}

public String toString() {
return ("Employee :[ Name : " + name
+ ", dept : " + dept + ", salary :"
+ salary + " ]");
}
}

使用 Employee 类来创建和打印员工的层次结构。

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 CompositePatternDemo {
public static void main(String[] args) {
Employee CEO = new Employee("John", "CEO", 30000);

Employee headSales = new Employee("Robert", "Head Sales", 20000);

Employee headMarketing = new Employee("Michel", "Head Marketing", 20000);

Employee clerk1 = new Employee("Laura", "Marketing", 10000);
Employee clerk2 = new Employee("Bob", "Marketing", 10000);

Employee salesExecutive1 = new Employee("Richard", "Sales", 10000);
Employee salesExecutive2 = new Employee("Rob", "Sales", 10000);

CEO.add(headSales);
CEO.add(headMarketing);

headSales.add(salesExecutive1);
headSales.add(salesExecutive2);

headMarketing.add(clerk1);
headMarketing.add(clerk2);

//打印该组织的所有员工
List<Employee> employees = new LinkedList<>();
employees.add(CEO);
while (!employees.isEmpty()) {
Employee employee = employees.remove(0);
System.out.println(employee);
employees.addAll(employee.getSubordinates());
}
}
}

注:代码参考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
public class KlDeviceUdIDUtils {
/**
* 缓存更新区间实例,防止频繁创建
*/
private static Map<String, SoftReference<UdIDRange>> cachedRange = new ConcurrentHashMap<>();

/**
* 判断是否在灰度区间内
*/
public static boolean isInRange(int versionCode, int radio, String udid) {
if (radio >= 100) {
return true;
} else if (radio <= 0) {
return false;
}
if (TextUtils.isEmpty(udid) || udid.length() < 2) {
return false;
}
UdIDRange udIDRange = getRange(versionCode, radio / 100f);
return udIDRange.isInRange(udid);
}

private static UdIDRange getRange(int version, float ratio) {
UdIDRange udIDRange = null;
String key = version + "_" + ratio;
try {
udIDRange = cachedRange.get(key).get();
} catch (Exception ignored) {
}
if (udIDRange == null) {

......

udIDRange = new UdIDRange(offset, start, end, isReverseRange, ratio);
cachedRange.put(key, new SoftReference<>(udIDRange));
}
return udIDRange;
}

private static class UdIDRange {

......

}

}

注:此代码片段为实际项目中的使用方式,增加缓存以减少实例创建次数,提高运行效率


行为型模式

类和对象如何交互,划分责任和算法.


策略模式

一个类的行为或其算法可以在运行时更改。

可以在运行时设置不同的 strategy

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
public interface Strategy {
float operator(float a, float b);
}

public class AddStrategy implements Strategy {
@Override
public float operator(float a, float b) {
return a + b;
}
}

public class MultiplyStrategy implements Strategy {
@Override
public float operator(float a, float b) {
return a * b;
}
}

public class SubstractStrategy implements Strategy {
@Override
public float operator(float a, float b) {
return a - b;
}
}

public class Context implements Strategy {
private Strategy strategy;

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

@Override
public float operator(float a, float b) {
if (strategy == null) {
throw new RuntimeException("no strategy set");
}
return strategy.operator(a, b);
}
}

模版方法模式


一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public abstract class Template {
public Template() {
onCreate();
}

public void onCreate() {
initView();
initData();
initListener();
}

protected abstract void initView();

protected abstract void initData();

protected abstract void initListener();
}

观察者模式

当一个对象被修改时,则会自动通知它的依赖对象。

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
public interface IObserver {
void update();
}

public class Subject {
private int state;

public int getState() {
return state;
}

public void setState(int state) {
this.state = state;
System.out.println("subject change");
notifyObservers();
}

private List<IObserver> observers = new ArrayList<>();

public void addObserver(IObserver observer) {
System.out.println("add observer: " + observer.getClass().getSimpleName());
observers.add(observer);
}

public boolean removeObserver(IObserver observer) {
return observers.remove(observer);
}

private void notifyObservers() {
if (!observers.isEmpty()) {
for (IObserver observer : observers) {
observer.update();
}
} else {
System.out.println("no observer");
}
}
}

public class AObserver implements IObserver {
@Override
public void update() {
System.out.println("A observer update");
}
}

public class BObserver implements IObserver {
@Override
public void update() {
System.out.println("B observer update");
}
}

public class Test {
public static void main(String[] args) {
Subject subject = new Subject();
subject.setState(0);
subject.addObserver(new AObserver());
subject.addObserver(new BObserver());
subject.setState(1);
}
}

输出结果:

1
2
3
4
5
6
7
subject change
no observer
add observer: AObserver
add observer: BObserver
subject change
A observer update
B observer update

迭代器模式


用于顺序访问集合对象的元素,不需要知道集合对象的底层表示。

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
public interface Iterator<T> {
T next();

boolean hasNext();
}

public class IntegerIterator implements Iterator<Integer> {
private int[] array;
private int index;

IntegerIterator(int[] array) {
this.array = array;
}

@Override
public Integer next() {
return array[index++];
}

@Override
public boolean hasNext() {
return index < array.length;
}
}

public class Array {
private int[] array = new int[10];

public Iterator getIterator() {
return new IntegerIterator(array);
}
}

责任链模式


避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求。

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
public abstract class Filter {
private Filter nextFilter;

public Filter setNextFilter(Filter nextFilter) {
this.nextFilter = nextFilter;
return nextFilter;
}

public String filter(String content) {
content = doOperator(content);
if (nextFilter != null) {
return nextFilter.filter(content);
}
return content;
}

protected abstract String doOperator(String content);
}

public class RemoveBlankFilter extends Filter {
@Override
protected String doOperator(String content) {
System.out.println("Before RemoveBlankFilter: " + content);
content = content.replace(" ", "");
System.out.println("After RemoveBlankFilter: " + content);
return content;
}
}

public class RemoveBottomLineFilter extends Filter {
@Override
protected String doOperator(String content) {
System.out.println("Before RemoveBottomLineFilter: " + content);
content = content.replace("_", "");
System.out.println("After RemoveBottomLineFilter: " + content);
return content;
}
}

public class ToUppFilter extends Filter {
@Override
protected String doOperator(String content) {
System.out.println("Before ToUppFilter: " + content);
content = content.toUpperCase();
System.out.println("After ToUppFilter: " + content);
return content;
}
}

public class Test {
public static void main(String[] args) {
Filter filter = new RemoveBlankFilter();
filter.setNextFilter(new RemoveBottomLineFilter()).setNextFilter(new ToUppFilter());
System.out.println("Filter result: " + filter.filter("abc de_fGHIJK"));
}
}

输出结果:

1
2
3
4
5
6
7
Before RemoveBlankFilter: abc de_fGHIJK
After RemoveBlankFilter: abcde_fGHIJK
Before RemoveBottomLineFilter: abcde_fGHIJK
After RemoveBottomLineFilter: abcdefGHIJK
Before ToUppFilter: abcdefGHIJK
After ToUppFilter: ABCDEFGHIJK
Filter result: ABCDEFGHIJK

命令模式


将一个请求封装成一个对象,从而使您可以用不同的请求对客户进行参数化。

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 class Request {
public int sum(int... array) {
int result = 0;
if (array != null) {
for (int i : array) {
result += i;
}
}
return result;
}

public int mul(int... array) {
int result = 1;
if (array != null) {
for (int i : array) {
result *= i;
}
}
return result;
}
}

// 命令接口
public interface Order {
int ORDER_SUM = 0;
int ORDER_MUL = 1;

int getOrderType();

int execute(int... array);
}

// 累加命令
public class SumOrder implements Order {
private Request request;

public SumOrder(Request request) {
this.request = request;
}

@Override
public int getOrderType() {
return Order.ORDER_SUM;
}

@Override
public int execute(int... array) {
return request.sum(array);
}
}

// 累乘命令
public class MulOrder implements Order {
private Request request;

public MulOrder(Request request) {
this.request = request;
}

@Override
public int getOrderType() {
return Order.ORDER_MUL;
}

@Override
public int execute(int... array) {
return request.mul(array);
}
}

// 命令使用者
public class User {
Map<Integer, Order> orderMap = new HashMap<>();

public void takeOrder(Order order) {
orderMap.put(order.getOrderType(), order);
}

public int executeOrder(int orderType, int... array) {
Order order = orderMap.get(orderType);
if (order != null) {
return order.execute(array);
} else {
throw new RuntimeException("you has not " + orderType + " order");
}
}
}

// 测试命令使用者使用命令
public class Test {
public static void main(String[] args) {
Request request = new Request();

User user = new User();
user.takeOrder(new MulOrder(request));
user.takeOrder(new SumOrder(request));

System.out.println("execute sum order: " + user.executeOrder(Order.ORDER_SUM, 1, 2, 3, 4, 5));
System.out.println("execute mul order: " + user.executeOrder(Order.ORDER_MUL, 1, 2, 3, 4, 5));
}
}

输出结果:

1
2
execute sum order: 15
execute mul order: 120

备忘录模式


保存一个对象的某个状态,以便在适当的时候恢复对象。

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
// 备忘录内容
public class Memento {
String state;

public Memento(String state) {
this.state = state;
}

public String getState() {
return state;
}
}

// 备忘录管理
public class MementoRecord {
List<Memento> mementos = new ArrayList<>();

public void addMemento(Memento memento) {
mementos.add(memento);
}

public Memento getMemento(int index) {
if (index >= 0 && index < mementos.size()) {
return mementos.get(index);
}
return null;
}

public void printMementoRecord() {
System.out.println("Print MementoRecord");
for (Memento memento : mementos) {
System.out.println(memento.getState());
}
}
}

// 需要备忘状态的对象
public class SomeObject {
private String state;

public String getState() {
return state;
}

public void setState(String state) {
this.state = state;
}

public Memento getMemento() {
return new Memento(state);
}
}


// 测试备忘功能
public class Test {
public static void main(String[] args) {
MementoRecord mementoRecord = new MementoRecord();

SomeObject someObject = new SomeObject();
someObject.setState("state 1");
mementoRecord.addMemento(someObject.getMemento());
someObject.setState("state 2");
mementoRecord.addMemento(someObject.getMemento());
someObject.setState("state 3");
mementoRecord.addMemento(someObject.getMemento());
someObject.setState("state 4");
mementoRecord.addMemento(someObject.getMemento());
someObject.setState("state 5");

System.out.println("current: " + someObject.getState());
mementoRecord.printMementoRecord();
}
}

输出结果:

1
2
3
4
5
6
current: state 5
Print MementoRecord
state 1
state 2
state 3
state 4

状态模式


允许对象在内部状态发生改变时改变它的行为。

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
// 定义状态接口
public interface State {
void start(Context context);

void stop(Context context);
}

// 定义使用状态的主体
public class Context {
private State state;

public Context() {
this.state = null;
}

public State getState() {
return state;
}

public void setState(State state) {
this.state = state;
}

public void start() {
getState().start(this);
}

public void stop() {
getState().stop(this);
}
}

// 开始状态可以切换至结束状态
public class StartState implements State {
@Override
public void start(Context context) {
System.out.println("current state is start");
}

@Override
public void stop(Context context) {
context.setState(new StopState());
System.out.println("change to stop state");
}
}

// 结束状态可以切换至开始状态
public class StopState implements State {
@Override
public void start(Context context) {
context.setState(new StartState());
System.out.println("change to start state");
}

@Override
public void stop(Context context) {
System.out.println("current state is stop");
}
}

// 测试状态切换
public class Test {
public static void main(String[] args) {
Context context = new Context();
context.setState(new StopState());
context.start();
context.stop();
context.stop();
context.start();
}
}

输出结果:

1
2
3
4
current state is start
change to stop state
current state is stop
change to start state

访问者模式


元素的执行算法可以随着访问者改变而改变,将数据结构与数据操作分离。

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
// 定义访问者管理类,设置对应身份访问的处理类型
public class Computer {
public static final int SUM_VISITOR = 0;
public static final int SUB_VISITOR = 1;
public static final int MUL_VISITOR = 2;

Map<Integer, Calculator> calculatorMap = new HashMap<>();

public Computer() {
calculatorMap.put(SUM_VISITOR, new Sum());
calculatorMap.put(SUB_VISITOR, new Sub());
calculatorMap.put(MUL_VISITOR, new Mul());
}

public int visit(int visitorType, int a, int b) {
Calculator calculator = calculatorMap.get(visitorType);
if (calculator != null) {
return calculator.calculator(a, b);
} else {
throw new RuntimeException("unknown visitor type: " + visitorType);
}
}
}

// 计算接口
public interface Calculator {
int calculator(int a, int b);
}

// 相加
public class Sum implements Calculator {
@Override
public int calculator(int a, int b) {
return a + b;
}
}

// 相减
public class Sub implements Calculator {
@Override
public int calculator(int a, int b) {
return a - b;
}
}

// 相乘
public class Mul implements Calculator {
@Override
public int calculator(int a, int b) {
return a * b;
}
}

// 测试
public class Test {
public static void main(String[] args) {
Computer computer = new Computer();
System.out.println("sum visitor: 2 + 3 = " + computer.visit(Computer.SUM_VISITOR, 2, 3));
System.out.println("sub visitor: 2 - 3 = " + computer.visit(Computer.SUB_VISITOR, 2, 3));
System.out.println("mul visitor: 2 * 3 = " + computer.visit(Computer.MUL_VISITOR, 2, 3));
System.out.println("unknown visitor: 2 / 3 = " + computer.visit(-1, 2, 3));
}
}

输出结果:

1
2
3
4
5
6
sum visitor: 2 + 3 = 5
sub visitor: 2 - 3 = -1
mul visitor: 2 * 3 = 6
Exception in thread "main" java.lang.RuntimeException: unknown visitor type: -1
at pattern.behavior.visit.Computer.visit(Computer.java:24)
at pattern.behavior.visit.Test.main(Test.java:9)

中介者模式


用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

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
public class User {
public String id;
public String name;

public User(String id, String name) {
this.id = id;
this.name = name;
}

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

public class Message {
public String message;

public Message(String message) {
this.message = message;
}

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

public class Mediator {
public static void sendMessage(User fromUser, User toUser, Message message) {
System.out.println(fromUser + " -> " + toUser + ": " + message);
}
}

public class Test {
public static void main(String[] args) {
User xiaoming = new User("1", "小明");
User xiaogang = new User("2", "小刚");

Mediator.sendMessage(xiaoming, xiaogang, new Message("你在家么?"));
Mediator.sendMessage(xiaogang, xiaoming, new Message("我在家,你要来玩不?"));
}
}

输出结果:

1
2
小明 -> 小刚: 你在家么?
小刚 -> 小明: 我在家,你要来玩不?

解释器模式


实现了一个表达式接口,该接口解释一个特定的上下文。这种模式被用在 SQL 解析、符号处理引擎等。

找出一段区间内同时被 5,7,11 整除的数,通过提供一个 Solution 提供此类数字的表示方法。

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
// 定义整除接口
public interface IDivisible {
boolean divisible(int number);
}

public class FiveDivisible implements IDivisible {
@Override
public boolean divisible(int number) {
if (number % 5 == 0) {
return true;
}
return false;
}
}

public class SevenDivisible implements IDivisible {
@Override
public boolean divisible(int number) {
if (number % 7 == 0) {
return true;
}
return false;
}
}

public class ElevenDivisible implements IDivisible {
@Override
public boolean divisible(int number) {
if (number % 11 == 0) {
return true;
}
return false;
}
}

// 找出一段区间内同时能被 5,7,11 整除的数
public class Solution {
private IDivisible fiveDivisible = new FiveDivisible();
private IDivisible sevenDivisible = new SevenDivisible();
private IDivisible elevenDivisible = new ElevenDivisible();

public List<Integer> solution(int start, int end) {
List<Integer> result = new ArrayList<>();
for (int i = start; i <= end; i++) {
if (divisible(i)) {
result.add(i);
}
}
return result;
}

private boolean divisible(int number) {
return fiveDivisible.divisible(number)
&& sevenDivisible.divisible(number)
&& elevenDivisible.divisible(number);
}
}

public class Test {
public static void main(String[] args) {
System.out.println(new Solution().solution(1, 10000));
}
}

输出结果:

1
[385, 770, 1155, 1540, 1925, 2310, 2695, 3080, 3465, 3850, 4235, 4620, 5005, 5390, 5775, 6160, 6545, 6930, 7315, 7700, 8085, 8470, 8855, 9240, 9625]

总结


动手编写各种模式实例代码,发现工作中其实用到了其中的很多模式,自己却不知,通过这次梳理,加深了对设计模式的理解。





文章目录
  1. 1. 23种设计模式
  2. 2. 创建型模式
    1. 2.1. 单例模式
      1. 2.1.1. 饿汉式
      2. 2.1.2. 懒汉式
      3. 2.1.3. 双重校验锁
      4. 2.1.4. 枚举单例
    2. 2.2. 工厂方法模式
    3. 2.3. 抽象工厂模式
    4. 2.4. 建造者模式
    5. 2.5. 原型模式
  3. 3. 结构型模式
    1. 3.1. 适配器模式
    2. 3.2. 装饰器模式
    3. 3.3. 代理模式
    4. 3.4. 外观模式
    5. 3.5. 桥接模式
    6. 3.6. 组合模式
    7. 3.7. 享元模式
  4. 4. 行为型模式
    1. 4.1. 策略模式
    2. 4.2. 模版方法模式
    3. 4.3. 观察者模式
    4. 4.4. 迭代器模式
    5. 4.5. 责任链模式
    6. 4.6. 命令模式
    7. 4.7. 备忘录模式
    8. 4.8. 状态模式
    9. 4.9. 访问者模式
    10. 4.10. 中介者模式
    11. 4.11. 解释器模式
  5. 5. 总结