web-dev-qa-db-ja.com

実際にDecoratorパターンは実際にどのように使用されていますか?

私は、Decoratorパターンを実装する方法を完全に理解しています。また、その意図が何であるかも理解しています。

デコレータは、次の2つのケースのいずれかで使用されます。

サブクラス化の代替として-オブジェクトが持つことができる複数の特性がある場合、継承を使用して、可能なすべての組み合わせのサブクラスを作成できます。たとえば、3つの特性A、B、およびCは、A、B、C、ABC、AB、AC、BCという多くのクラスになります。これは「階級爆発」をもたらします。デコレータを使用すると、3つのデコレータA、B、C、およびクラスDで「装飾」することができます-それだけです。

実行時にオブジェクトの機能を拡張する方法として-実行時にオブジェクトを「ラップ」するデコレータを決定できるため、オブジェクトを動的に「カスタマイズ」できます。

これは、Decoratorが何であるかを理解していることを示すためだけのものでした(実装方法も完全に理解しています)。 今私の質問:

私は、Decoratorをいつどのように使用するかの理論的な例に精通しています。そして、ご覧のとおり、私はそれが何を意図しているのかを知っています。しかし、これを実際に実際のアプリケーションでいつ使用するかはまだわかりません。 「サブクラス化の代替として使用されている」または「オブジェクトに機能を動的に追加するために使用されている」と言っても、私はその意図に精通しているため、役に立ちません。

また、「たとえば、UIウィンドウについて考えてみてください。境界線があるかどうか、サイズが変更できるかどうかはわかりません」と言っても役に立たないので、これらの理論的な例はすでに知っています。

だから私が求めているのは、実用的な現実のシナリオでの具体的な現実の世界Decoratorの例です、 他の手法よりもデコレータパターンを使用する利点の簡単な説明。


明確にするために、Decoratorが使用されているアプリケーションのリストを探しているのではありません。デコレータがデザインでどこでどのように使用されたのか、なぜそれが優れたデザイン選択であったのか、そしてそれが解決した具体的な問題の例を探しています。具体的な問題Decoratorで解決しました。うまくいけば、もっとよく理解できるでしょう。

8
Aviv Cohn

これは基本的に質問に対するコメントでkdgregoryによって回答されましたが...

ストリームは、互いに独立して複数の属性を追加することでメリットを得られるものです。ストリームにアプリケーションデータの大きなダンプが必要です。すごい。暗号化もしたいです。ああ、この場合、私もそれを圧縮したいです。この特定のクライアントから、彼らが使用する改行のスタイルも変更したいと考えています。

これは、あなたの質問が言及するサブクラス化の代替の例です。 LineBreakFixingEncryptingZippingStream(3つの動作すべてを継承することができないため、すでにLineBreakFixingStream、EncryptingStream、およびZippingStreamがある場合はコードの重複につながる)ではなく、ストリームインターフェイスを共有するクラスの構成を使用できます。

そのため、LineBreakFixingStreamはBoringStreamを修飾し、BoringStreamから読み取り、その読み取りをLineBreakFixingStreamの呼び出し元に転送することによって実装されますが、改行は変更されません。次に、anyストリームを修飾できるEncryptingStreamは、この場合はBoringStreamを修飾するLineBreakFixingStreamのインスタンスを修飾できます。次に、ZippingStreamはそのEncryptingStreamを装飾できます。ストリームクラスの任意の組み合わせは、実行時にも必要に応じて非常に簡単に組み合わせることができます(ただし、私の例にはありませんが、クライアントがAPIを呼び出して、それらを1つの可能なものとしてまとめるシナリオを想像できます。ランタイム構成を使用する世界のシナリオ)。

これは目的についてはまだ抽象的なものですが、実際のシナリオです。以前に実際のアプリケーションでストリームを構成しました。圧縮と暗号化は頻繁に行われ、クライアントデータストリームのカスタムフォーマットを少し行うことも一般的です。

8
psr