UML基礎系列:類圖

libingql發表於2014-01-04

  類圖描述系統中類的靜態結構,它不僅定義系統中的類,描述類之間的聯絡,如關聯、依賴、聚合等,還包括類的內部結構(類的屬性和操作)。類圖描述的是靜態關係,在系統的整個生命週期中都是有效的。物件圖是類圖的例項,它們的不同之處在於物件圖顯示類圖的多個物件例項,而不是實際的類。由於物件存在生命週期,所以物件圖只能在系統某一時間存在。

1. 類圖概述

  類圖(Class Diagram)是描述類、介面、協作以及它們之間關係的圖,用來顯示系統中各個類的靜態結構。類圖是一種模型型別,一種靜態模型型別。一個類圖根據系統中的類以及各個類之間的關係描述系統的靜態結構。

  類圖是物件導向系統建模中最常用的圖,它是定義其他圖的基礎,在類圖的基礎上,可以使用狀態圖、協作圖、元件圖和配置圖等進一步描述系統其他方面的特性。

  類圖包含7個元素:類(Class)、介面(Interface)、協作(Collaboration)、依賴關係(Dependency)、泛化關係(Generalization)、關聯關係(Association)以及實現關係(Realization)。

2. 類(Class)

  類是對一組具有相同屬性、操作、關係和語義的物件的描述。類定義聊了一組有著狀態和行為的物件。其中,屬性和關聯用來描述狀態。屬性通常用沒有身份的資料值表示。關聯則用有身份的物件之間的關係表示。行為由操作來描述,方法是操作的實現。

  在UML中,類用矩形來表示,並且該矩形被劃分為3個部分:名稱部分(Name)、屬性部分(Attribute)和操作部分(Operation)。其中頂端的部分存放類的名稱,中間的部分存放類的屬性、屬性型別及其值,底部的部分存放類的操作、操作的引數和返回型別。

  類的屬性格式:

name : attribute type

  UML規範允許在屬性列表節中設定預設值的標識。

name : attribute type = default value

  類的操作格式:

name (parameter list) : type of value returned

  當一個操作有引數時,引數被放在操作的括號內,引數格式:

parameter name : parameter type

  當文件化操作引數時,可以使用一個可選擇的指示器,以顯示引數到操作的輸入引數或輸出引數。in 表示輸入引數,out 表示輸出引數。按照UML規範, in 是引數的預設型別。

  

3. 類之間的關係

  類之間的關係最常用的有4種,分別是表示類之間使用關係的依賴關係(Dependency)、表示類之間一般和特殊關係的泛化關係(Generalization)、表示物件之間結構關係的關聯關係(Association)、表示類中規格說明和實現之間關係的實現關係(Realization)。

3.1 依賴關係(Dependency)

  依賴關係用於表示類之間的使用關係,UML定義了4種基本依賴型別:使用依賴、抽象依賴、授權依賴和繫結依賴。

  使用依賴是最常用的依賴,使用依賴關係圖:

  

  表示客戶使用提供者提供的服務以實現它的行為。可以簡單的理解,就是一個類A使用到了另一個類B,而這種使用關係是具有偶然性的、臨時性的、非常弱的,但是B類的變化會影響到A。客戶使用產品需要提供者,但一個客戶需要的產品可以有多個提供者。

  場景:Driver與Car,Driver駕駛之前需要Car能夠開動。

  依賴關係圖:

  

  C#實現:

public class Driver
{
     pulic void Drive(Car car)
     {
          car.Move();
     }
}
public class Car
{
     pulic void Move()
     {
          // 省略程式碼
     }
}

3.2 泛化關係(Generalization)

  泛化關係是一種存在於一般元素和特殊元素之間的分類元素。泛化關係主要表現為類與類之間的繼承關係、類與介面之間的實現關係。

  場景:形狀類(Shape)為基類,圓形類(Circle)、矩形類(Rectangle)和三角形類(Triangle)均繼承形狀類。

  類之間的泛化關係圖:

  

  C#實現:

  Shape.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

public abstract class Shape
{
    protected string _name;

    public Shape(string name)
    {
        this._name = name;
    }

    /// <summary>
    /// 面積
    /// </summary>
    /// <returns></returns>
    public abstract double Area();

    /// <summary>
    /// 顯示
    /// </summary>
    public abstract void Display();
}

  Circle.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

/// <summary>
/// 圓形
/// </summary>
public class Circle : Shape
{
    private double _radius;

    public Circle(string name, double radius)
        : base(name)
    {
        this._radius = radius;
    }

    public override double Area()
    {
        return Math.Round(Math.PI * _radius * _radius, 2);
    }

    public override void Display()
    {
        Console.WriteLine("{0} 半徑:{1},面積:{2}", _name, _radius, this.Area());
    }
}

  Rectangle.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

/// <summary>
/// 矩形
/// </summary>
public class Rectangle : Shape
{
    private double _width;
    private double _height;

    public Rectangle(string name, double width, double height)
        : base(name)
    {
        this._width = width;
        this._height = height;
    }

    public override double Area()
    {
        return _width * _height;
    }

    public override void Display()
    {
        Console.WriteLine("{0} 長:{1},寬:{2},面積:{3}", _name, _width, _height, this.Area());
    }
}

  Triangle.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

/// <summary>
/// 三角形
/// </summary>
public class Triangle : Shape
{
    private double _a;
    private double _b;
    private double _c;

    /// <summary>
    /// 三角形建構函式
    /// 引數:三角形名稱和三條邊長
    /// </summary>
    /// <param name="name">三角形名稱</param>
    /// <param name="a">第一條邊長</param>
    /// <param name="b">第二條邊長</param>
    /// <param name="c">第三條邊長</param>
    public Triangle(string name, double a, double b, double c)
        : base(name)
    {
        _a = a;
        _b = b;
        _c = c;
    }

    public override double Area()
    {
        double p = (_a + _b + _c) / 2;
        return Math.Sqrt(p * (p - _a) * (p - _b) * (p - _c));
    }

    public override void Display()
    {
        Console.WriteLine("{0} 三條邊長:{1},{2},{3},面積:{3}", _name, _a, _b, _c, this.Area());
    }
}

3.3 關聯關係(Association)

  關聯關係是一種結構關係,它指明一個事物的物件與另一個事物的物件之間的聯絡。關聯關係比依賴關係更強,不存在依賴關係的偶然性,關係也不是臨時性的,而一般是長期性的。

3.3.1 單向關聯(DirectedAssociation)

  場景:商品和訂單,訂單中包含商品資訊,但商品中不包含訂單資訊。

  類之間單向關聯圖:

  

  C#實現:

  Product.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

public class Product
{
    public int ProductID { get; set; }
    public string ProductName { get; set; }

    public void Add() { }

    public void Remove() { }

    protected void Find() { }
}

  Order.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

public class Order
{
    public int OrderID { get; set; }

    public List<Product> GetProductsByOrderID(int orderID)
    {
        List<Product> products = new List<Product>();
        // 省略程式碼
        return products;
    }
}

3.3.2 雙向關聯(Association)

  場景:使用者與角色,一個使用者可以屬於多個角色,同時一個角色也可以擁有多個使用者。

  類之間的雙向關聯圖:

 

  C#實現:

  User.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

public class User
{
    public int UserID { get; set; }
    public string UserName { get; set; }

    public List<Role> GetRolesByUserID(int userID)
    {
        return new List<Role>();
    }
}

  Role.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

public class Role
{
    public int RoleID { get; set; }
    public string RoleName { get; set; }

    public List<User> GetUsersByRoleID(int roleID)
    {
        return new List<User>();
    }
}

3.3.3 聚合關係(Aggregation)

  聚合表示的是一種has-a的關係,是一種整體-部分關係,同時整體與部分之間又可以相互分離。整體與部分擁有相互獨立的生命週期,部分的生命週期並不由整體來管理決定。當整體這個物件已經不存在的時候,部分的物件還是可能繼續存在的。整體可以包含多個部分,部分可以屬於多個整體物件,也可以為多個整體物件共享。

  場景:汽車與車輪,汽車有多個車輪。車輪使用週期結束,可以為汽車安裝新的車輪。同時汽車使用週期結束,可再用的車輪也可以卸下安裝到其他的汽車上。

  聚合關係圖:

  

  C#實現:

Wheel wheel = new Wheel();
Car car = new Car(wheel);

  或者

Car car = new Car(new Wheel());

  Car與Wheel的生命週期相互獨立。

3.3.4 組合關係(Composition)

  組合關係是聚合關係的另一種形式,體現的是一種contains-a的關係,但是整體與部分擁有共同是生命週期,整體與部分不可分,一旦整體物件不存在,部分物件也將不存在。子類物件的生命週期依賴於父類的生命週期。

  場景:公司(Company)與公司內部設定的部門(Department),一個Company物件至少有一個Department物件,當Company物件被銷燬時,Department物件也將同時被銷燬。

  組合關係圖:

  

  C#實現:

public class Department ()
{
        // 省略程式碼
}
pulic class Company ()
{
        Department d = new Department ();
        // 省略程式碼
}

  Department物件在Company物件中建立,當Company物件的生命週期結束的時候,Department物件的生命週期同時也結束。

3.4 實現關係(Realization)

  實現是規格說明和其實現之間的關係,實現關係通常在兩種情況下被使用:在介面與實現該介面的類之間;在用例以及實現該用例的協作之間。

  實現關係圖:

  

相關文章