Prototype패턴
인스턴스를 만들때 new연산자를 쓰는게 아니라 어떤 인스턴스로부터 인스턴스를 만드는 패턴입니다.
framework패키지의 Product 클래스
package framework;
public interface Product extends Cloneable{//Cloneable인터페이스를 상속받아야 clone메소드 사용 가능
public abstract void use(String s);
public abstract Product createClone();//복사본을 만드는 메소드
}
framework패키지의 Manage클래스
package framework;
import java.util.HashMap;
public class Manager {
/**
* @uml.property name="showcase"
* @uml.associationEnd qualifier="protoname:java.lang.String framework.Product"
*/
private HashMap showcase = new HashMap();//해쉬테이블을 만들고
public void register(String name, Product proto){
showcase.put(name, proto);//name을 index로 두고 내용물은 proto로 둔다
}
public Product create(String protoname){//index를 주면 내용물을 불러올수 있게함
Product p = (Product)showcase.get(protoname);
return p.createClone();//내용물은 복사본으로 결국 여기서 new를 해서 인스턴스를 만드는 효과가 일어난다
}
}
익명패키지의 MessageBox클래스
import framework.Product;
//*******
//*hello*
//*******
//로 모양 꾸미는 클래스
public class MessageBox implements Product{
/**
* @uml.property name="decochar"
*/
private char decochar;
public MessageBox(char decochar){
this.decochar = decochar;
}
@Override//자기자신을 복제하는 메소드
public Product createClone() {
// TODO Auto-generated method stub
Product p = null;
try{//예외가 발생할 수도 있어서 씀
p = (Product)clone();//clone메소드로 복사가능한것은 Cloneable 인터페이스를 구현하고 있는 클래스뿐
//즉 Product클래스만 복사가능 shallow copy를 함
}catch(CloneNotSupportedException e){
e.printStackTrace();
}
return p;
}
@Override
public void use(String s) {
// TODO Auto-generated method stub
int length = s.getBytes().length;//스트링의 길이를 바이트 단위로 읽음
for(int i = 0; i < length + 4; i++){//************부분
System.out.print(decochar);
}
System.out.println("");
System.out.println(decochar + "" + s + "" + decochar);//*hello*부분
//***********부분
for(int i = 0; i < length + 4; i++){
System.out.print(decochar);
}
System.out.println("");
}
}
익명패키지의 UnderlinePen클래스
import framework.Product;
//"hello"
//~~~~~~~
//로 꾸미는 클래스
public class UnderlinePen implements Product{
/**
* @uml.property name="ulchar"
*/
private char ulchar;
public UnderlinePen(char ulchar){
this.ulchar = ulchar;
}
@Override
public Product createClone() {
// TODO Auto-generated method stub
Product p = null;
try{//예외가 발생할 수도있어서 써줌
p = (Product)clone();//마찬가지로 자기자신의 복제를 생성하는 메소드 shallow copy를 함
}catch(CloneNotSupportedException e){
e.printStackTrace();
}
return p;
}
@Override
public void use(String s) {
// TODO Auto-generated method stub
int length = s.getBytes().length;//바이트 단위로 읽어옴
System.out.println("\"" + s + "\"");//"hello"부분
System.out.print("");
//~~~~~~~부분
for(int i = 0; i < length; i++){
System.out.print(ulchar);
}
System.out.println("");
}
}
익명패키지의 Main클래스
import framework.Manager;
import framework.Product;
public class Main {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//준비
Manager manager = new Manager();
UnderlinePen upen = new UnderlinePen('~');
MessageBox mbox = new MessageBox('*');
MessageBox sbox = new MessageBox('/');
manager.register("strong message", upen);
manager.register("warning box", mbox);
manager.register("slash box", sbox);
//생성
Product p1 = manager.create("strong message");//결국 new와 같은 효과가 일어나게됨
p1.use("Hello, world.");
Product p2 = manager.create("warning box");
p2.use("Hello, world.");
Product p3 = manager.create("slash box");
p3.use("Hello, world.");
}
}
왜 new로 안하고 이렇게 할까?
1. 종류가 너무 많아서 클래스로 정리할 수 없는 경우
예제에서는 ~을 사용 *을 사용 /을 사용 3개지만 많아지면 여러개의 클래스를 만들어야합니다. 그 불편함을 줄이기 위해서 이 패턴을 씁니다.
2. 클래스로부터 인스턴스 생성이 어려운 경우
이 예제에서는 실감이 안나지만 사용자가 포토샵으로 어떤 도형을 복사하고싶다면 처음부터 생성해서 똑같이 그리는 것보다 그냥 단순히 그 도형을 복사하는 것이 빠를 것입니다.
3. framework와 생성하는 인스턴스를 분리하고 싶은 경우
일종의 new Something이라는 인스턴스 생성방법에서 클래스를 써야한다는 점을 벗어나기 위해서 입니다. 즉 예제를 보면 strong message같은 것으로 인스턴스를 생성한 점입니다.
마지막 3번의 경우 객체지향프로그래밍에 해당하는 것입니다. 항상 클래스 이름을 써야된다는 점에 구속된다면 재사용면에서 보면 안좋을 수 밖에 없습니다. 그래서 이런식으로 클래스명에 구애받지 않게 인스턴스를 생성하는 것이 좋습니다.
'프로그래밍 > 자바 디자인패턴' 카테고리의 다른 글
디자인 패턴 Memento 패턴 (0) | 2012.08.13 |
---|---|
디자인패턴 Observer 패턴 (0) | 2012.08.10 |
디자인패턴 Mediator 패턴 (0) | 2012.08.09 |
디자인패턴 Facade 패턴 (0) | 2012.08.06 |
디자인 패턴 singleton 패턴 (0) | 2012.08.03 |
디자인 패턴 Factory Method 패턴 (0) | 2012.08.03 |
디자인 패턴 Template Method 패턴 (0) | 2012.08.03 |
디자인 패턴 위임에 의한 Adapter 패턴(인스턴스를 이용한) (0) | 2012.08.03 |