デコレーター パターンは、追加の動作をオブジェクトに動的に付加する構造設計パターンです。デコレータは、サブクラス化 (継承) ではなく合成によって柔軟な拡張理由を提供します。
実行時に小さな動作を追加してオブジェクトを構築したい場合は、Decorator パターンを使用します。
デコレータ クラスは合成と継承を使用するため、その意図を理解することが重要です。
Decorator パターンでは、コンポーネントとデコレータの両方に同じ型を使用します。 Decorator は Component オブジェクトを合成して動作を取得します。つまり、Component オブジェクトに定義されているフィールドまたはメソッドを取得します。 Decorator は Component を継承 (拡張) するため、Decorator オブジェクトを Component オブジェクトとして宣言できます。
デコレータ パターンは、オープン-クローズの原則、つまり、拡張のために開き、変更のために閉じられることを実現します。コンポーネントやデコレータを追加するのは簡単です。たとえば、別の具体的なデコレータを追加したい場合は、それを表すクラスを作成し、Decorator クラスを拡張するだけです。
アイスクリームショップ用のシステムを開発していると想像してください。店内には様々なアイスクリームやトッピングが揃っています。システムは、アイスクリームの説明 (トッピングを含む) と価格を表示する必要があります。
IceCream クラス:
// Component class public abstract class IceCream { public String description = "Unknown ice cream"; public String getDescription() { return description; } public abstract double cost(); }
チョコレートアイスクリームクラス:
// Concrete component class public class ChocolateIceCream extends IceCream { public ChocolateIceCream() { description = "ChocolateIceCream"; } @Override public double cost() { return 1.99; } }
トップクラス:
// Base decorator class public abstract class Topping extends IceCream { public IceCream iceCream; // All subclasses (concrete decorator classes) need to implement getDescription method, // by declaring this method as abstract, we enforce all subclasses to implement this method public abstract String getDescription(); }
MapleNuts クラス:
// Concrete decorator class public class MapleNuts extends Topping { public MapleNuts(IceCream iceCream) { this.iceCream = iceCream; } @Override public String getDescription() { return iceCream.getDescription() + ", MapleNuts"; } @Override public double cost() { return iceCream.cost() + .30; } }
PeanutButterShell クラス:
// Concrete decorator class public class PeanutButterShell extends Topping { public PeanutButterShell(IceCream iceCream) { this.iceCream = iceCream; } @Override public String getDescription() { return iceCream.getDescription() + ", PeanutButterShell"; } @Override public double cost() { return iceCream.cost() + .30; } }
クライアントクラス:
public class Client { public static void main(String[] args) { IceCream iceCream = new ChocolateIceCream(); System.out.println(iceCream.getDescription() + ", $" + iceCream.cost()); iceCream = new MapleNuts(iceCream); System.out.println(iceCream.getDescription() + ", $" + iceCream.cost()); iceCream = new PeanutButterShell(iceCream); System.out.println(iceCream.getDescription() + ", $" + iceCream.cost()); } }
出力:
ChocolateIceCream, .99 ChocolateIceCream, MapleNuts, .29 ChocolateIceCream, MapleNuts, PeanutButterShell, .59
ここですべてのデザインパターンの実装を確認できます。
GitHub リポジトリ
追記
技術ブログを書くのは初めてです。文章を改善するためのアドバイスや、わかりにくい点がある場合は、コメントを残してください。
読んでいただきありがとうございます:)
以上がデコレータパターンの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。