委任、合成、集約の区別 (Java OO 設計)
-
21-09-2019 - |
質問
私は、委任、構成、集計を相互に区別し、一方を他方よりも使用するのが最適なケースを特定するという継続的な問題に直面しています。
Java OO Analysis and Design の本を参照しましたが、まだ混乱が残っています。主な説明は次のとおりです。
代表団:自分のオブジェクトが別のオブジェクトの機能を変更せずにそのまま使用する場合。
構成:私のオブジェクトは他のオブジェクトで構成されており、オブジェクトがガベージ コレクションによって破棄された後はそれらのオブジェクトは存在できなくなります。
集計:私のオブジェクトは、オブジェクトが破壊された後でも存続できる他のオブジェクトで構成されています。
それぞれのケースとその背後にある理由を示す簡単な例をいくつか挙げていただくことは可能でしょうか?私のオブジェクトが単に別のオブジェクトへの参照を持っているということ以外に、これらの例をどのようにして示すことができるでしょうか?
解決
3 つの場合すべてにおいて、オブジェクトは別のオブジェクトを参照します。違いは、参照されるオブジェクトの動作やライフサイクルにあります。いくつかの例:
構成:家には 1 つ以上の部屋があります。Room は House なしでは存在しないため、Room の存続期間は House によって制御されます。
集計:ブロックで作ったおもちゃの家。分解はできますがブロックは残ります。
代表団:上司からコーヒーを買ってきてほしいと頼まれ、代わりにインターンにコーヒーを買ってきてもらいました。委任は、関連付けの一種ではありません (構成/集約とは異なります)。後の 2 つは Stack Overflow で議論されています 何度も
コメントでは、各ケースで実装がどのように異なるかを尋ねており、すべてのケースで関連するオブジェクトのメソッドを呼び出していることがわかります。確かに、それぞれのケースで次のようなコードが必要になります。
myRoom.doWork();
myBlock.doWork();
myMinion.doWork();
ただし、違いは関連オブジェクトのライフサイクルとカーディナリティにあります。
コンポーネントの場合、ハウスが作成されると部屋が存在します。したがって、ハウスのコンストラクターでそれらを作成するかもしれません。
アソシエーションの場合 (タイヤと車を使用します) 車はコンストラクターにタイヤを追加する可能性がありますが、後でタイヤを削除して交換する必要がある場合があります。したがって、次のようなメソッドもあります
removeTyre(FrontLeft)
addNewTyre(aTyre, BackRight)
そして、aTyre オブジェクトがファクトリーから来た可能性が非常に高いですが、私たちはそうではありませんでした。 new
Car のメソッドのいずれかでそれを実行します。
委任の場合、デリゲートを保持するメンバー変数さえない可能性があります。
resourcingPool().getIntern().getCoffee(SkinnyLatte, workstation 7);
オブジェクト間の関係は、インターンがコーヒーを取りに行っている間のみ持続します。その後、リソース プールに戻ります。
他のヒント
委任
public class A {
private B b = new B();
public void methodA() {
b.methodB();
}
}
ときA
コールmethodA
のクライアント、クラスA
の代表者のB
のmethodB
に呼び出します。
の論理的根拠。のクラスAは、他の場所で所属の行動を公開します。これは、クラスAの一つのクラスから継承しますが、そのクライアントが別のクラスに実装されている行動を必要とする単一継承言語で発生する可能性があります。 さらに研究するます。
ハイブリッド委任
public class A {
private B b = new B();
public void methodA() {
b.methodB( this );
}
}
継承の代用として作用簡単転送および委任を含む委任の違いは例示として、被呼者が発呼者のパラメーターを受け入れなければならないことです
b.methodB( this );
の論理的根拠のクラスB
から入手利用機能にクラスA
インスタンスを可能にします、ちょうどそれがクラスB
から継承された場合にクラスA
と同じように - 。しかし、継承なし。 さらに研究するます。
組成物
public class A {
private B b = new B();
public A() {
}
}
は、クラスA
のが存在の特定のインスタンスへのこれ以上の言及したら、クラスB
のそのインスタンスは破棄されます。
の論理的根拠。のクラスはモジュール方式での行動や属性を定義することができます。 さらに研究するます。
集計
public class A {
private B b;
public A( B b ) {
this.b = b;
}
}
public class C {
private B b = new B();
public C() {
A a = new A( this.b );
}
}
クラスA
の特定のインスタンスへの参照がなくなったら、、クラスB
のそのインスタンスは破棄されません。 A
が破壊される前に、この例では、両方のC
とB
ゴミを収集する必要があります。
の論理的根拠。の再利用オブジェクトにインスタンスを許可します。 さらに研究するます。
マニュアルを見ずに、デモンストレーション
これらの単純なパターンに指定された名前は、その参照関係によって定義されています。
あなたの本は非常に詳しく説明していますので、詳しく説明し、いくつかの例を紹介します。
代表団: 自分のオブジェクトが別のオブジェクトの機能を変更せずにそのまま使用する場合。
論理的にクラスを大きくする必要がある場合があります。しかし、大きなクラスはコーディングの習慣としては適切ではありません。また、クラスの一部の機能が複数の方法で実装可能であり、それを変更したくなる場合もあります。
class FeatureHolder {
void feature() {
// Big implementation of the feature that you dont want to put in the class Big
}
}
class Big {
private FeatureHolder FH = new FeatureHolder();
void feature() {
// Delegate to FeatureHolder.
FH.feature();
}
//.. Other features
}
上記の例から、Big.feature() は FH の機能を変更せずにそのまま呼び出します。この方法では、クラス Big に機能 (分業) の実装を含める必要がありません。また、feature() は「NewFeatureHolder」などの他のクラスによって異なる方法で実装でき、Big は代わりに新しい機能ホルダーを使用することを選択する場合があります。
構成: 私のオブジェクトは他のオブジェクトで構成されており、オブジェクトがガベージ コレクションによって破棄された後は存在できなくなります。
集計: 私のオブジェクトは、オブジェクトが破壊された後でも存続できる他のオブジェクトで構成されています。
技術的には、Composition は関係の「一部」であり、Aggregation は「参照」関係です。あなたの腕はあなたの一部です。あなたが生きられなくなったら、あなたの腕も死んでしまいます。あなたの布はあなたの一部ではありませんが、あなたはそれを持っています。ゲストとして参加することはできますが、布地は持ち歩きません。
プログラミングでは、一部のオブジェクトは別のオブジェクトの一部であり、それがなければ論理的な意味を持ちません。たとえば、ボタンはウィンドウ フレームに組み込まれます。フレームが閉じている場合、ボタンは存在する必要がありません (コンポジション)。ボタンにはデータベースへの参照が含まれる場合があります (データの更新など)。ボタンが削除されても、データベースがまだ存在している可能性があります (集約)。
私の英語で申し訳ありませんが、これがお役に立てば幸いです
1)委任:マンドライバーカー例。 A男は車を買いました。しかし、その男は車を運転することを知りません。そこで彼は車を運転して知っているドライバーを任命します。だから、男クラスは、車を利用して輸送を行うために望んでいます。しかし、それは車でinteracting-機能/互換性を持っていません。そこで彼は、男クラスと互換性のあるドライバである車との互換性を持つクラスを使用しています。
言う人ドライバーが理解できると仮定すると、2)組成:車のシミュレーションは、ルーチンの例です。車の移動、ホイールが回転を行います。ホイールと車の一部であり、その移動機能の一部として、車輪クラス回転functinalityを使用して車のクラス。
3)集計:車とその色。 Carクラスのオブジェクトのフェラーリは、カラークラスのオブジェクトの赤を持っています。しかし、カラークラスオブジェクト赤、ユーザの検索は赤色の仕様に発生した場合、個々のクラスとして存在することができる。