中身と装飾を同一視して、重ねて装飾を追加していく。
Decoratorとは装飾者のことで、ケーキのデコレーションのように飾っていくこと。
ゲームで考えてみよう。
RPGでの武器に魔力が追加されたり、強さが+1とかに強化される状態を表現する。
Weapon.java 中身と装飾を同一視するための抽象クラス
public abstract class Weapon { public abstract String getName(); public final void disp() { System.out.println(getName()); } }
WeaponName.java 中身となる武器の名前。名前を指定してインスタンスを作成する。
public class WeaponName extends Weapon { private String name; public WeaponName(String name) { this.name = name; } public String getName() { return name; } }
Enhance.java 強化を表す抽象クラス
public abstract class Enhance extends Weapon { protected Weapon weapon; protected Enhance(Weapon weapon) { this.weapon = weapon; } }
MagicEnhance.java 魔法強化のクラス。強化する武器と魔法名を指定してインスタンスを作成する。
public class MagicEnhance extends Enhance { private String magicname; public MagicEnhance(Weapon weapon, String magicname) { super(weapon); this.magicname = magicname; } public String getName() { return magicname + " " + weapon.getName(); } }
PowerEnhance.java 強さ増加のクラス。強化する武器と増加量を指定してインスタンスを作成する。
public class PowerEnhance extends Enhance { private int power; public PowerEnhance(Weapon weapon, int power) { super(weapon); this.power = power; } public String getName() { return weapon.getName() + " +" + power; } }
Main.java テストプログラム
public class Main { public static void main(String[] args) { Weapon w1 = new WeaponName("Sword"); w1.disp(); Weapon w2 = new MagicEnhance( w1, "Fire" ); w2.disp(); Weapon w3 = new PowerEnhance( w2, 2 ); w3.disp(); Weapon w4 = new MagicEnhance( new PowerEnhance( new WeaponName("Shield"), 1 ), "Cold" ); w4.disp(); } }
実行結果
Sword Fire Sword Fire Sword +2 Cold Shield +1
Weaponクラスを継承して作られているので、中身もいろんな強化も同一視できるので、どんどん強化を重ねていくことができる。まあ、このサンプルはただ文字をつなげていくだけだから、Fire Coldとか、+2 +3とか変な名前のものもできてしまうけど。
参考文献:Java言語で学ぶデザインパターン入門
参考:
ギコ猫とDecoratorパターン
Decorator パターン - Wikipedia