备忘录模式与命令模式的结合

来源:互联网 发布:阿里云实名认证多久好 编辑:程序博客网 时间:2024/04/30 02:37
/**   *备忘录窄接口 */public interface Memento {}


public interface OperationApi {    /**     * 获取计算完成后的结果     */    public int getResult();         /**     * 执行加法     */    public void add(int num);        /**     * 执行减法     */    public void substract(int num);        /**     * 创建保存原发器对象状态的备忘录对象     */    public Memento createMemento();        /**     * 重新设置原发器对象的状态,让其回到备忘录记录的状态     */    public void setMemento(Memento memento);    }

/** *定义一个命令的接口 */public interface Command {     /**     * 执行命令     */    public void execute();     /**     * 撤销命令,恢复到备忘录记录的状态     */    public void undo(Memento m);     /**     * 重做命令,恢复到备忘录记录的状态     */    public void redo(Memento m);     /**     * 创建备忘录对象     */    public Memento createMemento();}

public class Operation implements OperationApi {    //记录运算的结果private int result;@Overridepublic int getResult() {return result;}@Overridepublic void add(int num) {         result += num;}@Overridepublic void substract(int num) {         result -=num;}@Overridepublic Memento createMemento() {MementoImpl m = new MementoImpl(result);return m;}@Overridepublic void setMemento(Memento memento) {        MementoImpl m = (MementoImpl) memento;        this.result = m.getResult();}private static class MementoImpl implements Memento{private int result = 0;public MementoImpl(int result){this.result = result;}public int getResult(){return this.result;}} }

public abstract class AbstractCommand implements Command {    /**     * 持有真正的命令实现者对象     */    protected OperationApi operation =null;public void setOperation(OperationApi operation){this.operation = operation;}//具体的功能实现,这里不管@Overridepublic void execute() {}    @Overridepublic void undo(Memento memento) {          this.operation.setMemento(memento);}@Overridepublic void redo(Memento memento) {          this.operation.setMemento(memento);}@Overridepublic Memento createMemento() {return this.operation.createMemento();}}

public class AddCommand extends AbstractCommand {       private int opeNum;              public AddCommand(int opeNum){       this.opeNum = opeNum;       }@Overridepublic void execute() { this.operation.add(opeNum);} }

public class SubstractCommand extends AbstractCommand {       private int opeNum;       public SubstractCommand(int opeNum){       this.opeNum = opeNum;       }       public void execute(){       this.operation.substract(opeNum);       }}

/** *计算器类,有加法按钮,减法按钮,还有撤销和恢复按钮 */public class Caculator {    /**     * 命令的操作历史记录,在撤销的时候用     */    private List<Command> undoCommands = new ArrayList<Command>();    /**     * 命令被撤销的历史记录,在恢复时候用     */    private List<Command> redoCommands = new ArrayList<Command>();    /**     * 命令操作对应的备忘录的历史记录,在撤销时用     * 数组有两个元素,一个是执行命令前的状态,一个是执行命令后的状态     */    private List<Memento[]> undoMementos = new ArrayList<Memento[]>();        /**     * 被撤销命令对应的历史记录,在恢复时使用,     * 数组有两个元素,第一个是执行命令前的状态,第二个是执行命令后的状态     */    private List<Memento[]> redoMementos = new ArrayList<Memento[]>();                    private Command addCommand;    private Command substractCommand;    public void setAddCmd(Command addCommand){    this.addCommand = addCommand;    }    public void setSubstractCommand(Command substractCommand){    this.substractCommand = substractCommand;    }            //加法操作    public void addPressed(){    Memento m1 = this.addCommand.createMemento(); //执行加法前的记录    this.addCommand.execute();//执行加法    undoCommands.add(addCommand);//把操作记录添加到历史记录中    Memento m2 = this.addCommand.createMemento();//执行加法后的记录    this.undoMementos.add(new Memento[]{m1,m2});//添加到历史记录中     }        //减法操作    public void substractPressed(){    Memento m1 = this.substractCommand.createMemento();    this.substractCommand.execute();    undoCommands.add(this.substractCommand);    Memento m2 = this.substractCommand.createMemento();    this.undoMementos.add(new Memento[]{m1,m2});    }                public void undoPressed(){    if(undoCommands.size()>0){    Command cmd = undoCommands.get(undoCommands.size()-1);    Memento[] ms = undoMementos.get(undoCommands.size()-1);    //撤销    cmd.undo(ms[0]);    //添加进去可恢复的记录    redoCommands.add(cmd);    redoMementos.add(ms);    //删除相应的记录    undoCommands.remove(cmd);    undoMementos.remove(ms);    }else{    System.out.println("没有可以撤销的操作");    }    }            public void redoPressed(){    if(redoCommands.size()>0){    Command cmd = redoCommands.get(redoCommands.size()-1);    Memento[] ms = redoMementos.get(redoCommands.size()-1);        cmd.redo(ms[1]);    undoCommands.add(cmd);    undoMementos.add(ms);        redoCommands.remove(cmd);    redoMementos.remove(ms);    }else{    System.out.println("没有可以恢复的命令");    }    } }
 

public class Client {public static void main(String[] args) {        OperationApi operation = new Operation();        AddCommand addCmd =new AddCommand(5);        SubstractCommand substractCmd = new SubstractCommand(2);        addCmd.setOperation(operation);        substractCmd.setOperation(operation);                        Caculator caculator = new Caculator();        caculator.setAddCmd(addCmd);        caculator.setSubstractCommand(substractCmd);                        caculator.addPressed();        System.out.println("一次加法运算后的结果"+operation.getResult());        caculator.substractPressed();        System.out.println("一次减法运算后的结果"+operation.getResult());        caculator.undoPressed();        System.out.println("一次撤销后的结果"+operation.getResult());        caculator.undoPressed();         System.out.println("再一次撤销后的结果"+operation.getResult());        caculator.redoPressed();        System.out.println("一次恢复后的结果"+operation.getResult());         caculator.redoPressed();        System.out.println("再一次恢复后的结果"+operation.getResult());                }}









0 0
原创粉丝点击