Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/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 纪念图案_Java_Oop_Design Patterns_Memento - Fatal编程技术网

Java 纪念图案

Java 纪念图案,java,oop,design-patterns,memento,Java,Oop,Design Patterns,Memento,这里是Memento模式的一个典型实现(跳过了getter和setter) 公共类员工{ 私有字符串名称; 私人电话; 公共雇员记忆保存(){ 返回新员工纪念品(姓名、电话); } 公共无效恢复(员工纪念){ this.name=memento.getName(); this.phone=memento.getPhone(); } } 公共类员工纪念品{ 私有最终字符串名; 私人最终字符串电话; 公共雇员纪念品(字符串名称、字符串电话){ this.name=名称; this.phone=电话;

这里是Memento模式的一个典型实现(跳过了getter和setter)

公共类员工{
私有字符串名称;
私人电话;
公共雇员记忆保存(){
返回新员工纪念品(姓名、电话);
}
公共无效恢复(员工纪念){
this.name=memento.getName();
this.phone=memento.getPhone();
}
}
公共类员工纪念品{
私有最终字符串名;
私人最终字符串电话;
公共雇员纪念品(字符串名称、字符串电话){
this.name=名称;
this.phone=电话;
}
}
公务舱管理员{
私有堆栈历史;
公共看守人(){
历史=新堆栈();
}
公共作废保存(员工){
history.push(employee.save());
}
公共作废恢复(员工){
employee.revert(history.pop());
}
}
我发现这个模式的所有实现或多或少都与上面的相同。但这种实现方式存在一些问题,我不喜欢:

  • 可以触发
    employee.revert()
    管理员.revert(employee)
    。我只想要一个接入点
  • 如果我们想更改EmployeeMemento,我们还必须在Employee类中进行更改(因为
    revert
    method)
  • 有没有办法克服这个问题? 或者是我太注意了,而这些细节并没有那么重要?

    1)请注意,管理员应该负责保管纪念品,而不一定负责撤消/重做。如果您查看Internet上的各种实现(例如),您将看到管理员没有
    revert()
    ,但通常类似于
    getMemento()
    。因此,负责撤销的类是另一个类,它在管理员上调用
    getMemento()
    ,然后在主题上调用
    revert()

    即使您希望管理员负责撤消,也要注意
    employee.revert()
    是一种专门为
    career.revert()
    创建的方法,因为在这种设计中,没有其他人可以访问纪念品。您可以将其可见性降低为仅由管理员可见。(如果是C++的话,很容易用<代码>朋友< /C>来完成,但是在爪哇,你必须有创造性,使用<代码>包<代码>可见性或其他方式。 2) 在Memento模式中,类及其Memento是紧密耦合的。实际上,只有类本身可以访问Memento的内部,其他人不应该看到Memento是如何组成的。所以,对类的更改是否会传播到它的纪念品并不重要

    如果你想隔离变化,你可以再次发挥创造力。例如,您可以提取另一个包含这些字段的类(例如,通过
    状态的名称
    ),然后在原始类及其Memento中使用该
    状态
    ,而不是在类及其Memento中复制
    名称
    手机
    。这样,当您更改类的状态时,只需修改
    状态

    旁注:最好将Memento定义为主题内的嵌套静态类

    所以我的设计,解决了你的问题,应该是这样的:

    public class Employee {
        private State state;
    
        public Memento save() {
            return new Memento(state);
        }
    
        public void revert(Memento memento) {
            this.state = memento.state;
        }
    
        public static class Memento {
            private final State state;
    
            public Memento(State state) {
                this.state = state;
            }
        }
    
        public static class State {
            private String name;
            private String phone;
        }
    }
    
    public class Caretaker {
        private Stack<Employee.Memento> history;
    
        public Caretaker() {
            history = new Stack<>();
        }
    
        public void addMemento(Employee.Memento memento) {
            history.push(memento);
        }
    
        public Employee.Memento getMemento() {
            return history.pop();
        }
    }
    
    public class UndoHandler {
        Employee employee;
        Caretaker caretaker;
    
        public void snapshot() {
            caretaker.save(employee.save());
        }
    
        public void undo() {
            employee.revert(caretaker.getMemento());
        }
    }
    
    公共类员工{
    私营国家;
    公共纪念品保存(){
    归还新的纪念品(州);
    }
    公共无效恢复(纪念品){
    this.state=memento.state;
    }
    公共静态类纪念品{
    私人最终国家;
    公共纪念品(州){
    this.state=状态;
    }
    }
    公共静态类状态{
    私有字符串名称;
    私人电话;
    }
    }
    公务舱管理员{
    私有堆栈历史;
    公共看守人(){
    历史=新堆栈();
    }
    public void addMemento(Employee.Memento Memento){
    历史推送(纪念品);
    }
    公共雇员。Memento getMemento(){
    返回history.pop();
    }
    }
    公共类撤消处理程序{
    员工;
    看守人;
    公共无效快照(){
    管理员.save(employee.save());
    }
    公共作废撤消(){
    employee.revert(carether.getMemento());
    }
    }
    
    public class Employee {
        private State state;
    
        public Memento save() {
            return new Memento(state);
        }
    
        public void revert(Memento memento) {
            this.state = memento.state;
        }
    
        public static class Memento {
            private final State state;
    
            public Memento(State state) {
                this.state = state;
            }
        }
    
        public static class State {
            private String name;
            private String phone;
        }
    }
    
    public class Caretaker {
        private Stack<Employee.Memento> history;
    
        public Caretaker() {
            history = new Stack<>();
        }
    
        public void addMemento(Employee.Memento memento) {
            history.push(memento);
        }
    
        public Employee.Memento getMemento() {
            return history.pop();
        }
    }
    
    public class UndoHandler {
        Employee employee;
        Caretaker caretaker;
    
        public void snapshot() {
            caretaker.save(employee.save());
        }
    
        public void undo() {
            employee.revert(caretaker.getMemento());
        }
    }