UML類圖是一種結構圖,用于描述一個系統的靜态結構。類圖以反映類結構和類之間關系為目的,用以描述軟體系統的結構,是一種靜态模組化方法。類圖中的類,與面向對象語言中的類的概念是對應的。
1 類結構
在類的UML圖中,使用長方形描述一個類的主要構成,長方形垂直地分為三層,以此放置類的名稱、屬性和方法。
其中,
一般類的類名用正常字型粗體表示,如上圖;抽象類名用斜體字粗體,如
User
;接口則需在上方加上
<<interface>>
。
屬性和方法都需要标注可見性符号,
+
代表
public
,
#
代表
protected
,
-
代表
private
。
另外,還可以用冒号
:
表明屬性的類型和方法的傳回類型,如
+$name:string
、
+getName():string
。當然,類型說明并非必須。
2 類關系
類與類之間的關系主要有六種:繼承、實作、組合、聚合、關聯和依賴,這六種關系的箭頭表示如下,
接着我們來了解類關系的具體内容。
3 六種類關系
六種類關系中,組合、聚合、關聯這三種類關系的代碼結構一樣,都是用屬性來儲存另一個類的引用,是以要通過内容間的關系來差別。
3.1 繼承
繼承關系也稱泛化關系(Generalization),用于描述父類與子類之間的關系。父類又稱作基類,子類又稱作派生類。
繼承關系中,子類繼承父類的所有功能,父類所具有的屬性、方法,子類應該都有。子類中除了與父類一緻的資訊以外,還包括額外的資訊。
例如:公共汽車、計程車和小轎車都是汽車,他們都有名稱,并且都能在路上行駛。
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),主要用來規定接口和實作類的關系。
接口(包括抽象類)是方法的集合,在實作關系中,類實作了接口,類中的方法實作了接口聲明的所有方法。
例如:汽車和輪船都是交通工具,而交通工具隻是一個可移動工具的抽象概念,船和車實作了具體移動的功能。
<?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):整體與部分的關系,但是整體與部分不可以分開。
組合關系表示類之間整體與部分的關系,整體和部分有一緻的生存期。一旦整體對象不存在,部分對象也将不存在,是同生共死的關系。
例如:人由頭部和身體組成,兩者不可分割,共同存在。
<?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):整體和部分的關系,整體與部分可以分開。
聚合關系也表示類之間整體與部分的關系,成員對象是整體對象的一部分,但是成員對象可以脫離整體對象獨立存在。
例如:公共汽車司機和工衣、工帽是整體與部分的關系,但是可以分開,工衣、工帽可以穿在别的司機身上,公交司機也可以穿别的工衣、工帽。
<?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圖中,雙向的關聯可以有兩個箭頭或者沒有箭頭,單向的關聯或自關聯有一個箭頭。上圖對應的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類。
大多數情況下,依賴關系展現在某個類的方法使用另一個類的對象作為參數。
依賴關系是一種“使用”關系,特定事物的改變有可能會影響到使用該事物的其他事物,在需要表示一個事物使用另一個事物時使用依賴關系。
例如:汽車依賴汽油,如果沒有汽油,汽車将無法行駛。
<?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類圖均使用免費的UMLet工具,在比較了Viso和StartUML後,感覺UMLet要好用很多,強烈推薦使用。另外,本文所有的UML類圖源檔案請點這裡下載下傳。
參考資料:
- UML圖中類之間的關系:依賴,泛化,關聯,聚合,組合,實作
- PHP程式員如何了解依賴注入容器(dependency injection container)
- php 組合模式
- UML類圖畫法及其之間的幾種關系
網際網路+時代,時刻要保持學習,攜手千鋒PHP,Dream It Possible。
原文連結:http://www.awaimai.com/patterns/uml