C# 使用UML类图的组合和聚合示例

C# 使用UML类图的组合和聚合示例,c#,uml,class-diagram,C#,Uml,Class Diagram,我似乎不能完全理解代码中聚合和组合之间的区别 客户-->银行账户 (这应该是客户机-银行账户组合类图) 在这个例子中,客户机有一个银行账户,这意味着,当客户机对象死亡时,他的银行账户对象也死亡。这是否意味着我们必须在客户端类中有一个BankAccount对象 Class Client { BankAccount acc = new BankAccount(); public void addMoneyToBankAccount(decimal amount) {

我似乎不能完全理解代码中聚合和组合之间的区别

客户-->银行账户

(这应该是客户机-银行账户组合类图)

在这个例子中,客户机有一个银行账户,这意味着,当客户机对象死亡时,他的银行账户对象也死亡。这是否意味着我们必须在客户端类中有一个BankAccount对象

Class Client
{

    BankAccount acc = new BankAccount();

    public void addMoneyToBankAccount(decimal amount)
    {         
        acc.AddMoney(amount);
    }

    public decimal CheckBalance()
    {
        return acc.CheckAccountBalance();
    }

}
那么,这是代码中的组合吗?在本例中,聚合是什么样子的?
对不起,新手的问题,请纠正我,如果代码是错误的。提前谢谢。

是的,你说得对。这是一篇简单的作文

对于聚合,您的客户机类应该保留BankAccount类的引用,但不应该控制它的对象生存期

class Client
{
     private readonly BankAccount _account;

     public Client(BankAccount account)
     {
         _account = account;
     }

     //...
}

客户对象将被销毁后,可以将中使用的BankAccount对象分配给另一个客户。

您的客户BankAccount代码是一个组合关系

您的代码满足组合的所有属性

->部分分类器(
BankAccount
)的生存期取决于整个分类器(
Client
)的生存期

->数据通常只向一个方向流动(即从整个分类器(
客户端
)到部分分类器(
银行账户


聚合可以通过将BankAccount作为方法的参数传递给客户端来表示

所以,这段代码是聚合

class client
{
    public bool updateAccount(BankAccount ba){....}
}
如您所见,它满足聚合的所有属性

class client
{
    public bool updateAccount(BankAccount ba){....}
}
->它可以独立于
客户端


->数据从整个分类器(
客户机
)流到部分(
银行账户

是的,您要做的是调用组合,如果您想这样对它进行聚合:

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系统的实施,所以我要g以其中的一部分为例

《客户关系管理系统》有一个客户数据库和一个独立的数据库,它保存了一个地理区域内的所有地址。在这种情况下,聚合是有意义的,因为客户的“A—A”地址。说地址是客户的一部分,这是没有道理的,因为它不是。如果这样,如果客户不再存在,DOE。地址是什么?我认为它并没有停止存在。聚合在UML图上显示为一个未填充的菱形

正如我在回答的开头所说,这是我对合成和聚合的看法。决定是使用合成还是聚合不应该是一件棘手的事情。在对象建模时,应该说这是“的一部分”还是“有-a”?

这个解释对我很有帮助:

例如,我们可以将汽车视为一个整体实体,将车轮视为整个汽车的一部分。车轮可以提前几周创建,并且可以在组装期间放置在汽车上之前放置在仓库中。在本例中,车轮类的实例显然独立于汽车类的实例。但是,有时部分类的生命周期与整个类不完全独立,这被称为组合聚合。例如,考虑一个公司与其部门之间的关系。公司和部门都被建模为类,并且一个部门不能存在于公司存在之前。当公司类的实例存在时

所以对我来说,创造者/破坏者的生命周期(新的,发行版)对于实例内部的合成,聚合必须具有addObject选项,并且该方法只需将对象id保存为自身的属性。因此,在上面的客户机和银行帐户示例中,即使客户机记录被销毁(孤立帐户),也要由业务部门确定帐户是否可以存在如果它是aggegator,那么您将拥有客户端方法:

Class Client {
- (void) addToAccount:(BankAccount *)acc;
- (void) removeFromAccount:(BankAccount *)acc;
}
close account方法将是BankAccount对象实例的一部分,因为它可以独立于客户端存在

与要求客户存在的组合方法不同,如果客户不再存在,则属于该帐户所有者的所有帐户都将被删除。因此,您将要求客户对象为您创建一个帐户:

Class Client {
- (BankAccount *) openAccount;
- (BOOL) closeAccount:(BankAccount *)acc;
}

谢谢你的回答,但我还有一个后续问题:私人只读银行账户;公共客户(银行账户){u账户=账户;}在客户端构造函数中,这是否会启动一个新的BankAccount对象,然后指定我们的只读变量\u account来引用该对象,该对象由account变量引用?您应该传递account对象,例如,包含在指定银行对象内的独立集合中。主要思想是您无法控制BanckAccount对象生存期(与组合关系一样),但您引用了它。如果您只写var client=new client(new BankAccount)-它将不会是聚合(因为account对象将与客户端对象同时被销毁)。您可以为BankAccount类创建私有构造函数,并使用AccountFactory创建包含指定银行的所有帐户的新对象。我有点困惑。下面这句话:“在聚合中,部分的生存期不是由整体管理的”。假设运行时代码进行如下调用:new Client(new BankAccount())。由于BankAccount是作为构造函数中的参数传递的,因此仅在客户端的生存期内存在,因此部件的生存期不是由客户端管理的吗?