JAVA/DesignPattern

Design Pattern 디자인 패턴 Memento Pattern 메멘토 패턴

호두밥 2021. 12. 27. 21:01

Memento Pattern 메멘토 패턴

행동 패턴으로, 객체의 과거 버전을 저장하기 위해 사용됩니다. 프로세스가 진행되는 중에 원하는 지점에서 객체를 저장하고, 나중에 저장한 지점으로 복원할 수 있습니다. (Undo)

Memento Pattern 메멘토 패턴 사용이 적합한 경우

  • 객체의 상태 변화 이력을 저장하고 싶은 경우 (스냅샷을 남기고 싶은 경우)
  • field나 getter/setter를 이용해서 객체에 직접 접근하여 캡슐화가 손상된 경우

장단점

장점

  • 캡슐화는 손상시키지 않고 객체의 상태 변화 이력을 저장할 수 있습니다.
  • 객체의 상태 변화 이력을 관리함으로써 객체의 코드를 단순하게 할 수 있습니다.

단점

  • 메멘토 패턴이 너무 자주 사용되면, RAM 사용량이 많을 수 있습니다.
  • 과거 이력을 삭제할 수 있도록 원래 객체의 생애주기를 관리해야 합니다.
  • 동적 프로그래밍 언어인 PHP, Python, JavaScript에서는 이력이 고유한 상태로 남아있을 것을 보장할 수 없습니다.

 

Memento Pattern 메멘토 패턴 구현

이력을 담을 객체인 Memento를 생성합니다. 그리고 Memento(이력) 리스트를 관리할 객체인 TimeLine을 생성합니다.

필요한 경우 TimeLine에 Memento(이력)을 저장할 수 있는 기능을 구현합니다. SampleObject를 Memento로 바꾸어주는 (스냅샷을 찍는) saveState() 메소드를 생성하고, TimeLine의 Memento(이력) 리스트에 저장하는 기능을 구현합니다. 

Memento

public class Memento {
    private String state;

    public Memento(String state) {
        this.state = state;
    }

    public String getState(){
        return state;
    }

    @Override
    public String toString() {
        return "Memento{" +
                "state='" + state + '\'' +
                '}';
    }
}

SampleObject

public class SampleObject {

    private String state;

    public SampleObject(String state) {
        this.state = state;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public Memento saveState(){
        return new Memento(state);
    }
}

TimeLine

public class TimeLine {
    private List<Memento> mementoList = new ArrayList<>();

    public void add(Memento memento) {
        mementoList.add(memento);
    }

    public Memento get(int index) {
        return mementoList.get(index);
    }

    public String printHistory(){
       return mementoList.stream().map(Memento::toString).collect(Collectors.joining("\n"));
    }

}

Main

public class Main {
    public static void main(String[] args) {
        TimeLine timeLine = new TimeLine() ;
        SampleObject sampleObject = new SampleObject("start");

        timeLine.add(sampleObject.saveState());

        sampleObject.setState("doing 1 step");
        timeLine.add(sampleObject.saveState());

        System.out.println("====== show history ======");
        System.out.println(timeLine.printHistory());
    }
}
====== show history ======
Memento{state='start'}
Memento{state='doing 1 step'}

참조