177 lines
4.6 KiB
Java
177 lines
4.6 KiB
Java
## 备忘录(Memento)
|
||
|
||
### Intent
|
||
|
||
在不违反封装的情况下获得对象的内部状态,从而在需要时可以将对象恢复到最初状态。
|
||
|
||
### Class Diagram
|
||
|
||
- Originator:原始对象
|
||
- Caretaker:负责保存好备忘录
|
||
- Memento:备忘录,存储原始对象的的状态。备忘录实际上有两个接口,一个是提供给 Caretaker 的窄接口:它只能将备忘录传递给其它对象;一个是提供给 Originator 的宽接口,允许它访问到先前状态所需的所有数据。理想情况是只允许 Originator 访问本备忘录的内部状态。
|
||
|
||
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/50678f34-694f-45a4-91c6-34d985c83fee.png"/> </div><br>
|
||
|
||
### Implementation
|
||
|
||
以下实现了一个简单计算器程序,可以输入两个值,然后计算这两个值的和。备忘录模式允许将这两个值存储起来,然后在某个时刻用存储的状态进行恢复。
|
||
|
||
实现参考:[Memento Pattern - Calculator Example - Java Sourcecode](https://www.oodesign.com/memento-pattern-calculator-example-java-sourcecode.html)
|
||
|
||
```java
|
||
/**
|
||
* Originator Interface
|
||
*/
|
||
public interface Calculator {
|
||
|
||
// Create Memento
|
||
PreviousCalculationToCareTaker backupLastCalculation();
|
||
|
||
// setMemento
|
||
void restorePreviousCalculation(PreviousCalculationToCareTaker memento);
|
||
|
||
int getCalculationResult();
|
||
|
||
void setFirstNumber(int firstNumber);
|
||
|
||
void setSecondNumber(int secondNumber);
|
||
}
|
||
```
|
||
|
||
```java
|
||
/**
|
||
* Originator Implementation
|
||
*/
|
||
public class CalculatorImp implements Calculator {
|
||
|
||
private int firstNumber;
|
||
private int secondNumber;
|
||
|
||
@Override
|
||
public PreviousCalculationToCareTaker backupLastCalculation() {
|
||
// create a memento object used for restoring two numbers
|
||
return new PreviousCalculationImp(firstNumber, secondNumber);
|
||
}
|
||
|
||
@Override
|
||
public void restorePreviousCalculation(PreviousCalculationToCareTaker memento) {
|
||
this.firstNumber = ((PreviousCalculationToOriginator) memento).getFirstNumber();
|
||
this.secondNumber = ((PreviousCalculationToOriginator) memento).getSecondNumber();
|
||
}
|
||
|
||
@Override
|
||
public int getCalculationResult() {
|
||
// result is adding two numbers
|
||
return firstNumber + secondNumber;
|
||
}
|
||
|
||
@Override
|
||
public void setFirstNumber(int firstNumber) {
|
||
this.firstNumber = firstNumber;
|
||
}
|
||
|
||
@Override
|
||
public void setSecondNumber(int secondNumber) {
|
||
this.secondNumber = secondNumber;
|
||
}
|
||
}
|
||
```
|
||
|
||
```java
|
||
/**
|
||
* Memento Interface to Originator
|
||
*
|
||
* This interface allows the originator to restore its state
|
||
*/
|
||
public interface PreviousCalculationToOriginator {
|
||
int getFirstNumber();
|
||
int getSecondNumber();
|
||
}
|
||
```
|
||
|
||
```java
|
||
/**
|
||
* Memento interface to CalculatorOperator (Caretaker)
|
||
*/
|
||
public interface PreviousCalculationToCareTaker {
|
||
// no operations permitted for the caretaker
|
||
}
|
||
```
|
||
|
||
```java
|
||
/**
|
||
* Memento Object Implementation
|
||
* <p>
|
||
* Note that this object implements both interfaces to Originator and CareTaker
|
||
*/
|
||
public class PreviousCalculationImp implements PreviousCalculationToCareTaker,
|
||
PreviousCalculationToOriginator {
|
||
|
||
private int firstNumber;
|
||
private int secondNumber;
|
||
|
||
public PreviousCalculationImp(int firstNumber, int secondNumber) {
|
||
this.firstNumber = firstNumber;
|
||
this.secondNumber = secondNumber;
|
||
}
|
||
|
||
@Override
|
||
public int getFirstNumber() {
|
||
return firstNumber;
|
||
}
|
||
|
||
@Override
|
||
public int getSecondNumber() {
|
||
return secondNumber;
|
||
}
|
||
}
|
||
```
|
||
|
||
```java
|
||
/**
|
||
* CareTaker object
|
||
*/
|
||
public class Client {
|
||
|
||
public static void main(String[] args) {
|
||
// program starts
|
||
Calculator calculator = new CalculatorImp();
|
||
|
||
// assume user enters two numbers
|
||
calculator.setFirstNumber(10);
|
||
calculator.setSecondNumber(100);
|
||
|
||
// find result
|
||
System.out.println(calculator.getCalculationResult());
|
||
|
||
// Store result of this calculation in case of error
|
||
PreviousCalculationToCareTaker memento = calculator.backupLastCalculation();
|
||
|
||
// user enters a number
|
||
calculator.setFirstNumber(17);
|
||
|
||
// user enters a wrong second number and calculates result
|
||
calculator.setSecondNumber(-290);
|
||
|
||
// calculate result
|
||
System.out.println(calculator.getCalculationResult());
|
||
|
||
// user hits CTRL + Z to undo last operation and see last result
|
||
calculator.restorePreviousCalculation(memento);
|
||
|
||
// result restored
|
||
System.out.println(calculator.getCalculationResult());
|
||
}
|
||
}
|
||
```
|
||
|
||
```html
|
||
110
|
||
-273
|
||
110
|
||
```
|
||
|
||
### JDK
|
||
|
||
- java.io.Serializable
|