본문 바로가기

Coding Note

[Design pattern] Decorator

Decorator pattern : 기존에 존재하는 오브젝트에 필요한 사항을 하나하나 데코레이션 하는 패턴. 실행시간에 필요한 기능을 하나하나 붙여나가는 방식이다.


데코레이션이 의미하듯 오브젝트에 필요한 기능을 하나하나 붙여나간다. 데코레이션이 심하면 부담스럽듯, Decoration이 많아지면 실행중에 비용이 많이들게된다. 하지만 이 패턴의 적용으로 코드의 변경이 적어지며 클래스의 확장성이 커지기 때문에 객체지향적 관점에서 본다면 이만한 패턴이 없다.


Decorator는 기존 오브젝트에 데코를 달아주는 역할을 한다. 동일한 클래스를 상속하며 동일한 클래스로 구현하는 클래스이다(응?)



Decorator pattern을 적용할 곳은 다양하다. 런타임에 성질이 변경될 여지가 있는곳이라면 어디든 적용된다.

마법사가 새로운 원소를 접할수록 공격의 형태가 달라진다고 하면, 이 상황은 Decorator pattern으로 표현할 수 있다.


/* Elemental.java */

public interface Elemental {

public float getEffect();

}


/* Normal.java */
public class Normal implements Elemental {
private float effectPoint;

public Normal(){
effectPoint = 0;
}

@Override
public float getEffect() {
return effectPoint;
}
}

/* SpecialElemental.java */
public abstract class SpecialElemental implements Elemental {
protected Elemental elemental;

public SpecialElemental(Elemental elemental){
this.elemental = elemental;
}
}

/* IceElemental.java */
public class IceElemental extends SpecialElemental {

public IceElemental(Elemental elemental){
super(elemental);
}

@Override
public float getEffect() {
return elemental.getEffect() + 10; //additional effect point
}
}

/* FireElemental.java */
public class FireElemental extends SpecialElemental {

public FireElemental(Elemental elemental){
super(elemental);
}

@Override
public float getEffect() {
return elemental.getEffect() + 20;  //additional effect point
}
}

/* Character.java */
public class Character {
private float attackPoint;
private Elemental elemental;

public Character(){
attackPoint = 10;
elemental = new Normal();
}
public Character(float attackPoint, Elemental elemental){
this.attackPoint = attackPoint;
this.elemental = elemental;
}

public Elemental getElemental(){ return elemental; }
public void setElemental(Elemental elemental){
this.elemental = elemental;
}

public float attack(){
return attackPoint + elemental.getEffect();
}
}


/* main */

public static void main(String[] args){

Character character = new Character();

System.out.println("attack : " + character.attack());


character.setElemental(new IceElemental(character.getElemental()));

System.out.println("attack : " + character.attack());


character.setElemental(new FireElemental(character.getElemental()));

System.out.println("attack : " + character.attack());

}


물론 게임에서 이런 패턴은 별로 좋진 않지만,, 상황극 ㅎ;;


한줄요약 : 꾸밀수있다는건 언제든 변신이 가능하다는 뜻. 하지만 너무 꾸미면 부담스러워진다.

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

[Design pattern] Flyweight  (3) 2013.03.05
[Design pattern] Facade  (0) 2013.03.04
[Design pattern] Composite  (0) 2013.03.03
[Design pattern] Bridge  (0) 2013.02.20
[Design pattern] Adapter  (0) 2013.02.20