본문 바로가기

Coding Note

[Design pattern] Prototype

Prototype Pattern : 미리 만들어진 인스턴스를 모체로 복제품을 만들어낸다. 제품이 생상되기 전에 프로토타입을 잘 만들어놔야한다. 그래야 프로토타입을 토대로 만들어진 제품도 잘 나오니깐

 

 

 

Prototype클래스는 클론의 추상 인터페이스만을 제공한다. 그리고 프로토타입 모델을 사용할 클래스에서 Prototype을 상속하여 클론을 재정의한다. 

그 후 클라이언트 클래스에서는 프로토타입을 하나 만든 후 변경사항은 프로토타입에 대해서만 관리하며 새로운 인스턴스가 필요하다면 프로토타입을 복제하여 주게된다.


팩토리와는 다르게 생성시마다 생성되는 인스턴스의 속성을 결정짓지 않고 미리 만들어둔 프로토타입만을 관리하면 그 복제품도 자연히 따라만들어지기 때문에 인스턴스의 생성 관리차원에서 효과적이다. 단지 속성의 차이만 있다면 클래스를 상속하여 새로운 클래스를 만들기 보다는 프로토타입을 정의하여 복제하는 방식이 코드를 더 깔끔하게 만든다.


Prototype pattern은 동일한 인터페이스를 가지는 클래스들끼리만 동일하게 처리할 수 있다. 단점이라기보다는 당연한 사실이다. 프로토타입이랑 프로토타입을 보고 만든 제품이랑 기능이 다르면 프로토타입의 존재의미가 사라지는꼴이다.


게임의 몬스터에 대해서 Prototype pattern을 적용하면 적당할것 같다. 몬스터는 계속 리젠되지만 몬스터마다 똑같은 속성값을 같는것은 아니다. 이럴때 하나의 몬스터종류에 대해서 생성가능한 몬스터 프로토타입을 여러개 만들어두어 필요할때 복제해가기만 하면 몬스터를 생성하면서 특별한 처리를 하지 않아도 손쉽게 여러종류의 몬스터를 생성할 수 있을것이다. 생성 가능한 몬스터의 프로토타입을 적절한 알고리즘에 의해 랜덤하게 선택하게 한다면 좋은 응용이 될 수 있다.


/* Prototype.java */

public interface Prototype {

public Prototype Clone();

}


/* Monster.java */
public class Monster implements Prototype {
private int minDamage;
private int maxDamage;
private String nameColor;

public Monster(){

}
public Monster(Monster monster){
minDamage = monster.minDamage;
maxDamage = monster.maxDamage;
nameColor = monster.nameColor;
}

public void setMinDamage(int minDamage){
this.minDamage = minDamage;
}

public void setMaxDamage(int maxDamage){
this.maxDamage = maxDamage;
}

public void setNameColor(String nameColor){
this.nameColor = nameColor;
}

@Override
public Prototype Clone() {
return new Monster(this);
}
}

/* MonsterRegenManager.java */
public class MonsterRegenManager {
private Monster normalMonPrototype;
private Monster magicMonPrototype;

public MonsterRegenManager(){
//default monster prototype
normalMonPrototype = new Monster();
normalMonPrototype.setMinDamage(0);
normalMonPrototype.setMaxDamage(100);
normalMonPrototype.setNameColor("white");

//magic monster prototype
magicMonPrototype = new Monster();
magicMonPrototype.setMinDamage(10);
magicMonPrototype.setMaxDamage(120);
magicMonPrototype.setNameColor("blue");
}

public Monster getMonster(String type){
if(type.equals("magic")){
return ((Monster)magicMonPrototype.Clone());
}
else if(type.equals("normal")){
return ((Monster)normalMonPrototype.Clone());
}
else{
return null;
}
}
}


한줄요약 : 적절한 롤 모델이 있다는것은 멋진일이다.

'Coding Note' 카테고리의 다른 글

[Design pattern] Command  (0) 2013.02.04
[Design pattern] Chain of Responsibliity  (1) 2013.02.02
[Design pattern] Builder  (0) 2013.01.31
[Design pattern] Singleton  (0) 2013.01.31
[Design pattern] Factory Method  (0) 2013.01.30