목표:
Undo 기능을 구현하기.
이 때 Undo는 여러 차례 연속으로 행할 수 있어야 한다.
예시 상황:
Notepad 클래스에 void SetString(String s)과 String GetString()메소드가 있다고 하자.
Notepad 클래스에는 String타입의 content라는 변수가 존재하며, Notepad는 한 번에 딱 하나의 String값만을 저장한다고 가정하자.
Notepad 클래스에 string을 저장한 후 Undo하는 기능을 추가하려면 어떻게 해야할까?
접근 1:
Notepad 클래스에 stringList를 추가하고, 이 List에 SetString()이 실행될 때마다 String정보를 저장한다.
Undo() 메소드를 추가하고, 이 메소드가 실행될 때마다 List에서 String정보를 가져와 이전 상태로 되돌린다.
-> 이 방식의 문제점:
만약 Notepad에 SetString이 아닌 DrawShape()과 같은 메소드가 추가된다면?
Shape 정보를 저장하는 shapeList를 별도로 만들어야 한다.
이는 확장성이 좋지 못한 방법이다.
접근 2:
NotepadStatus클래스를 제작한다.
이 클래스는 Notepad의 상태(status)를 저장한다.
NotepadStatus 내부에는 stringState, shapeState 같이 여러 콘텐츠를 저장하는 변수들이 존재할 수 있다.
Notepad 클래스에 NotepadStatus클래스를 저장하는 리스트 statusList를 만들고, Notepad에서 발생하는 모든 변화를 여기에 저장한다.
만약 DrawShape() 같은 메소드가 추가된다고 하더라도, Notepad 클래스 자체에는 변화가 없고,
NotepadStatus클래스 내부에 shapeState 같은 변수를 추가해주기만 하면 된다.
이는 접근1보다 확장성이 높은 방법이다.
-> 이 방식의 문제점:
Notepad 클래스가 너무 많은 일을 혼자 맡게 된다. 이는 Single Responsibility Principle(SRP)에 위배된다.
접근 3 (Memento Pattern):
NotepadStatus 클래스를 제작한다. (접근 2와 동일)
NotepadHistory 클래스를 제작한다. 이 클래스 내부에 saveStatus(), loadStatus() 메소드를 제작한다.
이 클래스 내부에 NotepadStatus클래스를 저장하는 리스트 statusList를 만들고, Notepad에서 발생하는 모든 변화를 여기에 저장한다.
Notepad에서 변화가 일어날 때마다 NotepadHistory 는 해당 변화를 기록하고 자신 내부에 저장한다.
이로써 Notepad는 Status를 기록하는 것에 더이상 신경쓰지 않아도 된다.
정리 - Memento Pattern이란?
Memento 패턴은
1) 행위의 주체가 되는 클래스 (Originator)
2) 주체의 다양한 행동들은 하나의 형태로 나타낼 수 있는 클래스 (Memento)
3) 주체의 행동을 기록하는 클래스 (Caretake)
세가지 객체로 구분되며, 이 세 객체의 상호작용을 통해 구현된다.
'software engineering > design patterns' 카테고리의 다른 글
디자인 패턴을 남용하지 말아야 하는 이유 (0) | 2021.01.09 |
---|---|
State 패턴 (0) | 2021.01.09 |
UML이란 (0) | 2021.01.09 |