天天看點

UML的類圖詳解

UML類圖是一種結構圖,用于描述一個系統的靜态結構。類圖以反映類結構和類之間關系為目的,用以描述軟體系統的結構,是一種靜态模組化方法。類圖中的類,與面向對象語言中的類的概念是對應的。

1 類結構

在類的UML圖中,使用長方形描述一個類的主要構成,長方形垂直地分為三層,以此放置類的名稱、屬性和方法。

UML的類圖詳解

其中,

一般類的類名用正常字型粗體表示,如上圖;抽象類名用斜體字粗體,如

User

;接口則需在上方加上

<<interface>>

屬性和方法都需要标注可見性符号,

+

代表

public

#

代表

protected

-

代表

private

另外,還可以用冒号

:

表明屬性的類型和方法的傳回類型,如

+$name:string

+getName():string

。當然,類型說明并非必須。

2 類關系

類與類之間的關系主要有六種:繼承、實作、組合、聚合、關聯和依賴,這六種關系的箭頭表示如下,

UML的類圖詳解

接着我們來了解類關系的具體内容。

3 六種類關系

六種類關系中,組合、聚合、關聯這三種類關系的代碼結構一樣,都是用屬性來儲存另一個類的引用,是以要通過内容間的關系來差別。

3.1 繼承

繼承關系也稱泛化關系(Generalization),用于描述父類與子類之間的關系。父類又稱作基類,子類又稱作派生類。

繼承關系中,子類繼承父類的所有功能,父類所具有的屬性、方法,子類應該都有。子類中除了與父類一緻的資訊以外,還包括額外的資訊。

例如:公共汽車、計程車和小轎車都是汽車,他們都有名稱,并且都能在路上行駛。

UML的類圖詳解

PHP代碼實作如下:

<?php

class Car
{
    public $name;
    public function run()
    {
        return '在行駛中';
    }
}

class Bus extends Car
{
    public function __construct()
    {
        $this->name = '公共汽車';
    }
}

class Taxi extends Car
{
    public function __construct()
    {
        $this->name = '計程車';
    }
}

// 用戶端代碼
$line2 = new Bus;
echo $line2->name . $line2->run();      

3.2 實作

實作關系(Implementation),主要用來規定接口和實作類的關系。

接口(包括抽象類)是方法的集合,在實作關系中,類實作了接口,類中的方法實作了接口聲明的所有方法。

例如:汽車和輪船都是交通工具,而交通工具隻是一個可移動工具的抽象概念,船和車實作了具體移動的功能。

UML的類圖詳解
<?php

interface Vehicle
{
    public function run();
}

class Car implements Vehicle
{
    public $name = '汽車';
    public function run()
    {
        return $this->name . '在路上行駛';
    }
}

class Ship implements Vehicle
{
    public $name = '輪船';
    public function run()
    {
        return $this->name . '在海上航行';
    }
}

// 用戶端代碼
$car = new Car;
echo $car->run();      

3.3 組合關系

組合關系(Composition):整體與部分的關系,但是整體與部分不可以分開。

組合關系表示類之間整體與部分的關系,整體和部分有一緻的生存期。一旦整體對象不存在,部分對象也将不存在,是同生共死的關系。

例如:人由頭部和身體組成,兩者不可分割,共同存在。

UML的類圖詳解
<?php

class Head
{
    public $name = '頭部';
}

class Body
{
    public $name = '身體';
}

class Human
{
    public $head;
    public $body;

    public function setHead(Head $head)
    {
        $this->head = $head;
    }

    public function setBody(Body $body)
    {
        $this->body = $body;
    }

    public function display()
    {
        return sprintf('人由%s和%s組成', $this->head->name, $this->body->name);
    }
}

// 用戶端代碼
$man = new Human();
$man->setHead(new Head());
$man->setBody(new Body());
echo $man->display();      

3.4 聚合關系

聚合關系(Aggregation):整體和部分的關系,整體與部分可以分開。

聚合關系也表示類之間整體與部分的關系,成員對象是整體對象的一部分,但是成員對象可以脫離整體對象獨立存在。

例如:公共汽車司機和工衣、工帽是整體與部分的關系,但是可以分開,工衣、工帽可以穿在别的司機身上,公交司機也可以穿别的工衣、工帽。

UML的類圖詳解
<?php

class Clothes
{
    public $name = '工衣';
}

class Hat
{
    public $name = '工帽';
}

class Driver
{
    public $clothes;
    public $hat;

    public function wearClothes(Clothes $clothes)
    {
        $this->clothes = $clothes;
    }

    public function wearHat(Hat $hat)
    {
        $this->hat = $hat;
    }

    public function show()
    {
        return sprintf('公共汽車司機穿着%s和%s', $this->clothes->name, $this->hat->name);
    }
}

// 用戶端代碼
$driver = new Driver();
$driver->wearClothes(new Clothes());
$driver->wearHat(new Hat());
echo $driver->show();      

3.5 關聯關系

關聯關系(Association):表示一個類的屬性儲存了對另一個類的一個執行個體(或多個執行個體)的引用。

關聯關系是類與類之間最常用的一種關系,表示一類對象與另一類對象之間有聯系。組合、聚合也屬于關聯關系,隻是關聯關系的類間關系比其他兩種要弱。

關聯關系有四種:雙向關聯、單向關聯、自關聯、多重數關聯。

例如:汽車和司機,一輛汽車對應特定的司機,一個司機也可以開多輛車。

UML的類圖詳解

在UML圖中,雙向的關聯可以有兩個箭頭或者沒有箭頭,單向的關聯或自關聯有一個箭頭。上圖對應的PHP代碼如下:

<?php

class Driver
{
    public $cars = array();
    public function addCar(Car $car)
    {
        $this->cars[] = $car;
    }
}

class Car
{
    public $drivers = array();
    public function addDriver(Driver $driver)
    {
        $this->drivers[] = $driver;
    }
}

// 用戶端代碼
$jack = new Driver();
$line1 = new Car();
$jack->addCar($line1);
$line1->addDriver($jack);
print_r($jack);      

在多重性關系中,可以直接在關聯直線上增加一個數字,表示與之對應的另一個類的對象的個數。

  • 1..1

    :僅一個
  • 0..*

    :零個或多個
  • 1..*

    :一個或多個
  • 0..1

    :沒有或隻有一個
  • m..n

    :最少m、最多n個 (m<=n)

3.6 依賴關系

依賴關系(Dependence):假設A類的變化引起了B類的變化,則說名B類依賴于A類。

大多數情況下,依賴關系展現在某個類的方法使用另一個類的對象作為參數。

依賴關系是一種“使用”關系,特定事物的改變有可能會影響到使用該事物的其他事物,在需要表示一個事物使用另一個事物時使用依賴關系。

例如:汽車依賴汽油,如果沒有汽油,汽車将無法行駛。

UML的類圖詳解
<?php
class Oil
{
    public $type = '汽油';
    public function add()
    {
        return $this->type;
    }
}

class Car
{
    public function beforeRun(Oil $oil)
    {
        return '添加' . $oil->add();
    }
}

// 用戶端代碼
$car = new Car;
echo $car->beforeRun(new Oil());      

4 總結

這六種類關系中,組合、聚合和關聯的代碼結構一樣,可以從關系的強弱來了解,各類關系從強到弱依次是:繼承→實作→組合→聚合→關聯→依賴。如下是完整的一張UML關系圖。

UML的類圖詳解

(點選圖檔檢視大圖)

UML類圖是面向對象設計的輔助工具,但并非是必須工具,如果暫時不了解本文的内容,可以繼續看設計模式部分,并不會影響。

說明:本文所有UML類圖均使用免費的UMLet工具,在比較了Viso和StartUML後,感覺UMLet要好用很多,強烈推薦使用。另外,本文所有的UML類圖源檔案請點這裡下載下傳。

參考資料:

  1. UML圖中類之間的關系:依賴,泛化,關聯,聚合,組合,實作
  2. PHP程式員如何了解依賴注入容器(dependency injection container)
  3. php 組合模式
  4. UML類圖畫法及其之間的幾種關系

網際網路+時代,時刻要保持學習,攜手千鋒PHP,Dream It Possible。

原文連結:http://www.awaimai.com/patterns/uml