UML中关联(Association)、聚合(Aggregation)和合成(Composition)之间的区别

前端之家收集整理的这篇文章主要介绍了UML中关联(Association)、聚合(Aggregation)和合成(Composition)之间的区别前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

http://www.tuicool.com/articles/ra6BJb

现在,我们需要设计一个项目管理系统,目前我们收集到了如下这些需求:

  1. REQ1:一个项目内有多名项目成员
  2. REQ2:一名项目成员只能被指派给一个项目
  3. REQ3:一个项目内仅有一名项目成员被指派为项目经理负责管理项目
  4. REQ4:所有项目成员均是公司员工
  5. REQ5:公司员工的薪水基本工资项目奖金组合而成
  6. REQ6:项目经理的项目奖金由项目的成败决定
  7. REQ7:项目中包含项目计划
  8. REQ8:一个项目计划由多个项目计划项组成

根据上面的需求描述,我们首先识别出若干个概念名词:

  1. 项目(Project)
  2. 项目成员(Project Member)
  3. 项目经理(Project Manager)
  4. 公司员工(Employee)
  5. 薪水(Salary)
  6. 基本工资(Base Salary)
  7. 项目奖金(Project Bonus)
  8. 项目计划(Schedule)
  9. 项目计划项(Schedule Item)

根据需求 “REQ4:所有项目成员均是公司员工”,我们可以得到 Employee 与 ProjectMember 的关系。

类 ProjectMember 实现了抽象类 Employee。Employee 类中包含计算薪水(Salary)操作,并负责封装需求 “REQ5:公司员工的薪水基本工资项目奖金组合而成”。ProjectMember 类覆写父类的薪水计算方法

 1   public abstract class Employee
2   {
3     public Employee(int id,string name)
4     {
5       ID = id;
6       Name = name;
7     }
8 
9     int ID { get; private set; }
10     string Name { 11 
12     double CalculateSalary()
13 14       return GetBaseSalary() + GetProjectBonus();
15 16 
17     protected  GetBaseSalary();
18     19   }
20 
21    ProjectMember : Employee
22 23     public ProjectMember(24       : base(id,name)
25 26 27 
28     public Project AssignedProject { 29 
30     void AssignProject(Project project)
31 32       AssignedProject = project;
33 34 
35     override double GetBaseSalary() { return 100036     double GetProjectBonus() { 20037   }

根据需求 “REQ3:一个项目内仅有一名项目成员被指派为项目经理负责管理项目”,可以推断出 ProjectManager 与 ProjectMember 的关系。

ProjectManager 继承自 ProjectMember。ProjectMember 类覆写父类的薪水计算方法,以实现需求 “REQ6:项目经理的项目奖金由项目的成败决定”。

ProjectManager : ProjectMember public ProjectManager(4 : 5 6 7 8 20009 GetProjectBonus() 11 12 return AssignedProject.IsSuccess ? 800 : 0; 14 }

由下面三个需求可以识别出 Project 与 ProjectMember/ProjectManager 之间的关系。

REQ1:一个项目内有多名项目成员

REQ2:一名项目成员只能被指派给一个项目

REQ3:一个项目内仅有一名项目成员被指派为项目经理负责管理项目

Project 聚合(Aggregation)了 ProjectMember,ProjectMember 当不在该项目中时仍然可以存在,比如转去做其他项目。

Project 关联(Association)了 ProjectManager,ProjectManager 当不在该项目时,需要转换为 ProjectMember。

ProjectManager 的薪水将由所负责的项目的成败决定,会调用 Project 的状态以计算薪水。

Project private ProjectManager _manager; 4 private List<ProjectMember> _members = new List<ProjectMember>(); 5 private Schedule _schedule = new Schedule(); 6 7 public Project( name,ProjectManager manager) 8 9 Name =10 _manager = manager; 12 13 14 public ProjectManager Manager { get { return _manager; } } 15 public ReadOnlyCollection<ProjectMember> Members { _members.AsReadOnly(); } } 16 public Schedule Schedule { _schedule; } } bool IsSuccess { return (new Random().Next(1,100) % 2) > ; } } 18 19 void AssignMembers(IEnumerable<ProjectMember> members) 20 21 _members.AddRange(members); 22 _members.ForEach(m => m.AssignProject(this)); 23 24 25 AddScheduleItem(ScheduleItem item) 27 _schedule.Add(item); 28 29 }

根据需求 “REQ7:项目中包含项目计划” 可得出 Project 与 Schedule 的关系。

根据需求 “REQ8:一个项目计划由多个项目计划项组成” 可得出 Schedule 与 ScheduleItem 的关系。

Project 聚合(Aggregation)了 Schedule。Schedule 由多个 ScheduleItem 组成(Composition)。

class Schedule : List<ScheduleItem> 3 4 5 ScheduleItem string Description { public DateTime BeginTime { public DateTime EndTime { 10 }

由此,我们得到了满足全部需求的类图:

现在,我们可通过以上类的定义来组织业务逻辑。

Program static void Main([] args) 5 ProjectManager manager = new ProjectManager(@"Dennis Gao"); 6 ProjectMember member2 = new ProjectMember(2,0)">Super Man7 ProjectMember member3 = 3,0)">Iron Man8 ProjectMember member4 = Spider Man10 var projectMembers = () { manager,member2,member3,member4 }; 12 Project project = new Project("EarnMoney,manager); project.AssignMembers(projectMembers); 14 15 ScheduleItem item1 = ScheduleItem() 16 { 17 Description = Team Building18 BeginTime = DateTime.Now.AddDays(5),153)">19 EndTime = DateTime.Now.AddDays(6 }; project.AddScheduleItem(item1); 22 23 Console.WriteLine(Salary List of Project [{0}] Members:24 foreach (var member in project.Members) Console.WriteLine( 27 \tProject Member [{0}] has TotalSalary [{1}]. member.Name,member.CalculateSalary()); 29 } 30 Console.WriteLine(); 32 Console.WriteLine([{0}] members will have a [{1}] on [{2}]. project.Name,project.Schedule.First().Description,153)">34 project.Schedule.First().BeginTime); 35 36 Console.ReadKey(); 37 38 }

由于在业务逻辑中,ProjectManager 的项目奖金由项目的成败来决定,但是项目的成败又多少带了点运气。

1 0; } }
1 3 4 }

所以,我们可能会得到两种输出结果,成功的项目和失败的项目。

失败的项目没有项目奖金:

成功的项目拿到了项目奖金:

我们给出 UML 中的相关定义:

元素名称 符号图例 含义
Association

A 和 B 相互调用和访问对方的元素。

A and B call and access each other’s elements.

Aggregation

A 中拥有一个 B,但 B 脱离于 A 仍然可以独立存活。

A has a B,and B can outlive A.

A "uses" B = Aggregation : B exists independently (conceptually) from A.

Composition

A 中拥有一个 B,B 脱离 A 后在系统中没有任何存活的意义。

A has a B,and B depends on A.

A "owns" B = Composition : B has no meaning or purpose in the system without A.

我们可以从不同的角度来理解和区分这三种关系:

Association Aggregation Composition Owner No owner

Single owner

Single owner

Lifetime Have their own lifetime

Have their own lifetime

Owner's lifetime

Child Object Child objects all are independent

Child objects belong to a single parent

Child objects belong to single parent

所以,总结来说,聚合(Aggregation)是一种特殊的关联(Association),合成(Composition)是一种特殊的聚合(Aggregation)。

Association->Aggregation->Composition

参考资料

  1. Introduction to Object Oriented Programming Concepts (OOP) and More
  2. Understanding Association,Aggregation,and Composition
  3. UML类图基本元素符号

完整代码

using System;
 System.Collections.Generic;
 System.Collections.ObjectModel;
 System.Linq;

namespace UML
{
   Program
  {
    [] args)
    {
      ProjectManager manager = );
      ProjectMember member2 = );
      ProjectMember member3 = );
      ProjectMember member4 = );

      =  ScheduleItem()
      {
        Description = = DateTime.Now.AddDays( project.Members)
      {
        Console.WriteLine(
           Employee
  {
     name)
    {
      ID = id;
      Name = name;
    }

    ; }
    ; }

     CalculateSalary()
    {
       GetProjectBonus();
    }

     GetBaseSalary();
     GetProjectBonus();
  }

   ProjectMember : Employee
  {
     name)
      :  AssignProject(Project project)
    {
      AssignedProject = project;
    }

    ; }
  }

   ProjectManager : ProjectMember
  {
     GetProjectBonus()
    {
      ;
    }
  }

  class Schedule : List<ScheduleItem>
  {
  }

   ScheduleItem
  {
     Project
  {
     ProjectManager _manager;
    ();
     Schedule();

     name;
      _manager = manager;
    }

     _manager; } }
     _members.AsReadOnly(); } }
     _schedule; } }
    ; } }

     members)
    {
      _members.AddRange(members);
      _members.ForEach(m => m.AssignProject());
    }

     AddScheduleItem(ScheduleItem item)
    {
      _schedule.Add(item);
    }
  }
}
View Code

猜你在找的设计模式相关文章