コード内の集約と構成の違いを完全に理解できないようです。
クライアント<。> ---->銀行口座
(これは、クライアント-銀行口座構成クラス図であると想定されています)。
したがって、この例では、クライアントは銀行口座を持っています。つまり、クライアントオブジェクトが停止すると、彼の銀行口座オブジェクトも停止します。これは、Clientクラス内にBankAccountオブジェクトが必要であることを意味しますか?
Class Client
{
BankAccount acc = new BankAccount();
public void addMoneyToBankAccount(decimal amount)
{
acc.AddMoney(amount);
}
public decimal CheckBalance()
{
return acc.CheckAccountBalance();
}
}
それで、この構成はコードですか?この例では、集計はどのようになりますか?初心者の質問で申し訳ありませんが、コードが間違っていた場合は訂正してください。前もって感謝します。
はい、あなたがしていることは、あなたがこのようにあなたをそれに集約したいのであれば、作曲と呼ぶことです:
Class Client
{
BankAccount acc;
public Client(BankAccount p_acc)
{
acc=p_acc;
}
public void addMoneyToBankAccount(decimal amount)
{
acc.AddMoney(amount);
}
public decimal CheckBalance()
{
return acc.CheckAccountBalance();
}
}
集計:
継承が「is-a」を与え、構成が「part-of」を与える場合、集約は「has-a」関係を与えると主張することができます。集約内では、パーツの存続期間は全体によって管理されません。これを明確にするために、例が必要です。過去12か月以上、CRMシステムの実装に携わってきたので、この一部を例として使用します。
CRMシステムには、顧客のデータベースと、地理的領域内のすべての住所を保持する個別のデータベースがあります。この状況では、顧客が「住所」を持っているため、集計は理にかなっています。住所が顧客の「一部」であると言っても意味がありません。そうではないからです。このように考えてください。顧客が存在しなくなった場合、住所はありますか?私はそれが存在し続けることを主張します。集計は、UML図に塗りつぶされていないひし形として表示されます。
答えの冒頭で述べたように、これは構成と集約に関する私の見解です。コンポジションとアグリゲーションのどちらを使用するかを決定するのは難しいことではありません。オブジェクトモデリングの場合、これは「の一部」なのか、「持っている」のかということです。
クライアントと銀行口座コードはcomposition
関係です
あなたのコードは構成のすべての特性を満たしています
->部分分類子(BankAccount
)の存続期間は、分類子全体(Client
)の存続期間に依存します。
->データは通常、一方向にのみ流れます(つまり、分類子全体(Client
)から部分分類子(BankAccount
)に流れます。
集計は、メソッドの引数としてBankAccountをクライアントに渡すことで表すことができます。
したがって、このコードは集約です
class client
{
public bool updateAccount(BankAccount ba){....}
}
ご覧のとおり、Aggregationのすべてのプロパティを満たしています
-> client
とは独立して存在できます
->データは分類子全体(client
)から部分(BankAccount
)に流れます
この説明 IBMから は私に役立ちます:
たとえば、Carをエンティティ全体として、CarWheelをCar全体の一部として考えることができます。ホイールは数週間前に作成することができ、組み立て中に車に乗せる前に倉庫に置くことができます。この例では、Wheelクラスのインスタンスは、Carクラスのインスタンスとは明らかに独立しています。ただし、パーツクラスのライフサイクルがクラス全体のライフサイクルから独立していない場合があります。これは、コンポジション集約と呼ばれます。たとえば、会社とその部門との関係について考えてみます。会社と部門の両方がクラスとしてモデル化されており、会社が存在する前に部門が存在することはできません。ここで、Departmentクラスのインスタンスは、Companyクラスのインスタンスの存在に依存しています。
したがって、私にとって、コンポジションの作成者/破棄者のライフサイクル(新規、リリース)はインスタンス内にあります。アグリゲーションには、代わりにaddObjectのオプションが必要であり、メソッドは単にオブジェクトIDをそれ自体の属性として保存します。したがって、上記のクライアントと銀行口座の例では、クライアントレコードが破棄された場合でもアカウントが存在できるかどうかを判断するのは実際にはビジネス次第です(孤立したアカウント)。それが集約者である場合、クライアントメソッドがあります。
Class Client {
- (void) addToAccount:(BankAccount *)acc;
- (void) removeFromAccount:(BankAccount *)acc;
}
また、close accountメソッドは、クライアントから独立して存在できるため、BankAccountオブジェクトインスタンスの一部になります。
クライアントが存在することを要求する構成方法に対して、クライアントが存在しなくなると、そのアカウント所有者に属するすべてのアカウントが削除されます。したがって、クライアントオブジェクトにアカウントを作成するように依頼します。
Class Client {
- (BankAccount *) openAccount;
- (BOOL) closeAccount:(BankAccount *)acc;
}
はい、その通りです。これは単純です構成。
aggregationの場合、ClientクラスはBankAccountクラスの参照を保持する必要がありますが、オブジェクトの有効期間を制御することはできません。
class Client
{
private readonly BankAccount _account;
public Client(BankAccount account)
{
_account = account;
}
//...
}
クライアントオブジェクトが破棄された後、その中で使用されているBankAccountオブジェクトを別のクライアントに割り当てることができます。