2016-04-03 2 views
4

私はちょうどComposite patternについて学んだ。私が理解しているように、その背後にある主な考え方は、ツリーのエッジとノードの両方を一様に扱うことです。これは、このような何かに私たちをリードする、構造の「透明性」が「安全」以上に評価されていることを意味します透明性は複合パターンの安全性よりも重視されるのはなぜですか?

enter image description here

私が概念を理解しますが、安全性を犠牲にするときの状況を考えることはできません透明性が良い選択になるだろう。言い換えれば、私たちがそのような深刻な犠牲を払うことを厭わないほど透明性を必要とするケースはありますか?

答えて

4

透明性は、Gang of Fourの元の説明を含め、複合パターンのいくつかの議論では安全性よりも重視されると言えるでしょう。しかし、Gang of Fourの記述は、トレードオフを認識し、other influential discussions are more pro-safetyです。

安全(のみコンポジットの葉には適用できないメソッドを宣言する)コストました:とにかく、ここで透明性のためのケースです

  • 安全なコンポーネントの木のクライアントは、各コンポーネントがあるかどうかをチェックする必要がある

    ツリーを横切るときに合成します(おそらく、GoFブックの168ページに示されている外部多態性技法を使用します)。ツリーのすべてのクライアントがこの検査を実装する必要があります。検査がVisitorなどで提供されている場合は、その複雑さに対処する必要があります。

  • コンポーネントの作成者は、各コンポーネントがリーフかコンポジットかを選択し、選択が変更されるとコードを変更する必要があります。

「透明」(葉およびコンポジットの均一性、すなわち、コンポーネント内のすべてのツリー操作メソッドを宣言する)の値は、安全性のコストが最小化されることです。

  • リーフスは稀または存在しません:以下のいずれかに該当する場合

    透明性がより貴重になります。たとえば、UIツールキットでは、任意のコンポーネント(チェックボックスのように通常は子どもにはほとんど使用されないコンポーネントでも)に子を追加し、それらをインテリジェントにレンダリングすることが期待されます。このように提供された視覚的な柔軟性は、Leafsでなければならないものを開発者が必要とする余分な努力に価値があるかもしれません。

  • ツリーの多くの用途では、リーフとコンポジットを区別する必要はありません。たとえば、UIツールキットでは、描画などの操作では、各コンポーネントの長さがゼロの可能性のある子リストを反復して、LeafsとCompositesを一様に処理できます。

  • 子コンポーネントのリストを持つすべてのコンポーネントのランタイム(メモリおよびCPU)コストは、残りのプログラムに比べて低くなります。

上記に該当する場合には、均一性がより多くを報わ:木のクライアントはツリーを使用して以下を実行する必要があり、かつ利用のしやすさがトラブルにして、クライアントを取得状況はまれです。これは、UIコンポーネントの場合によくあることです。ツリーのクライアントがコンポジットであるかどうかを心配する必要がある唯一の時間は、ツリーを構築(追加)するときです。とにかくすべてのコンクリートコンポーネントがあります。

Java Swingがこの選択をしました:JComponentにはaddの方法が含まれています。開発者は子供を収容しないJComponentsでそれらを使用する必要があります。これは多くのコンポーネントで明らかです(やはりチェックボックスなど)。

逆の状況のいずれかが当てはまる場合、リーフとコンポジットの区別はより重要になり、安全なツリーを管理する複雑さの増加は価値があります。リーフが共通で、ツリーの多くのクライアントがリーフとコンポジットを区別する必要があるが、タイプが「透過的」で、区別ができない場合(おそらく、GoFはこの選択を透明ではなく不透明にする必要があります)クライアントが間違いを犯す可能性が高くなります。子どものリストが高すぎる場合、コンポーネントの作成者は、各コンポーネントがリーフかコンポジットかを選択する価値があります。

+0

ありがとう、私はまだ葉が無関係な機能を持つ必要がある理由は理解していません。リーフで 'add()'を呼び出すのは間違っています。それはメソッドが正しく実装されていないか、まったく持っていなくてもかまいません。言い換えれば、 'add()'を使用したければ、オブジェクトがコンポジットかどうかをチェックする必要があります。 –

+1

1つの基本クラスのすべての機能を宣言すると、基本クラスが1つだけ必要になります。これは誰にとっても簡単です。すべてのコンポジット機能がコンポジットでのみ宣言されている場合、ツリーの管理は誰にとってもより複雑です。ほとんどの子機能がComponentで宣言されているが、Composite(おそらくもっとも自然な安全指向の設計)でのみ 'add'が宣言されている場合、ツリーの一部のクライアントではコストが削減されますが、コンポーネント実装者にとっては、 –

関連する問題