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類圖是面向對象設計的輔助工具,但並非是必須工具,如果暫時不理解本文的內容,可以繼續看設計模式部分,並不會影響。
轉自:歪麥博客
https://www.awaimai.com/patterns/uml
可以關注微信公眾 lovephp