디자인 모드 (1) - 비망록 모드

정의: 패 키 징 성 을 파괴 하지 않 는 전제 에서 대상 의 내부 상 태 를 포착 하고 이 대상 외 에 이 상 태 를 저장 합 니 다.이렇게 하면 이 대상 을 원래 저 장 된 상태 로 복원 할 수 있다.
유형: 행동 클래스
아 날로 그:
        우 리 는 프로 그래 밍 을 할 때 항상 대상 의 중간 상 태 를 저장 해 야 하 며 필요 할 때 이 상태 로 회복 할 수 있다.예 를 들 어, 우리 가 Eclipse 를 사용 하여 프로 그래 밍 을 할 때, 만약 에 실수 (예 를 들 어 실수 로 몇 줄 의 코드 를 잘못 삭 제 했 습 니 다) 를 작성 하면, 우 리 는 삭제 전의 상 태 를 되 돌려 주 기 를 원 합 니 다. Ctrl + Z 를 사용 하여 되 돌 릴 수 있 습 니 다.이때 우 리 는 비망록 모드 를 사용 하여 실현 할 수 있다.
 
비망록 모드 의 구조
  • 발기인: 현재 시간의 내부 상 태 를 기록 하고 백업 범위 에 속 하 는 상 태 를 정의 하 며 비망록 데 이 터 를 만 들 고 복원 하 는 것 을 책임 집 니 다.
  • 비망록: 발기인 대상 의 내부 상 태 를 저장 하고 필요 할 때 발기인 이 필요 로 하 는 내부 상 태 를 제공한다.
  • 관리 역할: 비망록 을 관리 하고 보존 하 며 비망록 을 제공한다.
  • class Originator {
    	private String state = "";
    	
    	public String getState() {
    		return state;
    	}
    	public void setState(String state) {
    		this.state = state;
    	}
    	public Memento createMemento(){
    		return new Memento(this.state);
    	}
    	public void restoreMemento(Memento memento){
    		this.setState(memento.getState());
    	}
    }
    class Memento {
    	private String state = "";
    	public Memento(String state){
    		this.state = state;
    	}
    	public String getState() {
    		return state;
    	}
    	public void setState(String state) {
    		this.state = state;
    	}
    }
    class Caretaker {
    	private Memento memento;
    	public Memento getMemento(){
    		return memento;
    	}
    	public void setMemento(Memento memento){
    		this.memento = memento;
    	}
    }
    public class Client {
    	public static void main(String[] args){
    		Originator originator = new Originator();
    		originator.setState("  1");
    		System.out.println("    :"+originator.getState());
    		Caretaker caretaker = new Caretaker();
    		caretaker.setMemento(originator.createMemento());
    		originator.setState("  2");
    		System.out.println("     :"+originator.getState());
    		originator.restoreMemento(caretaker.getMemento());
    		System.out.println("     :"+originator.getState());
    	}
    }

       코드 는 단일 상태 단일 백업 의 예 를 보 여 줍 니 다. 논 리 는 매우 간단 합 니 다. Originator 류 의 state 변 수 는 필요 할 때 복원 할 수 있 도록 백업 해 야 합 니 다.Memento 클래스 에 도 state 변수 가 있 습 니 다. Originator 클래스 의 state 변 수 를 저장 하 는 임시 상태 입 니 다.한편, Caretaker 류 는 비망록 류 를 관리 하 는 데 사용 되 며 비망록 대상 에 상 태 를 기록 하거나 상 태 를 되 찾 는 데 사용 된다.
     
    다 중 상태 백업 비망록
           유 니 버 설 코드 프 리 젠 테 이 션 의 예 에서 Originator 류 는 하나의 state 변수 만 백업 해 야 합 니 다. 일반적인 상황 에서 발기인 역할 은 자바 빈 입 니 다. 대상 에서 백업 해 야 할 변 수 는 하나 가 아니 라 백업 해 야 할 상태 도 하나 가 아 닙 니 다. 이것 이 바로 다 중 상태 다 중 비망록 입 니 다.비망록 을 실현 하 는 방법 은 매우 많 습 니 다. 비망록 모델 은 변형 과 처리 방식 이 많 습 니 다. 유 니 버 설 코드 와 같은 방식 은 일반적으로 사용 되 지 않 습 니 다. 대부분 상황 에서 비망록 모델 은 다 중 상태 로 백업 되 어 있 습 니 다.사실 다 중 상태 다 중 백업 을 실현 하 는 것 도 간단 합 니 다. 가장 자주 사용 하 는 방법 은 우리 가 Memento 에 Map 용 기 를 추가 하여 모든 상 태 를 저장 하 는 것 입 니 다. Caretaker 류 에서 도 하나의 Map 용 기 를 사용 해 야 모든 백업 을 저장 할 수 있 습 니 다.다음은 다 중 상태 다 중 백업 의 예 를 보 여 드 리 겠 습 니 다.
    class Originator {
    	private String state1 = "";
    	private String state2 = "";
    	private String state3 = "";
    	public String getState1() {
    		return state1;
    	}
    	public void setState1(String state1) {
    		this.state1 = state1;
    	}
    	public String getState2() {
    		return state2;
    	}
    	public void setState2(String state2) {
    		this.state2 = state2;
    	}
    	public String getState3() {
    		return state3;
    	}
    	public void setState3(String state3) {
    		this.state3 = state3;
    	}
    	public Memento createMemento(){
    		return new Memento(BeanUtils.backupProp(this));
    	}
    	
    	public void restoreMemento(Memento memento){
    		BeanUtils.restoreProp(this, memento.getStateMap());
    	}
    	public String toString(){
    		return "state1="+state1+"state2="+state2+"state3="+state3;
    	}
    }
    class Memento {
    	private Map<String, Object> stateMap;
    	
    	public Memento(Map<String, Object> map){
    		this.stateMap = map;
    	}
    	public Map<String, Object> getStateMap() {
    		return stateMap;
    	}
    	public void setStateMap(Map<String, Object> stateMap) {
    		this.stateMap = stateMap;
    	}
    }
    class BeanUtils {
    	public static Map<String, Object> backupProp(Object bean){
    		Map<String, Object> result = new HashMap<String, Object>();
    		try{
    			BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass());
    			PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();
    			for(PropertyDescriptor des: descriptors){
    				String fieldName = des.getName();
    				Method getter = des.getReadMethod();
    				Object fieldValue = getter.invoke(bean, new Object[]{});
    				if(!fieldName.equalsIgnoreCase("class")){
    					result.put(fieldName, fieldValue);
    				}
    			}
    			
    		}catch(Exception e){
    			e.printStackTrace();
    		}
    		return result;
    	}
    	
    	public static void restoreProp(Object bean, Map<String, Object> propMap){
    		try {
    			BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass());
    			PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();
    			for(PropertyDescriptor des: descriptors){
    				String fieldName = des.getName();
    				if(propMap.containsKey(fieldName)){
    					Method setter = des.getWriteMethod();
    					setter.invoke(bean, new Object[]{propMap.get(fieldName)});
    				}
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    }
    class Caretaker {
    	private Map<String, Memento> memMap = new HashMap<String, Memento>();
    	public Memento getMemento(String index){
    		return memMap.get(index);
    	}
    	
    	public void setMemento(String index, Memento memento){
    		this.memMap.put(index, memento);
    	}
    }
    class Client {
    	public static void main(String[] args){
    		Originator ori = new Originator();
    		Caretaker caretaker = new Caretaker();
    		ori.setState1("  ");
    		ori.setState2("  ");
    		ori.setState3("  ");
    		System.out.println("===     ===
    "+ori); caretaker.setMemento("001",ori.createMemento()); ori.setState1(" "); ori.setState2(" "); ori.setState3(" "); System.out.println("=== ===
    "+ori); ori.restoreMemento(caretaker.getMemento("001")); System.out.println("=== ===
    "+ori); } }

    비망록 모드 의 장단 점 과 적용 장면
    비망록 모드 의 장점 은 다음 과 같다.
  • 발기인 캐릭터 의 상태 가 바 뀌 었 을 때 잘못된 변화 일 수 있 습 니 다. 우 리 는 비망록 모드 를 사용 하면 이 잘못된 변 화 를 복원 할 수 있 습 니 다.
  • 백업 상 태 는 발기인 역할 외 에 저 장 됩 니 다. 그러면 발기인 역할 은 각 백업 상 태 를 관리 할 필요 가 없습니다.

  • 비망록 모드 의 단점:
  • 실제 응용 에서 비망록 모델 은 모두 다 중 상태 와 다 중 백업 이 고 발기인 역할 의 상 태 는 비망록 대상 에 저장 해 야 하 며 자원 에 대한 소 모 는 비교적 심각 하 다.

  • 스크롤 백 작업 이 필요 하 다 면 jdbc 의 트 랜 잭 션, 텍스트 편집기 의 Ctrl + Z 복구 등 비망록 모드 를 사용 하 는 것 이 좋 습 니 다.

    좋은 웹페이지 즐겨찾기