集約とかコンポジョンとか、対象のオブジェクトをuseしている関係って結局何がどう違うんじゃ〜〜?ってなったので調べた。
本記事の責任の委譲
以下の記事がよくまとまっている。本稿はこの記事の忘備録。
ノート
個人的には、これらの概念はオブジェクト間の結合度を表しているように捉えている。
上の記事では違いを次の観点で分類している。
- 相手のオブジェクトを保持するかどうか
- 保持したオブジェクトの寿命(開放されるまでの時間)
注意: 以下、プログラムの構文は適当なので雰囲気で読んでください.
Association
- 独立したオブジェクトが、メソッドで相手を使い合うだけ
- 相手オブジェクトを保持しない(保持するならAggregationかComposition)
// 個別にインスタンス生成
val manager: Manager = new Manager();
val swipe: SwipeCard = new SwipeCard();
manager.logo(swipe);
swipe.swipe(manager);
Aggregation
- 基本的にAssociationと同じ。異なる点は、他方のクラスが親になる(保持して使う)こと。
- Workerは親としてManager のみ を持つ。
class Manager
{
val workers: Seq[Worker] = null;
def add(worker: Worker)
{
workers :+ worker; //末尾にworkerを追加
}
}
val worker: Worker = new Worker();
val manager: Manager = new Manager();
manager.add(worker);
Composition
- Aggregationをさらに密結合させた状態。
- 保持するオブジェクトの寿命が、親の寿命に等しくなる。
- 典型的な例は、あるクラスの中でnewされるクラスの間の関係。
プロジェクトとマネージャの例
- 相互に依存:プロジェクトはマネージャがいないと成立しないし、マネージャはプロジェクトがないと存在できない。
- Projectオブジェクトを生成する際には、Managerオブジェクトが必要になる。
- 保持する側の寿命が、保持される側の最長の寿命
- ProjectオブジェクトとManagerオブジェクトは重度に依存しているため、オブジェクトの寿命が同じになる。つまりどちらかのオブジェクトに対してGCが働く場合、他方のオブジェクトも解放される。
class Manager
{
def HowisTheManager(Good: Boolean) {} // Managerのお賃金がProjectの出来で決まる
}
class Project
{
def Project(manager: Manager)
{
// projectはmanagerに依存している
this.manager = manager;
}
def isSuccess(): Boolean {}
def calcSalary()
{
// managerの給料はProjectに依存する
this.manager.HowisTheManager( this.isSuccess() );
}
}
val project: Project = new Project( new Manager() );
project.calcSalary(); // projectのメソッドは内部でManagerオブジェクトを参照している