1概要

  • Decoratorパターンを使用すると、静的または動的にオブジェクトに追加の責任を割り当てることができます。** Decoratorは、元のオブジェクトに対する拡張インターフェースを提供します。

このパターンの実装では、継承よりも合成を優先します。これにより、装飾要素ごとに何度もサブクラス化のオーバーヘッドを削減できます。このデザインに含まれる再帰は、必要なだけオブジェクトを装飾するために使用できます。


2デコレータパターン例

クリスマスツリーのオブジェクトがあり、それを装飾したいとします。装飾はオブジェクト自体を変更しません。クリスマスツリーに加えて、ガーランド、見掛け倒し、ツリートッパー、バブルライトなどの装飾アイテムを追加するだけです

リンク:/uploads/8poz64T-768×349.jpg%20768w[]

  • このシナリオでは、元のGang of Fourのデザインと命名規則に従います** 最初に、

    ChristmasTree

    インターフェイスとその実装を作成します。

public interface ChristmasTree {
    String decorate();
}

このインターフェースの実装は次のようになります。

public class ChristmasTreeImpl implements ChristmasTree {

    @Override
    public String decorate() {
        return "Christmas tree";
    }
}

このツリーのために抽象的な

TreeDecorator

クラスを作成しましょう。このデコレータは

ChristmasTree

インターフェースを実装し、同じオブジェクトを保持します。同じインターフェースから実装されたメソッドは、インターフェースから

decorate()

メソッドを呼び出すだけです。

public abstract class TreeDecorator implements ChristmasTree {
    private ChristmasTree tree;

   //standard constructors
    @Override
    public String decorate() {
        return tree.decorate();
    }
}

それでは装飾要素を作りましょう。これらのデコレータは私たちの抽象的な

TreeDecorator

クラスを拡張し、私たちの要求に従ってその

decorate()

メソッドを修正します:

public class BubbleLights extends TreeDecorator {

    public BubbleLights(ChristmasTree tree) {
        super(tree);
    }

    public String decorate() {
        return super.decorate() + decorateWithBubbleLights();
    }

    private String decorateWithBubbleLights() {
        return " with Bubble Lights";
    }
}

この場合、以下が当てはまります。

@Test
public void whenDecoratorsInjectedAtRuntime__thenConfigSuccess() {
    ChristmasTree tree1 = new Garland(new ChristmasTreeImpl());
    assertEquals(tree1.decorate(),
      "Christmas tree with Garland");

    ChristmasTree tree2 = new BubbleLights(
      new Garland(new Garland(new ChristmasTreeImpl())));
    assertEquals(tree2.decorate(),
      "Christmas tree with Garland with Garland with Bubble Lights");
}

最初の

tree1

オブジェクトでは、1つの

Garland

のみでそれを装飾していますが、他の

tree2

オブジェクトは1つの

BubbleLights

と2つの

Garlands

で装飾しています。このパターンにより、実行時に必要なだけデコレータを追加することができます。


4結論

この記事では、デコレータのデザインパターンを見ました。これは、次のような場合に適しています。

  • の動作や状態を追加、強化、削除したい場合

オブジェクト
** 単一のオブジェクトの機能を変更したいだけの場合

クラスにして他の人を変えない

この例の完全なソースコードはhttps://github.com/eugenp/tutorials/tree/master/patterns/design-patterns[GitHubで利用可能]です。