ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Design Pattern] 메멘토(Memento) 패턴 - 디자인 패턴
    CSE/Design Pattern 2015. 6. 13. 10:54

    Pattern #19  메멘토 패턴



     객체의 상태를 저장해두었다가 복원해야 될 경우 사용





     패턴 요약 
      - 오리지널 객체는 본래의 기능에 충실하고 메멘토는 상태 정보와 관리를 전답하면서 캡슐화되어 독립적
      - 상태 역할만 분리


     
     동기

      

     게임회사에 다니는 당신에게 새로 맡겨진 일은 바둑 프로그램 개발 작업이다. 게임 인공지능 부분은 다른 팀에서 맡기로 하였고, 당신은 사용자 인터페이스와 바둑 무르기, 복기하기 등과 같은 기능을 개발하여야 한다. 바둑 무르기 기능의 경우, 사용자가 두기 이전 상태로 되돌려야 하며 복기 기능은 게임의 처음부터 진행된 때 까지 바둑판 상태를 차례대로 표현할 수 있어야 한다. 이렇게 객체의 상태를 저장해두었다가 복원해야 될 경우 당신은 어떻게 객체지향설계를 할 것인가?

     

     









     





      바둑 게임 분석
       - 필요 정보
         * 바둑돌 배치: int board[19][19]; // 0: none, -1: black, 1: white
         * 흰돌 사석수: int whiteDeadNum;
         * 검은돌 사석수: int blackDeadNum;
         * 다음 둘 차례: int whoseTurn; // -1:black's turn, 1: white's turn
         * 패 위치: paePosX, paePosY;











      해결 방안 1:
       - 보관할 필요가 있는 정보를 따로 뽑아서 객체로 만들어 이를 저장하거나 복원함














       해결 방안 2:
       - 원 소유자를 제외한 다른 객체에서 상태정보(객체)에 대한 접근을 제한하기 위하여 Memento객체를 만든다.
        - Memento 객체의 GoState를 포함한다.
        - Memento 객체의 생성과 내부 GoState 객체 접근은 원 소유자인 GoBoard에서만 할 수 있다.
        - GoBoard는 Memento를 생성하고, 지정된 Memento로 복원하는 함수를 구현한다.
         * CreateMemento(): 내부 정보를 외부 객체(Memento)화
         * SetMemento(Memento *m): m에 저장되어있는 상태로 복원

















     - 접근 제한 방법
       * in C++: friend keyword 사용












     의도
       - 객체지향 개념인 캡슐화(Encapsulation)을 어기지 않으면서, 특정 객체의 상태정보를 나중에 복원하기 위하여 해당 정보를 외부에 상태객체로 표현한다.
      


     별명
       - Token



     적용범위
       - 어떤 객체의 특정 시점에 대한 상태 정보가 나중에 복원되기 위해 저장되어야 할 경우
        - 객체의 상태정보를 직접 접근하는 것이 정보 은닉이나 캡슐화 원리를 깨뜨릴 때.



     결과
       - 캡슐화 범위 안으로 유지
          * Originator 객체 이외의 객체에서 Memento 객체의 내부 정보를 접근하는 것을 제한
        - Originator 단순화
          * Client가 내부상태정보를 직접 접근하지 않으면서도 Memento 객체를 이용하여 Originator를 예전 상태로 복원할 수 있다.
        - 메멘토 사용이 부담이 될 수도 있음
          * Memento 객체의 생성이 자주 일어나거나 내부 상태정보가 많은 경우
        - 인터페이스 정의
          * 캡슐화를 위해 Memento 객체의 내부 정보 접근을 제한하는 것은 특정 프로그래밍언어에서는 어려울 수도 있음





    Life.java

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    package memento;
     
    public class Life {
        private String time;
     
        public void setTime(String time) {
            System.out.println("Setting time to " + time);
            this.time = time;
        }
     
        public Memento saveToMemento() {
            System.out.println("Saving time to Memento");
            return new Memento(time);
        }
     
        public void restoreFromMemento(Memento memento) {
            time = memento.getSavedTime();
            System.out.println("Time restored from Memento: " + time);
        }
     
        public static class Memento {
            private final String time;
     
            public Memento(String time) {
                this.time = time;
            }
     
            public String getSavedTime() {
                return time;
            }
        }
    }
     
     
    cs





    Memento.java

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    package memento;
     
    import java.util.ArrayList;
    import java.util.List;
     
    public class MementoMain {
        public static void main(String[] args) {
            List<Life.Memento> savedTimes = new ArrayList<Life.Memento>();
     
            Life life = new Life();
     
            life.setTime("2000 B.C");
            savedTimes.add(life.saveToMemento());
            life.setTime("2000 A.D");
            savedTimes.add(life.saveToMemento());
            life.setTime("3000 A.D");
            savedTimes.add(life.saveToMemento());
            life.setTime("4000 A.D");
            savedTimes.add(life.saveToMemento());
     
            life.restoreFromMemento(savedTimes.get(0));
        }
    }
     
     
    cs







      





    댓글

Designed by Tistory.