Memento 패턴

구름코딩·2020년 12월 1일

Java 디자인 패턴

목록 보기
11/12

인스턴스 정보를 저장, 복원하는 행위에 사용되는 패턴

  • 인스턴스를 복원할려면 전에 저장했던 인스턴스에 언제든지 접근해야한다

Memento Class

MacroCommand의 history를 담아서 load시 꺼낼수 있도록 하는 클래스를 구현

public class Memento {
    private MacroCommand state;

    public Memento(MacroCommand state) {
    // 받을때 값으로 받는다
        this.state = state.clone();
    }

    public MacroCommand getSavedState() {
    // 받은 값도 값으로 반환해준다
        return state.clone();
    }
}

여기서 매개변수로 받은 state를 clone이 아닌 그대로 전달하게 되면 레퍼런스 타입으로 전달되어서 주소를 참조하게 되는 형태가 된다. 따라서 외부 history가 변경되면 전달받아서 보관중인 값도 변경되므로 값을 실제로 복사해서 값을 전달하도록 해야한다
이때 사용하는것이 clone()메서드이다. clone()메서드를 사용하기 위해서는 해당 객체가 Clonable해야한다

MacroCommand Class

command 객체를 관리하는 MacroCommand에 clone()기능을 추가한다. 이때 MacroCommand객체가 clone()되기 위해서 Cloneable 인터페이스를 implements해야한다

public class MacroCommand implements Command, Cloneable{

    // 커맨드 관리
    private Stack<Command> commandStack = new Stack<>();

    @Override
    public void execute() {
        commandStack.forEach(Command::execute);
    }

    public void add(Command command) {
        commandStack.push(command);
    }

    public void undo() {
        if (!commandStack.isEmpty())
            commandStack.pop();
    }

    public void clear()
    {
        commandStack.clear();
    }

    @Override
    public MacroCommand clone() {
        MacroCommand macroCommand = null;
        try {
            macroCommand = (MacroCommand) super.clone();
            macroCommand.commandStack = 
                    (Stack<Command>)this.commandStack.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return macroCommand;
    }
}
정리

원하는 특정 객체를 담기 위해서는 참조(레퍼런스)타입이 아니라 값(value)타입으로 담아야 하며, 해당 객체 및 해당 객체 내 객체들 또한 Clonable 인터페이스를 가지고있어야 한다. Clonable() 인터페이스가 있는 객체여야 clone()메서드를 진행할수 있고 그래야 값을 전달 받거나 전달 할 수 있게 된다

profile
내꿈은 숲속의잠자는공주

0개의 댓글