理解设计模式之备忘录模式、解释器模式

今天就来聊聊这最后两个设计模式:备忘录模式和解释器模式。

备忘录模式

在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。

不破坏封装性,不破坏封装性,不破坏封装性,这是备忘录模式的核心,这也体现了最少知识原则。备忘录模式思考的是,如何把内部状态做到对外信息隐藏?
计算机科学领域的所有问题都可以通过增加一个间接中间层来解决,加一层Memento封装这些需要存储的状态。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class Memento {
private String state;
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
public class Originator {
// state可以是任何形式,这里用String做最简化示例
private String state;
public Memento createMemento() {
Memento memento = new Memento();
memento.setState(state);
return memento;
}
public void setMemento(Memento memento) {
state = memento.getState();
}
}

对外提供一个对这些状态保存、恢复等管理操作的Caretaker(外部化类):

1
2
3
4
5
6
7
8
9
10
11
public class Caretaker {
private Memento memento;
public void saveMemento(Memento memento) {
this.memento = memento;
}
public Memento restoreMemento() {甚至
return memento;
}
}

这里还继续抽象Memento,实现IMemento接口,基于此,Memento甚至可以作为Memento的内部类实现,这里不做赘述。备忘录模式UML类图如下:
备忘录模式UML类图

解释器模式

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

加入给一个表达式:(x + 5) * 6 + y, 假定x,y值分别给定值为1,5或者3,4,请写一个计算系统计算结果。
可能这个系统用过程式思维很容易写,一两个方法就行了,但是考虑扩展性(后期增加除,幂等),采用面向对象思维该如何设计?
实现过程有点无聊不做展开,最终效果大概如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 解析表达式
Constant p1Constant = new Constant(5);
Constant p2Constant = new Constant(6);
Variable xVariable = new Variable();
Variable yVariable = new Variable();
// 初始化
xVariable.setValue(1);
yVariable.setValue(5);
// 计算
new Add(
new Multiply(
new Add(xVariable, p1Constant),
p2Constant),
yVariable);

解释器模式虽然简单,但在设计解析模板引擎方面还是应用的很广泛的,UML类图如下:
解释器模式UML类图

小结

通过学习备忘录模式和解释器模式,可以增强面向对象思维,写出更符面向对象式的代码。