Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 计算器撤销场景中需要什么Memento设计模式_Java_Design Patterns_Undo_Memento - Fatal编程技术网

Java 计算器撤销场景中需要什么Memento设计模式

Java 计算器撤销场景中需要什么Memento设计模式,java,design-patterns,undo,memento,Java,Design Patterns,Undo,Memento,我正在读关于纪念品设计模式的书。我遇到了一个关于计算器撤销功能的例子 我能够通过以下代码实现计算器撤销: 计算器 public class Calculator implements Cloneable { int num1; int num2; int result; Stack<Calculator> states = new Stack<>(); public void setNum1(int num1) { this.num1 = num1; }

我正在读关于纪念品设计模式的书。我遇到了一个关于计算器撤销功能的例子

我能够通过以下代码实现计算器撤销:

计算器

public class Calculator implements Cloneable {

int num1;
int num2;
int result;

Stack<Calculator> states = new Stack<>();

public void setNum1(int num1) {
    this.num1 = num1;
}

public void setNum2(int num2) {
    this.num2 = num2;
}

public void setResult(int result) {
    this.result = result;
}

public int add() throws CloneNotSupportedException{
    result = num1 + num2;
    states.add((Calculator) this.clone());
    System.out.println("Caclulation done. ");
    return result;
}

public void undo(){
    states.pop();
    Calculator calc = states.peek();
    this.setNum1(calc.num1);
    this.setNum2(calc.num2);
    this.setResult(calc.result);
    System.out.println("Undo done. ");
}

public void displayState(){
    System.out.println("Current State: " + num1 + " + " + num2 + " = " + result);
}
}
输出

它对撤销很有效。为什么我要在这个场景中使用Memento模式

来源

动机

有时需要捕获对象的内部状态 在某一点上,并且能够将对象恢复到该状态 后来。这种情况在发生错误或失败时很有用

考虑一个计算器对象的撤销操作,例如 计算器可以简单地维护所有先前操作的列表,这些操作 它已执行,因此将能够恢复以前的 它已经进行了计算。这将导致计算器对象 变得更大、更复杂、更重,如计算器 对象必须提供额外的撤消功能,并且 维护以前所有操作的列表

此功能可以移出calculator类,以便 外部(我们称之为undo manager类)可以收集 计算器的内部状态并保存它。然而,提供 对计算器的每个状态变量的显式访问 还原管理器将不切实际,并且会违反 封装原理

因此,计算器对象将变得更大,计算器将不遵守SRP。如果我使用Memento模式,这两个设计缺陷是否可以避免?
    Calculator calc = new Calculator();

    calc.setNum1(10);
    calc.setNum2(11);
    calc.add();
    calc.displayState();

    calc.setNum1(12);
    calc.setNum2(13);
    calc.add();
    calc.displayState();

    calc.setNum1(16);
    calc.setNum2(17);
    calc.add();
    calc.displayState();

    calc.undo();
    calc.displayState();

    calc.undo();
    calc.displayState();
Caclulation done. 
Current State: 10 + 11 = 21
Caclulation done. 
Current State: 12 + 13 = 25
Caclulation done. 
Current State: 16 + 17 = 33
Undo done. 
Current State: 12 + 13 = 25
Undo done. 
Current State: 10 + 11 = 21