깊이 들 어가 기 쉬 운 디자인 모델 --- Prototype (원형 모델) 의 깊이 복제

전편 의 깊이 있 는 디자인 모델 인 - Prototype (원형 모델) 의 얕 은 복제 실현 에 이 어 본 고 는 Prototype (원형 모델) 의 진급 편 - 깊이 있 는 복제 에 들어간다.
깊이 클론 - 직렬 화 방식 구현
  대상 을 흐름 에 쓰 는 과정 은 직렬 화 (Serialization) 과정 이 고 대상 을 흐름 에서 읽 는 과정 을 반 직렬 화 (Deserialization) 라 고 한다.흐름 에 적 힌 것 은 대상 의 클론 (새로운, 독립 된) 이 며, 원래 대상 은 JVM 메모리 모델 에 존재 합 니 다.따라서 다음 코드 는 직렬 화 방식 으로 심도 있 는 복 제 를 실현 한다.
첫 번 째 단계: 전편 의 코드 를 약간 변경 하고 대상 인용 을 추가 합 니 다.
원형 인터페이스: FruitPrototype 은 변 하지 않 습 니 다.
package com.wenniuwuren.prototype;
/**
 *     
 * @author wenniuwuren
 *
 */
public interface FruitPrototype{  
     public abstract FruitPrototype shallowClone() throws CloneNotSupportedException;  
}  
  

원형 구체 적 실현: 인용 및 속성 을 추가 한 getter 와 setter 방법 비교
package com.wenniuwuren.prototype;
/**
 *       
 * @author wenniuwuren
 *
 */

public class ConcteteFruitPrototype implements FruitPrototype, Cloneable{  
    private String size;  
    private String color;  
	private Vitamins vitamins;
    
    public ConcteteFruitPrototype(String size, String color, Vitamins vitamins) {  
        this.size = size;  
        this.color = color;  
        this.vitamins = vitamins;
    }  
    
    //   
    public FruitPrototype shallowClone() throws CloneNotSupportedException  {  
        return (FruitPrototype) super.clone();  
    } 
    
    //     
    public void display(String colorname) {  
        System.out.println(colorname+"    : "+size+"    :"+color);  
    }

    
	public Vitamins getVitamins() {
		return vitamins;
	}

	public void setVitamins(Vitamins vitamins) {
		this.vitamins = vitamins;
	}  
	
	public String getSize() {
		return size;
	}

	public void setSize(String size) {
		this.size = size;
	}

	public String getColor() {
		return color;
	}

	public void setColor(String color) {
		this.color = color;
	}
}  
  

원형 관리 클래스: FruitTool 은 변 하지 않 습 니 다.
package com.wenniuwuren.prototype;

import java.util.HashMap;
/**
 *      
 * @author wenniuwuren
 *
 */
public class FruitTool {
	private HashMap<String, FruitPrototype> fruits = new HashMap<String, FruitPrototype>();

	public void put(String key, FruitPrototype fruitPrototype) {
		fruits.put(key, fruitPrototype);
	}

	public FruitPrototype get(String key) {
		return fruits.get(key);
	}
}

과일 에 들 어 있 는 비타민 류: Vitamins 는 새로 추 가 된 대상 인용 류 로 하나의 속성 만 테스트 할 수 있 습 니 다.
package com.wenniuwuren.prototype;
/**
 *           
 * @author wenniuwuren
 *
 */
public class Vitamins {
    
	private Boolean isContainsVitaminA;

	public Boolean getIsContainsVitaminA() {
		return isContainsVitaminA;
	}

	public void setIsContainsVitaminA(Boolean isContainsVitaminA) {
		this.isContainsVitaminA = isContainsVitaminA;
	}

}

테스트 클래스:
package com.wenniuwuren.prototype;

import java.io.IOException;

public class Client {
	public static void main(String[] args) throws CloneNotSupportedException, ClassNotFoundException, IOException {
		
		FruitTool fruitTool = new FruitTool();

		//            
		fruitTool.put("Apple", new ConcteteFruitPrototype("Middle", "Green", new Vitamins()));
		fruitTool.put("Watermelon", new ConcteteFruitPrototype("Large", "Red", new Vitamins()));
		fruitTool.put("Lemon", new ConcteteFruitPrototype("Small", "Yellow", new Vitamins()));

		
		System.out.println("#######################     ########################");
		String fruitName = "Apple";
		ConcteteFruitPrototype concteteFruitPrototype1 = (ConcteteFruitPrototype) fruitTool
				.get(fruitName).shallowClone();
		concteteFruitPrototype1.display(fruitName);
		
		System.out.print("   ,           String      :"  );
		System.out.println(concteteFruitPrototype1.getColor().equals(((ConcteteFruitPrototype)fruitTool
				.get(fruitName)).getColor()));
		
		System.out.print("   ,                  :"  );
		System.out.println(concteteFruitPrototype1.getVitamins().getIsContainsVitaminA() == ((ConcteteFruitPrototype)fruitTool
		.get(fruitName)).getVitamins().getIsContainsVitaminA());
		
		System.out.println("----------------          ,         --------------------");
	
		concteteFruitPrototype1.setColor("Red");
		System.out.print("   ,          String      :");
		System.out.println(concteteFruitPrototype1.getColor().equals(((ConcteteFruitPrototype)fruitTool
				.get(fruitName)).getColor()));
		
		concteteFruitPrototype1.getVitamins().setIsContainsVitaminA(Boolean.FALSE);
		System.out.print("   ,                  :"  );
		System.out.println(concteteFruitPrototype1.getVitamins().getIsContainsVitaminA() == ((ConcteteFruitPrototype)fruitTool
		.get(fruitName)).getVitamins().getIsContainsVitaminA());
		
	}
}

테스트 결과:
4. 567913. 얕 은 복 제 는 전편 에서 언급 한 바 와 같다 는 것 을 알 수 있다.
값 에 따라 전 달 된 데이터 만 복제 합 니 다. (String 형식의 데 이 터 는 복 제 된 것 이 확실 합 니 다. 오래된 String 데이터 와 독립 되 었 습 니 다) 인 용 된 대상 을 복사 하지 않 습 니 다. (대상 인용 은 JVM 메모리 모델 에 저 장 된 동일 한 것 입 니까? 그 중 하나의 인용 수 는 변 경 된 후에 도 인용 데 이 터 는 일치 합 니 다)
STEP 2: 딥 클론 추가
원형 인터페이스: 깊이 복제 방법 추가
Apple    : Middle    :Green
---------        ------------------
   ,           String      :true
   ,                  :true
----------------          ,         --------------------
   ,          String      :false
   ,                  :true

원형 구체 적 실현: 깊이 복제 실현
package com.wenniuwuren.prototype;

import java.io.IOException;

/**
 *     
 * 
 * @author wenniuwuren
 *
 */
public interface FruitPrototype {
	//     
	public abstract FruitPrototype shallowClone()
			throws CloneNotSupportedException;

	//     
	public FruitPrototype deepClone() throws IOException, ClassNotFoundException;
}

원형 관리 클래스: 변 하지 않 음
package com.wenniuwuren.prototype;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

/**
 *       
 * @author wenniuwuren
 *
 */
//    --        ,          
public class ConcteteFruitPrototype implements FruitPrototype, Cloneable, Serializable{  
	
	private static final long serialVersionUID = 508114335347191627L;
	
	private String size;  
    private String color;  
	private Vitamins vitamins;
    
    public ConcteteFruitPrototype(String size, String color, Vitamins vitamins) {  
        this.size = size;  
        this.color = color;  
        this.vitamins = vitamins;
    }  
    
    //    
    public FruitPrototype shallowClone() throws CloneNotSupportedException  {  
        return (FruitPrototype) super.clone();  
    } 
    
    //    
    @Override
	public FruitPrototype deepClone() throws IOException, ClassNotFoundException {
    	//         
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(this);
        //        
        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bis);
        return (FruitPrototype)ois.readObject();
	}
    
    //     
    public void display(String colorname) {  
        System.out.println(colorname+"    : "+size+"    :"+color);  
    }

    
	public Vitamins getVitamins() {
		return vitamins;
	}

	public void setVitamins(Vitamins vitamins) {
		this.vitamins = vitamins;
	}  
	
	public String getSize() {
		return size;
	}

	public void setSize(String size) {
		this.size = size;
	}

	public String getColor() {
		return color;
	}

	public void setColor(String color) {
		this.color = color;
	}

	
}  
  

비타민 류: 직렬 화 에 주의 하 세 요.
package com.wenniuwuren.prototype;

import java.util.HashMap;
/**
 *      
 * @author wenniuwuren
 *
 */
public class FruitTool {
	private HashMap<String, FruitPrototype> fruits = new HashMap<String, FruitPrototype>();

	public void put(String key, FruitPrototype fruitPrototype) {
		fruits.put(key, fruitPrototype);
	}

	public FruitPrototype get(String key) {
		return fruits.get(key);
	}
}

테스트 클래스: 
package com.wenniuwuren.prototype;

import java.io.Serializable;

/**
 *           
 * @author wenniuwuren
 *
 */
//     --        ,          
public class Vitamins implements Serializable{
    
	private static final long serialVersionUID = 1183447243521084226L;
	
	private Boolean isContainsVitaminA;

	public Boolean getIsContainsVitaminA() {
		return isContainsVitaminA;
	}

	public void setIsContainsVitaminA(Boolean isContainsVitaminA) {
		this.isContainsVitaminA = isContainsVitaminA;
	}

}

테스트 결과: 
package com.wenniuwuren.prototype;

import java.io.IOException;

public class Client {
	public static void main(String[] args) throws CloneNotSupportedException, ClassNotFoundException, IOException {
		
		FruitTool fruitTool = new FruitTool();

		//            
		fruitTool.put("Apple", new ConcteteFruitPrototype("Middle", "Green", new Vitamins()));
		fruitTool.put("Watermelon", new ConcteteFruitPrototype("Large", "Red", new Vitamins()));
		fruitTool.put("Lemon", new ConcteteFruitPrototype("Small", "Yellow", new Vitamins()));

		
		System.out.println("#######################     ########################");
		String fruitName = "Apple";
		ConcteteFruitPrototype concteteFruitPrototype1 = (ConcteteFruitPrototype) fruitTool
				.get(fruitName).shallowClone();
		concteteFruitPrototype1.display(fruitName);
		
		System.out.print("   ,           String      :"  );
		System.out.println(concteteFruitPrototype1.getColor().equals(((ConcteteFruitPrototype)fruitTool
				.get(fruitName)).getColor()));
		
		System.out.print("   ,                  :"  );
		System.out.println(concteteFruitPrototype1.getVitamins().getIsContainsVitaminA() == ((ConcteteFruitPrototype)fruitTool
		.get(fruitName)).getVitamins().getIsContainsVitaminA());
		
		System.out.println("----------------          ,         --------------------");
	
		concteteFruitPrototype1.setColor("Red");
		System.out.print("   ,          String      :");
		System.out.println(concteteFruitPrototype1.getColor().equals(((ConcteteFruitPrototype)fruitTool
				.get(fruitName)).getColor()));
		
		concteteFruitPrototype1.getVitamins().setIsContainsVitaminA(Boolean.FALSE);
		System.out.print("   ,                  :"  );
		System.out.println(concteteFruitPrototype1.getVitamins().getIsContainsVitaminA() == ((ConcteteFruitPrototype)fruitTool
		.get(fruitName)).getVitamins().getIsContainsVitaminA());
		
		System.out.println("#######################     ########################");
		fruitName = "Watermelon";
		ConcteteFruitPrototype concteteFruitPrototype2 = (ConcteteFruitPrototype) fruitTool
				.get(fruitName).deepClone();
		concteteFruitPrototype2.display(fruitName);
		
		System.out.print("   ,           String      :"  );
		System.out.println(concteteFruitPrototype2.getColor().equals(((ConcteteFruitPrototype)fruitTool
				.get(fruitName)).getColor()));
		
		System.out.print("   ,                  :"  );
		System.out.println(concteteFruitPrototype2.getVitamins().getIsContainsVitaminA() == ((ConcteteFruitPrototype)fruitTool
		.get(fruitName)).getVitamins().getIsContainsVitaminA());
		
		System.out.println("----------------          ,         --------------------");
	
		concteteFruitPrototype2.setColor("Yellow");
		System.out.print("   ,          String      :");
		System.out.println(concteteFruitPrototype2.getColor().equals(((ConcteteFruitPrototype)fruitTool
				.get(fruitName)).getColor()));
		
		concteteFruitPrototype2.getVitamins().setIsContainsVitaminA(Boolean.FALSE);
		System.out.print("   ,                  :"  );
		System.out.println(concteteFruitPrototype2.getVitamins().getIsContainsVitaminA() == ((ConcteteFruitPrototype)fruitTool
		.get(fruitName)).getVitamins().getIsContainsVitaminA());
	}
}

깊이 복제 와 얕 은 복제 의
가장 큰 차 이 는 깊이 복제 가 대상 을 인용 하여 한 부 복제 한 것 이다.따라서 결과 에서 인용 내 데 이 터 를 수정 하면 인용 데이터 의 앞 뒤 가 일치 하지 않 습 니 다.
이로써 디자인 모델 시리즈 의 창설 형 모델 은 끝났다. 그 다음 해 는 일이 바 빠 서 소스 코드 를 바 꿔 야 한다. 시간 이 많 지 않 기 때문에 가능 한 한 시간 을 쪼 개 서 다른 모델 을 써 야 한다. 박 우 들 이 의견 을 많이 제시 하여 필자 가 블 로그 의 질 을 향상 시 키 는 데 도움 이 되 기 를 바란다.(잘 자, 세상 사랑 해)

좋은 웹페이지 즐겨찾기