Decoratorパターンは、その名の通りオブジェクトに次々とデコレート(飾りつけ)をし、機能を追加していくパターンです。
Compositeパターンと同じように再帰的なクラス構成とすることで、冗長性を排除します。
今回は、じゃんけんの手を作成するサンプルコードを作ってみました。
「グー」「チョキ」「パー」といった単純な手も作れますし、これらの手を作成するオブジェクトを何度も呼び出すことで「必殺グーチョキパー」のようなズルい手も作れる、というサンプルコードです。
【サンプルコード】
・Hands.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
// 手そのものを表すクラス public abstract class Hands { public Hands() { } public Hands(Hands hands) { decorateHands(hands); } protected String handsString = ""; public void displayHands() { System.out.println("作成した手:" + handsString); } protected abstract void decorateHands(Hands hands); } |
・CreateEmptyHands.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// 空の手を作るクラス public class CreateEmptyHands extends Hands { public CreateEmptyHands() { } public CreateEmptyHands(Hands hands) { super(hands); } protected void decorateHands(Hands hands) { handsString = ""; } } |
・DecorateHands.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
// 具体的な手を作成する時の共通処理を記述した抽象クラス public abstract class DecorateHands extends Hands { public DecorateHands(Hands hands) { super(hands); } protected void decorateHands(Hands hands) { this.handsString = hands.handsString; addSpecialMoves(); addHands(); } protected void addSpecialMoves() { // 手を2つ以上くっつけた場合、頭に「必殺」を付ける if (!handsString.equals("") && !handsString.contains("必殺")) { handsString = "必殺" + handsString; } } protected abstract void addHands(); } |
・DecorateRock.java
1 2 3 4 5 6 7 8 9 10 11 12 |
// 手にグーを追加するクラス public class DecorateRock extends DecorateHands { public DecorateRock(Hands hands) { super(hands); } protected void addHands() { handsString = handsString + "グー"; } } |
・DecorateScissors.java
1 2 3 4 5 6 7 8 9 10 11 12 |
// 手にチョキを追加するクラス public class DecorateScissors extends DecorateHands { public DecorateScissors(Hands hands) { super(hands); } protected void addHands() { handsString = handsString + "チョキ"; } } |
・DecoratePaper.java
1 2 3 4 5 6 7 8 9 10 11 12 |
// 手にパーを追加するクラス public class DecoratePaper extends DecorateHands { public DecoratePaper(Hands hands) { super(hands); } protected void addHands() { handsString = handsString + "パー"; } } |
・HandsMain.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
// メインクラス public class HandsMain { public static void main(String[] args){ Hands hands1 = new CreateEmptyHands(); hands1.displayHands(); Hands hands2 = new DecorateRock(hands1); hands2.displayHands(); Hands hands3 = new DecoratePaper( new DecorateScissors(hands2)); hands3.displayHands(); Hands hands4 = new CreateEmptyHands(hands3); hands4.displayHands(); } } |
【実行結果】
1 2 3 4 |
作成した手: 作成した手:グー 作成した手:必殺グーチョキパー 作成した手: |
いかがでしたでしょうか?
Compositeパターンと似たような話ですが、Compositeパターンは構造を再帰的に表現するのに対し、今回のDecoratorパターンは機能を再帰的に表現します。
ディレクトリ構造を扱う等ではない場合、Decoratorパターンの方が出番は多いかもしれません。
紹介したいデザインパターンはあと5パターンぐらいあるので、皆さまもう少しお付き合いください。
では、また次回!
コメント