프로그래밍/자바 디자인패턴

디자인 패턴 Memento 패턴

가카리 2012. 8. 13. 21:43
반응형

Memento 패턴

 

 

 

 

 

                  

이름

해설

Memento

Gamer의 상태를 나타내는 클래스

Gamer

게임을 싱행하는 주인공의 클래스 Memento의 인스턴스를 만든다.

Main

게임을 진행시키는 클래스 Memento의 인스턴스를 저장해두고 필요에 따라서 Gamer의 상태를 복원한다.

 

 

Memento 클래스

 

package kch;

 

import java.util.List;

import java.util.ArrayList;

 

public class Memento{

          

                     /**

                      * @uml.property  name="money"

                      */

                     int money;//소지금

                     /**

                      * @uml.property  name="fruits"

                      * @uml.associationEnd  multiplicity="(0 -1)" elementType="java.lang.String"

                      */

                     ArrayList fruits;//과일

                    

                     /**

                      * @return

                      * @uml.property  name="money"

                      */

                     public int getMoney(){//소지금을 얻는다

                               

                                return money;

          

                     }

                    

                     Memento(int money){//생성자

                               

                                this.money = money;

                                this.fruits = new ArrayList();

                               

                     }

                    

                     void addFruit(String fruit){//과일을 추가한다.

                    

                                fruits.add(fruit);

          

                     }

          

                     List getFruits(){//과일을 얻는다.

                               

                                return (List)fruits.clone();

                               

                     }

                    

}

 

 

Gamer 클래스

 

package kch;

 

import java.util.ArrayList;

import java.util.Iterator;

import java.util.List;

import java.util.Random;

 

public class Gamer {

 

                     /**

                      * @uml.property  name="money"

                      */

                     private int money;//소지금

                     /**

                      * @uml.property  name="fruits"

                      * @uml.associationEnd  multiplicity="(0 -1)" elementType="java.lang.String"

                      */

                     private List fruits = new ArrayList();//과일

                     /**

                      * @uml.property  name="random"

                      */

                     private Random random = new Random();//난수 발생기

                     private static String[] fruitsname = {// 과일 이름의 표

                               

                                "사과", "포도", "바나나", "",

                               

                     };

          

                     public Gamer(int money){

                    

                                this.money = money;

                               

                     }

                    

                     //돈을 반환하는 함수.

                     /**

                      * @return

                      * @uml.property  name="money"

                      */

                     public int getMoney(){

                               

                                return money;

                               

                     }

                    

                     public void bet(){

                               

                                int dice = random.nextInt(6) + 1;//6이하의 주사위를 던짐

                               

                                if(dice == 1){//주사위가 1이면

                                         

                                          money += 100;

                                          System.out.println("소지금이 증가했습니다.");

                               

                                }else if(dice == 2){//주사위가 2이면

                                         

                                          money /= 2;

                                          System.out.println("소지금이 절반이 되었습니다.");

                               

                                }else if(dice == 6){//주사위가 6이면

                                         

                                          String f = getFruit();//맛있는 과일일수도 아닐수도 있음

                                          System.out.println("과일(" +  f + ") 을 받았습니다.");

                                          fruits.add(f);

                                         

                                }else{

                                         

                                          System.out.println("변한 것이 없습니다.");

                               

                                }

                     }

                               

                     //현재의 상태를 저장하는 메소드

                     public Memento createMemento(){

                                                    

                                          Memento m = new Memento(money);//돈을 저장함.

                                          Iterator it = fruits.iterator();//반복자를 만듬.

                                         

                                          while(it.hasNext()){//다음이 있으면

                                                    

                                                     String f = (String)it.next();

                                                     if(f.startsWith("맛있는")){//과일을 맛있는 것만 저장하기 위해서.

                                                               

                                                                m.addFruit(f);//추가시킴

                                                               

                                                     }

                                                    

                                          }

                                         

                                          return m;

                     }

                    

                     public void restoreMemento(Memento memento){

                               

                                this.money = memento.money;

                                this.fruits = memento.getFruits();

                    

                     }

                    

                     public String toString(){

                               

                                return "[money = " + money + ", fruits = " + fruits + "]";

                    

                     }

          

                     public String getFruit(){

                               

                                String prefix = "";

                                if(random.nextBoolean()){//맛있는 과일일수도 있고 아닐수도 있음

                                          prefix = "맛있는 ";

                                }

                               

                                return prefix + fruitsname[random.nextInt(fruitsname.length)];

                               

                     }

                    

}

 

 

Main 클래스

 

package kch;

 

public class Main {

           public static void main(String[] args){

                     Gamer gamer = new Gamer(100);//게이머가 처음에 100원을 가지고있다.

                     Memento memento = gamer.createMemento();//처음상태를 저장해둔다.(저장하는것은 과일)

                    

                     for(int i=0; i < 100; i++){

                                System.out.println("==== " + i);

                                System.out.println("현상 : " + gamer);//여기서 toString이 사용됨.

                               

                                gamer.bet();//주사위를 던져서 돈이 올라가거나 과일을 받음.

                               

                                System.out.println("소지금은 " + gamer.getMoney() + "원이 되었습니다.");

                               

                                //Memento 취급 결정

                                //이전에 저장한 값과 비교해서 저장하거나 복원하게 됨.

                                if(gamer.getMoney() >  memento.getMoney()){

                               

                                          System.out.println("많이 증가했으므로 현재 상태를 저장");

                                          memento = gamer.createMemento();

                               

                                }else if(gamer.getMoney() < memento.getMoney() / 2){

                                         

                                          System.out.println("많이 감소해서 이전의 상태로 복원하자");

                                          gamer.restoreMemento(memento);

                                         

                                }

                               

                                try{

                               

                                          Thread.sleep(1000);

                               

                                }catch(InterruptedException e){

                                         

                                }

                               

                                System.out.println("");

                               

                     }

                    

           }

 

}

 

 

 

 

 

이번 패턴은 그림판이나 워드를 쓸때 자주 사용하는 실행취소기능을 패턴으로 구현해보았습니다. 여기서 createMemento메소드가 저장하는 부분이고 restoreMemento가 불러오는 부분입니다.

 

그렇다면 언제 불러오고 언제 저장하나를 결정하는 곳은 Main클래스입니다. 현재 가진돈과 이전에 가진돈을 비교해서 저장하는지 불러오는지를 결정합니다.

 

이렇게 저장하거나 불러오는 기능과 언제 저장할건지 언제 불러온건지 이 두가지를 분리해둔다면

 

언제든지 파일에 저장하는 기능을 추가하거나 여러단계로 나눠서 저장하고 싶은 기능을 추가 할 때 각자의 클래스만 수정하면됩니다.

 

반응형

'프로그래밍 > 자바 디자인패턴' 카테고리의 다른 글

디자인패턴 Command 패턴  (1) 2012.08.18
디자인패턴 Proxy 패턴  (0) 2012.08.16
디자인패턴 Flyweight 패턴  (0) 2012.08.15
디자인패턴 State 패턴  (0) 2012.08.14
디자인패턴 Observer 패턴  (0) 2012.08.10
디자인패턴 Mediator 패턴  (0) 2012.08.09
디자인패턴 Facade 패턴  (0) 2012.08.06
디자인 패턴 ProtoType패턴  (0) 2012.08.03