2017-04-22 11 views
7

"Head First:Design Patterns"ブックのデコレータパターンユースケースは私にこの質問をしました。私はそれを書き留めてみます:デコレータパターンの代わりにリストを使用しますか?

は、それはあなたが(余分なコストのために)それらに置くことができる いくつかのコーヒーや調味料の多いコーヒーショップシステムです、あなたは を注文できるようにする必要がありますし、 (例えば、 調味料を追跡するブーリアン)デコレータパターンが使用されていることを避けるためには、 を使用してください。

Beverage Class Diagram

だから、我々は次のプロセスはコーヒーの費用を返している:私たちは、抽象飲料 クラス、具体的な構成要素として、コーヒーや各調味料、このような飲料を包む などの具体的なデコレータ、それぞれのタイプを持っています:

Coffee Cost Delegation

私の質問は:なぜ、代わりにデコレータのリストでこれを実装していませんか?各飲料に調味料のリストを用意し、リストを繰り返してコストを計算することができます。以下のような宣言を避け、我々は一度だけ、それをインスタンス化し、必要な調味料を追加する必要がありますコーヒーを注文するには:それに加えて

// Using second image example 
Beverage beverage = new DarkRoast(beverage); 
beverage = new Mocha(beverage); 
beverage = new Whip(beverage); 

を我々はそれの調味料を含まないコーヒーのための割引を与えるような操作のためのより多くの柔軟性を持っているでしょうコーヒーを包み込むデコレータは一度もありません。これは長い間研究されてきた問題です。私は何かが欠落しているか、何か間違っていることを知っています。あなたがこれについて何か考えているなら、それをもっと知り、さらに議論することが大好きです。

+0

これは、減算するか、または追加する必要がある割引や税金のリストではありません。これは、デコレータパターンで処理している動作についてです。そして、私を信じて、継承の代わりにリストでその行動を扱うのは難しいです。 – freedev

+0

このケースを使用した例はありますか?あるいは、別のランダムなケースですか?私は本当にこれが起こる状況を想像することはできません。 – Paternostro

+4

これは[softwareengineering.stackexchange.com](https://softwareengineering.stackexchange.com)の方が良いようです。個人的には、それはデコレータのひどい使い方だと思います(ウィキペディアにもそのような例があります)、リストを使ってもっと管理しやすい方法で絶対に解決することができます。 'java.io.InputStream'は、うまく動作するDecoratorの例です。しかし、あなたはすでに私に同意しないユーザーがいることを知ることができます。だから、これはおそらくSOの話題ではありません。 – Radiodef

答えて

1

データと動作を区別する必要があります。

デコレータは、非常に特殊な問題を扱う間接的なレイヤーです。データ(型、契約、プロトコルなどの点で)は同じままですが、実装に関しては柔軟性があります。デコレータを使用すると、既存の機能を再利用して変更を追加することができます。アダプタを使用して、ポーンAPIから別のAPIに移行するのが基本です。

リストに含まれるデータへのアクセスは、特定の方法でのみ行う必要があります。データにタスクを実行する/リストに含まれるデータを処理することは、責任の異なる関数/オブジェクト/クラスによって行われなければなりません。

+0

最後の段落は私には意味がありません。 _handlingデータはどのようにタスクを実行していませんか? –

+0

私はもう少し具体的になった。 –

1

あなたが言っているのは、飲み物の総コストを計算する方法です。より一般的な言い方をすれば、&をマージする別の方法を提案しています。デコレータパターンで想定されている各派生オブジェクトの主な動作をリストに追加して実行します。そしてそれはかなりOOのアプローチでもありません。

しかし、元の意図Decorator Patternはそれ以外の広い視点になります。 拡張機能をオブジェクトに動的に追加するです。つまり、私はいくつかのオブジェクトを持っていることを意味しますO1 &私はそれを別のオブジェクトに変換することを望んでいますO2拡張機能&まだ2は互換性があります。

だから、私たちはObject Lifecycleに対してオブジェクト進化を管理する方法についてです。あなたはアイデアを持っているといいですね。 :))

1

Decoratorパターンは、実行時に追加の機能を持つオブジェクトを装飾(強化)します。

既にクラスを持っているとします。クラスを呼び出すと、IAというインターフェイスが実装されています。ここで、追加の機能を追加する必要がある場合は、AにはないメソッドsomeAlignFeatureToA()が必要です。クラスAを拡張するオプションがあります。別のアプローチは、Inheritanceを優先するCompositionです。クラスAのオブジェクトを別のクラスBに含めると、同じInterfaceA(つまりIA)と同じものを含めることができます。このようにクライアントコードの場合、クラスBのオブジェクトを受け入れるのは、Aと同じインタフェースを持つため、簡単です。(抽象クラ​​ス(インタフェースIA)に依存し、具体的なクラスクラスA)。

この方法では、継承チェーンがあまり長くなく、簡単にランタイムに機能を追加できます。

関連する問題