技術とか戦略とか

IT技術者が技術や戦略について書くブログです。

javaでのDecoratorパターン

Decoratorパターンは、その名の通りオブジェクトに次々とデコレート(飾りつけ)をし、機能を追加していくパターンです。
Compositeパターンと同じように再帰的なクラス構成とすることで、冗長性を排除します。
 
今回は、じゃんけんの手を作成するサンプルコードを作ってみました。
「グー」「チョキ」「パー」といった単純な手も作れますし、これらの手を作成するオブジェクトを何度も呼び出すことで「必殺グーチョキパー」のようなズルい手も作れる、というサンプルコードです。
 
【サンプルコード】
・Hands.java
// 手そのものを表すクラス
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
// 空の手を作るクラス
public class CreateEmptyHands extends Hands {

    public CreateEmptyHands() {
    }

    public CreateEmptyHands(Hands hands) {
        super(hands);
    }

    protected void decorateHands(Hands hands) {
        handsString = "";
    }

}
 
・DecorateHands.java
// 具体的な手を作成する時の共通処理を記述した抽象クラス
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
// 手にグーを追加するクラス
public class DecorateRock extends DecorateHands {

    public DecorateRock(Hands hands) {
        super(hands);
    }

    protected void addHands() {
        handsString = handsString + "グー";
    }

}
 
・DecorateScissors.java
// 手にチョキを追加するクラス
public class DecorateScissors extends DecorateHands {

    public DecorateScissors(Hands hands) {
        super(hands);
    }

    protected void addHands() {
        handsString = handsString + "チョキ";
    }

}
 
・DecoratePaper.java
// 手にパーを追加するクラス
public class DecoratePaper extends DecorateHands {

    public DecoratePaper(Hands hands) {
        super(hands);
    }

    protected void addHands() {
        handsString = handsString + "パー";
    }

}
 
・HandsMain.java
// メインクラス
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();

    }
}
 
【実行結果】
作成した手:
作成した手:グー
作成した手:必殺グーチョキパー
作成した手: