데코레이터(Decorator) 패턴이란?
- 전체 클래스나 하위 클래스를 수정하지 않고도 개별 개체에 동작이나 기능을 추가할 수 있도록 한다.
- 런타임에 개체의 기능을 동적으로 확장하는데 사용한다.
데코레이터 패턴의 장점
확장을 위한 개방
- 기존 코드를 수정하지 않고 객체의 동작을 동적으로 수정하고 확장할 수 있다.
단일 책임 원칙
- 객체의 책임을 각각 다른 데코레이터 객체로 분리하여 개체의 동작을 유연하게 관리할 수 있다.
상속보다 구성
- 부모 클래스에서 동작을 상속하는 대신 새로운 개체에 동작을 추가하기 때문에 유지보수 및 수정에 유연성이 생기고 확장하기 좋다.
간소화된 유지보수
- 기존의 개체를 수정하지 않고 데코레이터 개체를 사용하여 새로운 동작을 추가할 수 있기 때문에 기존 코드에 영향을 주지 않고 개체의 동작을 변경할 수 있다.
데코레이터 패턴의 단점
복잡성 증가
- 많은 수의 데코레이터가 사용되는 경우 코드를 이해하고 유지보수하는데 문제가 발생할 수 있다.
성능
- 데코레이터는 객체를 래핑(Wrapping)하여 생성하므로 데코레이터의 생성 및 관리에서 성능의 문제가 발생할 수 있다.
구현 예제
다음은 게임의 스킬 체인 시스템을 예로 들어 설명한 데코레이터 패턴의 구현 예제이다.
먼저 데코레이터 클래스를 정의한다.
// 캐릭터의 기본 인터페이스
public interface Character {
void attack();
int getHealth();
}
// 캐릭터, Charactor 인터페이스의 구현체
public class Player implements Charactor {
private int health = 100;
public void attack() {
System.out.println("Attack.");
}
public int getHealth() {
return health;
}
}
// Charactor 인터페이스를 정의하는 Decorator 추상 클래스
public abstract class CharacterDecorator implements Character {
protected Character character; // 데코레이터로 장식할 객체
public CharacterDecorator(Character character) {
this.character = character;
}
// 캐릭터의 공격 방법을 장식된 객체에 위임
public void attack() {
character.attack();
}
// 캐릭터의 getHealth() 메소드 또한 장식된 객체에 위임
public int getHealth() {
return character.getHealth();
}
}
// 캐스팅하는 마법을 추가하는 구체적인 데코레이터 클래스
public class MagicDecorator extends CharacterDecorator {
public MagicDecorator(Character character) {
super(character);
}
// 공격 방법을 재정의하여 마법 공격을 추가한다.
public void attack() {
character.attack();
System.out.println("Character casts a magic spell!");
}
}
// 화염 속성 공격을 추가하는 데코레이터 클래스
public class FireDecorator extends CharacterDecorator {
public FireDecorator(Character character) {
super(character);
}
// 공격 방법을 재정의하여 화염 속성을 추가한다.
public void attack() {
character.attack();
System.out.println("Character casts a magic with fire!");
}
}
다음은 플레이어를 생성하고 데코레이터를 추가하여 공격 방식을 변경하는 예제이다.
public static void main(String[] args) {
// 장식이 될 플레이어 객체 생성
Character player = new Player();
// 플레이어가 마법을 캐스팅하는 데코레이터 추가
Character magicCaster = new MagicDecorator(player);
// 플레이어의 마법에 화염 속성을 추가하는 데코레이터 추가
Character fireMagicCaster = new FireDecorator(magicCaster);
// 플레이어가 공격한다면
player.attack(); // 출력: Attack.
magicCaster.attack(); // 출력: Attack.\n Character casts a magic spell!
fireMagicCaster.attack(); // 출력: Attack.\n Character casts a magic spell!\n Character casts a magic with fire!
}
'공부합시다 > DesignPattern' 카테고리의 다른 글
[Design Pattern] 싱글톤(Singleton) 패턴 (0) | 2023.04.09 |
---|---|
[Design Pattern] 옵저버(Observer) 패턴 (0) | 2023.04.03 |
[Design Pattern] 스트래티지(Strategy) 패턴 (0) | 2023.04.02 |