개발
home
🍰

[디자인 패턴] 데코레이터 패턴

Created
2022/03/27
Tags
Design Pattern
Decorator Pattern
Java
2022-03-27

데코레이터 패턴

데코레이터 패턴은 주어진 상황 및 용도에 따라 어떤 객체에 책임을 덧붙이는 패턴입니다.

롤 챔피언과 아이템 예제

롤 챔피언 (아리, 카이사)가 상점에서 아이템 (도란의 반지, 메자이, 마나무네)을 사는 예제입니다.
챔피언들은 어떤 아이템이든 순서와 상관없이 장착할 수 있습니다. 즉, 챔피언들은 아이템을 유연하게, 동적으로 장착할 수 있습니다.
아이템은 롤 챔피언을 변수로 가지고 있고, 장착하는 순간 해당 챔피언의 물리 공격력과 마법 공격력을 올려줍니다.

롤 챔피언과 아이템 예제 구현

롤 챔피언 인터페이스를 만듭니다.
public interface LolChampion { public int getAttackDamage(); public int getAbilityPower(); public String getName(); }
Java
복사
롤 챔피언 인터페이스를 구현하여 아리와 카이사 챔피언을 구현합니다.
public class Kaisa implements LolChampion { private int attackDamage = 32; private int abilityPower = 30; public Kaisa() { } @Override public int getAttackDamage() { return attackDamage; } @Override public int getAbilityPower() { return abilityPower; } @Override public String getName() { return "Kaisa"; } }
Java
복사
아리 구현체입니다.
public class Ahri implements LolChampion { private int attackDamage = 30; private int abilityPower = 34; public Ahri() { } @Override public int getAttackDamage() { return attackDamage; } @Override public int getAbilityPower() { return abilityPower; } @Override public String getName() { return "Ahri"; } }
Java
복사
롤 아이템 인터페이스를 만듭니다. 롤 아이템은 롤 챔피언을 인스턴스 변수로 가집니다. abstract class로 만들어 생성자까지 선언하겠습니다.
롤 아이템으로 만든 객체를 다시 롤 챔피언에게 반환하기 위해서 롤 아이템도 롤 챔피언을 구현(implements) 받습니다. 이 내용은 아래에 호출하는 코드를 보면 이해가 더 빠릅니다.
public abstract class LolItem implements LolChampion { LolChampion lolChampion; public LolItem(LolChampion lolChampion) { this.lolChampion = lolChampion; } abstract public String getName(); }
Java
복사
롤 아이템을 구현합니다. 도란의 반지, 메자이, 마나무네 3개의 아이템을 구현해 만듭니다.
💍도란의 반지 구현 부분입니다.
public class DoranRing extends LolItem { private final int additionalAttackDamage = 0; private final int additionalAbilityPower = 15; public DoranRing(LolChampion lolChampion) { super(lolChampion); } @Override public int getAttackDamage() { return lolChampion.getAttackDamage() + additionalAttackDamage; } @Override public int getAbilityPower() { return lolChampion.getAbilityPower() + additionalAbilityPower; } @Override public String getName() { return lolChampion.getName() + " + 💍도란링"; } }
Java
복사
📚메자이 구현 부분입니다.
public class Mejai extends LolItem { private final int additionalAttackDamage = 0; private final int additionalAbilityPower = 20; public Mejai(LolChampion lolChampion) { super(lolChampion); } @Override public int getAttackDamage() { return lolChampion.getAttackDamage() + additionalAttackDamage; } @Override public int getAbilityPower() { return lolChampion.getAbilityPower() + additionalAbilityPower; } @Override public String getName() { return lolChampion.getName() + " + 📚메자이"; } }
Java
복사
⚔️마나무네 구현 부분입니다.
public class Manamune extends LolItem { private final int additionalAttackDamage = 35; private final int additionalAbilityPower = 0; public Manamune(LolChampion lolChampion) { super(lolChampion); } @Override public int getAttackDamage() { return lolChampion.getAttackDamage() + additionalAttackDamage; } @Override public int getAbilityPower() { return lolChampion.getAbilityPower() + additionalAbilityPower; } @Override public String getName() { return lolChampion.getName() + " + 🗡마나무네"; } }
Java
복사

롤 챔피언과 아이템 호출

🦊 아리에게 도란의 반지와 메자이 아이템을 장착시킵니다.
그리고 🧙 카이사에게는 도란의 반지와 마나무네 아이템을 장착시킵니다.
챔피언들을 부모 클래스(여기에서는 LolChampion)으로 타입을 지정하였습니다. 아이템을 장착시킨 후에 해당 챔피언 인스턴스에게 다시 반환합니다. 이를 위해서 롤 아이템들을 롤 챔피언을 구현받도록 하였습니다.
public class DecoratorApplication { public static void main(String[] args) { // 🦊 아리 + 💍 도란링 + 📚 메자이 LolChampion ahri = new Ahri(); ahri = new DoranRing(ahri); ahri = new Mejai(ahri); System.out.println("👊 아리 물리 공격력 = " + ahri.getAttackDamage()); System.out.println("🪄 아리 마법 공격력 = " + ahri.getAbilityPower()); // 👊 아리 물리 공격력 = 30 // 🪄 아리 마법 공격력 = 69 // 🧙 카이사 + 💍 도란링 + ⚔️ 마나무네 LolChampion kaisa = new Kaisa(); kaisa = new DoranRing(kaisa); kaisa = new Manamune(kaisa); System.out.println("👊 카이사 물리 공격력 = " + kaisa.getAttackDamage()); System.out.println("🪄 카이사 마법 공격력 = " + kaisa.getAbilityPower()); // 👊 카이사 물리 공격력 = 67 // 🪄 카이사 마법 공격력 = 45 } }
Java
복사
코드는 깃허브에서도 확인할 수 있습니다.

Ref.

example inspired by. Tony