web-dev-qa-db-ja.com

複合パターンとデコレータパターンの違いは何ですか?

複合パターンとデコレータパターンの違いは何ですか?

51
coder

彼らは通常、手をつないで行きます。複合パターンを使用すると、デコレータパターンも使用されることがよくあります。

複合パターンを使用すると、外部コードで構造全体を単一のエンティティとして表示できるように、階層構造(要素のツリーなど)を構築できます。したがって、リーフエンティティへのインターフェイスは、複合エンティティのエンティティとまったく同じです。したがって、本質は、複合構造のすべての要素が同じインターフェースを持っているということです。ただし、いくつかはリーフノードで、他は完全な構造です。ユーザーインターフェイスでは、このアプローチを使用して、簡単に構成できるようにすることがよくあります。

http://en.wikipedia.org/wiki/Composite_pattern

デコレータパターンを使用すると、エンティティに別のエンティティを完全に含めることができるため、デコレータを使用すると、含まれているエンティティと同じように見えます。これにより、デコレータはエンティティの外観を変更せずに、カプセル化しているものの動作やコンテンツを変更できます。たとえば、デコレータを使用して、含まれている要素の動作を変更せずに、含まれている要素の使用状況に関するログ出力を追加できます。

http://en.wikipedia.org/wiki/Decorator_pattern

42
Phil Wright

compositeパターンとdecoratorの構造は同じに見えますが、意図は異なります。

Compositeは、リーフとコンポジットに統一されたインターフェースを提供します。

Decoratorデコレータはリーフに追加機能を提供する一方で、統一されたインターフェースを提供します。


複合パターン:クラシックなWindowsフォルダーとファイル。 Windowsフォルダーはコンポジットです。ファイルは葉です。それらのいずれかをダブルクリックすると、ファイル/フォルダーが開きます-ダブルクリックは統一されたインターフェースです。

Decorator pattern:Buffered io-_Java.io.FileWriter_と_Java.io.BufferedWriter_はどちらも_Java.io.Writer_を拡張します。 _Java.io.BufferedWriter_は複合であり、FileWriterはリーフです。 BufferedWriterは、バッファリングの追加の責任(または機能)をFileWriterに追加します。 write()メソッドは統一されたインターフェースですが、バッファリングは追加機能です。

40
Pavan

デコレータは、コンポーネントが1つしかない縮退したコンポジットと見なすことができます。ただし、デコレータは追加の責任を追加します。これはオブジェクトの集約を目的としたものではありません。

これは、「設計パターン-再利用可能なオブジェクト指向ソフトウェアの要素」で4人のギャングが言っていることです。

17
Ariel

違いはおそらく実装よりも目的のほうが多いでしょう。場合によっては、サブクラス化よりも複合パターンの方が適しています。たとえば、クラスに必要な機能を追加するには、クラスに他のクラスのインスタンスを追加し、転送インターフェースを介してその機能を公開します。

デコレーターを使用すると、クラスのインスタンスのクライアントがそこにデコレーターがあることを知る必要なく、機能(通常は単一の機能)をクラスに透過的に追加できます。たとえば、Djangoユーザーがログインしていない場合は例外が発生しますが、それ以外の場合、ビューはデコレータがない場合と同じように動作します。

どちらの場合も、1つのオブジェクトが別のオブジェクトに埋め込まれていますが、達成しようとしていることは間違いなく異なります。

5
Eric Walker

構造の違い

以下は、PlantUMLを使用して複製されたGoFブックのクラス図です。

GoF Decorator class diagram

GoF Composite class diagram

意図の違い

Decoratorの目的はsingleコンポーネントを装飾することです(UMLダイアグラムは実際には装飾されたコンポーネントに対して1の多重度を示す必要があります)、Compositeの目的はコンポーネント全体をCompositeにグループ化することです(この場合も、UMLは1つ以上コンポーネントを含むコンポジットを表示する必要があります)。

Decoratorは、ConcreteDecoratorsを介して動作(Operation()メソッドの動作を強化)を追加することを目的としていますが、Compositeはコンポーネントの収集を目的としています。

3
Fuhrmanator

Decorator パターンを使用して、同じクラスの他のインスタンスとは関係なく、特定のオブジェクトの機能を静的に、または場合によっては実行時に拡張(装飾)できます。

構成が原因である可能性があります。DecoratorはComponentを含み、同時にComponentインターフェースを実装します。

Composite パターンは、オブジェクトのグループがオブジェクトの単一のインスタンスと同じように扱われることを示しています。コンポジットの目的は、オブジェクトをツリー構造に「構成」して、部分全体の階層を表すことです。

複合パターンを実装すると、クライアントは個々のオブジェクトとコンポジションを均一に扱うことができます。

構造は同じように見えますが、意図とユースケースは異なります。

Decorator パターンの使用例:

  1. オブジェクトの責任と動作は動的に追加/削除する必要があります
  2. 具体的な実装は、責任と行動から切り離されるべきです
  3. サブクラス化はコストがかかりすぎて、責任を動的に追加/削除できません

Key differences これら2つのパターンの間:

  1. Decoratorは、サブクラス化せずにオブジェクトに責任を追加できるように設計されています。 Compositeの焦点は装飾ではなく表現にあります
  2. デコレーターは追加の責任を追加/削除します-これはオブジェクトの集約を目的としたものではありません。

理解を深めるためにSEで役立つ投稿:

IOのデコレータパターン

デコレータパターンを使用する場合?

1
Ravindra babu

複合:

  • 再帰を使用したツリー構造です。
  • リーフとコンポジットは同じインターフェースを持っています
  • オブジェクト間の統一

デコレーター:

  • 別のエンティティが含まれています。
  • 変更せずに複合オブジェクトに新しい機能を追加する。
0
Premraj