🛠Decoratorパターンは服を着せていくイメージ Decoratorパターンとストラテジとの違いはガッツ(肝)とスキン(皮膚)の違い 再帰的なパターン結合
Javaと.NET FrameworkのI/O Streams実装は、デコレーター・パターンを取り入れている。
Adapterはインターフェースの互換性を、Decoratorは動的な責務追加を、Strategyはアルゴリズムの柔軟な切り替えをそれぞれサポートします。
これは分かりやすい
これならわかる、サンプルもぜひ見よう
function run() {
var user = new User("Kelly");
user.say();
var decorated = new DecoratedUser(user, "Broadway", "New York");
decorated.say();
log.show();
}
ソースを見るだけで何をしているものかはわかりやすい。デコレーターという名前も被せてる感じが非常に分かりやすい。
GoFでのデコレーターの役割はデコレートするレイヤーのような機能に注目する。まるで「どてら」のように重ね着をしてデコレーションするわけだが、透明なプレートとしてイメージしているようだ。GUIだけでなく、ストリームの例も説明している。Javaのことしか知らないが、なんたらバッファードはデコレータの好例ということになる。
こっちのほうかな
次の奥義はストラテジになるが、以下の文章が不気味に響き渡る。
ガッツ(臓物)を変えたけりゃ、ストラテジを使えとなる
Decorator パターンは、既存のオブジェクトに動的に新しい責任や機能を追加するためのデザインパターンです。このパターンは、サブクラス化を使用することなく、オブジェクトの機能を拡張するために使用されます。Decorator パターンの鍵となる点は、同じ基本インターフェースまたは抽象クラスを継承または実装することによって、オブジェクトをラップする「デコレータ」として動作するクラスを定義することです。
再帰的な結合とは、Decorator パターンの特徴的な構造であり、デコレータが別のデコレータや基本のコンポーネントをラップできることを意味します。これにより、複数のデコレータを連鎖的に組み合わせることで、動的にオブジェクトの振る舞いや責任をカスタマイズすることができます。
例:
考えてみてください:あるビデオストリーミングサービスにて、基本的なビデオ再生機能があります。これが基本的なコンポーネントです。
しかし、以下のような追加機能を持つデコレータがあります:
AdDecorator: ビデオの前に広告を追加します。
SubtitleDecorator: ビデオに字幕を追加します。
WatermarkDecorator: ビデオに透かしを追加します。
これらのデコレータを使用して、基本のビデオ再生機能に上記の追加機能を動的に組み込むことができます。さらに、これらのデコレータを再帰的に組み合わせることで、複数の機能を組み合わせたビデオ再生体験を作成することができます。
例えば、広告付きで字幕が表示されるビデオを作成する場合、AdDecorator でビデオをラップし、次にその結果を SubtitleDecorator でラップします。このように、再帰的な結合を使用して、必要な機能の組み合わせを簡単に構築することができます。
このアプローチのメリットは、異なる機能の組み合わせを柔軟に作成できること、また新しい機能を追加する際に既存のコードを変更することなくデコレータとして追加できることです。
Dot
digraph DecoratorPattern {
node [shape=record]
Component [label="{Component|+operation(): void}"]
ConcreteComponent [label="{ConcreteComponent|+operation(): void}"]
Decorator [label="{Decorator|+operation(): void\n+addedBehavior(): void}"]
ConcreteDecoratorA [label="{ConcreteDecoratorA|+operation(): void\n+addedBehavior(): void}"]
ConcreteDecoratorB [label="{ConcreteDecoratorB|+operation(): void\n+addedBehavior(): void}"]
Component -> ConcreteComponent [arrowhead="none"]
Component -> Decorator [arrowhead="none"]
Decorator -> ConcreteDecoratorA [arrowhead="none"]
Decorator -> ConcreteDecoratorB [arrowhead="none"]
Decorator -> Component [label="decorates" dir="back"]
{rank=same; ConcreteDecoratorA ConcreteDecoratorB}
}
お願い致します