クラス継承とは対照的に、別のクラスのコンストラクター注入を使用してデコレーター クラスを作成することの違いについて、誰かが説明してもらえますか? 私が考えることができる例では、2 つの方法のいずれかで同じ最終目標を達成する可能性がありますが、根本的な何かが欠けているのではないかと思います。
3 に答える
デコレータ パターンは、オブジェクトの構成に関係します。そのオブジェクトの型を継承できるようにするには、明らかに継承可能でなければなりません。すべての型が継承用に設計されているわけではありません。つまり、純粋に技術的な観点から継承できる場合でも、基本クラスとして設計されているわけではありません(これは設計上の欠陥と見なされます)。
デコレーター パターンの存在理由は、オブジェクト自体を変更せずにオブジェクトの動作を変更できるようにすることです。継承することで、本質的にオブジェクト自体を変更することになり、ポリモーフィズムによる定期的な動作の変更が得られます。つまり、同じことを達成していないということです。
したがって、装飾と継承の両方に用途があります。これらのいずれかに該当する場合は装飾を使用してください
- 継承できません (たとえば、クラスが
sealed
C# の場合) - 継承すべきではありません (クラスは明らかに基底クラスを意図したものではありません)
- 1 つの特定のオブジェクトの動作を何度も変更したい (異なる動作のデコレータでラップすることにより)
継承は、OO ツールボックスにある最も強力なツールであることに注意してください。大きな力には大きな責任が伴いますが、これに対処するのは必ずしも容易ではありません。私は言います:常に構成または集約します。それができない場合は、継承します。継承できない場合は、構成または集約をより難しくしてください。」
装飾するもう1つの本当に良い理由は、クラスの代わりにインターフェイスを装飾するオプションを提供することです。次に、非常に緩く結合され、コードを追加せずに、インターフェイスの複数の実装に直交装飾動作を追加できます。
次のように再開します。
いつ継承する必要がありますか?
オブジェクトが同じセマンティック階層に属し、 is-a関係を表す場合。
それはどう言う意味ですか?
その a Cat
is-a Feline
、実際に a Feline
is-a Vertebrate
など。
いつ飾る?
オブジェクトがis-a関係を表していない場合。しかし、はい、両方ともCoffee
同じMilk
階層にある可能性があります。しかし、あなたが売るCappuccino
なら、あなたはコーヒーがミルクであるとは言わず、代わりにMilk
.
結論:
Is-aはhas- aとは異なります。1 つはサブタイプで、もう合成の一部です。
しかし、これを参照してください: https://stackoverflow.com/questions/1621344/head-first-design-patterns-decorator-pattern
実際の例では、ACL チェックを行うために、コントローラまたはサービスのデコレータとしてセキュリティ コンテナを作成します。