uml 圖學習記錄

UML類圖與類的關係詳解
 

2011-04-21 來源:網絡數據庫

 

在畫類圖的時候,理清類和類之間的關係是重點。類的關係有泛化(Generalization)、實現(Realization)、依賴(Dependency)和關聯(Association)。其中關聯又分爲通常關聯關係和聚合關係(Aggregation),合成關係(Composition)。下面咱們結合實例理解這些關係。編程

基本概念

類圖(Class Diagram): 類圖是面向對象系統建模中最經常使用和最重要的圖,是定義其它圖的基礎。類圖主要是用來顯示系統中的類、接口以及它們之間的靜態結構和關係的一種靜態模型。網絡

類圖的3個基本組件:類名、屬性、方法。 異步

泛化(generalization):表示is-a的關係,是對象之間耦合度最大的一種關係,子類繼承父類的全部細節。直接使用語言中的繼承表達。在類圖中使用帶三角箭頭的實線表示,箭頭從子類指向父類。編程語言

實現(Realization):在類圖中就是接口和實現的關係。這個沒什麼好講的。在類圖中使用帶三角箭頭的虛線表示,箭頭從實現類指向接口。ide

依賴(Dependency):對象之間最弱的一種關聯方式,是臨時性的關聯。代碼中通常指由局部變量、函數參數、返回值創建的對於其餘對象的調用關係。一個類調用被依賴類中的某些方法而得以完成這個類的一些職責。在類圖使用帶箭頭的虛線表示,箭頭從使用類指向被依賴的類。函數

關聯(Association) : 對象之間一種引用關係,好比客戶類與訂單類之間的關係。這種關係一般使用類的屬性表達。關聯又分爲通常關聯、聚合關聯與組合關聯。後兩種在後面分析。在類圖使用帶箭頭的實線表示,箭頭從使用類指向被關聯的類。能夠是單向和雙向。工具

聚合(Aggregation) : 表示has-a的關係,是一種不穩定的包含關係。較強於通常關聯,有總體與局部的關係,而且沒有了總體,局部也可單獨存在。如公司和員工的關係,公司包含員工,但若是公司倒閉,員工依然能夠換公司。在類圖使用空心的菱形表示,菱形從局部指向總體。oop

組合(Composition) : 表示contains-a的關係,是一種強烈的包含關係。組合類負責被組合類的生命週期。是一種更強的聚合關係。部分不能脫離總體存在。如公司和部門的關係,沒有了公司,部門也不能存在了;調查問卷中問題和選項的關係;訂單和訂單選項的關係。在類圖使用實心的菱形表示,菱形從局部指向總體。性能

多重性(Multiplicity) : 一般在關聯、聚合、組合中使用。就是表明有多少個關聯對象存在。使用數字..星號(數字)表示。以下圖,一個割接通知能夠關聯0個到N個故障單。

聚合和組合的區別

這兩個比較難理解,重點說一下。聚合和組合的區別在於:聚合關係是「has-a」關係,組合關係是「contains-a」關係;聚合關係表示總體與部分的關係比較弱,而組合比較強;聚合關係中表明部分事物的對象與表明聚合事物的對象的生存期無關,一旦刪除了聚合對象不必定就刪除了表明部分事物的對象。組合中一旦刪除了組合對象,同時也就刪除了表明部分事物的對象。

實例分析

聯通客戶響應OSS。系統有故障單、業務開通、資源覈查、割接、業務重保、網絡品質性能等功能模塊。如今咱們抽出部分需求作爲例子講解。

你們能夠參照着類圖,好好理解。

1. 通知分爲通常通知、割接通知、重保通知。這個是繼承關係。

2. NoticeService和實現類NoticeServiceImpl是實現關係。

3. NoticeServiceImpl經過save方法的參數引用Notice,是依賴關係。同時調用了BaseDao完成功能,也是依賴關係。

4. 割接通知和故障單之間經過中間類(通知電路)關聯,是通常關聯。

5. 重保通知和預案庫間是聚合關係。由於預案庫能夠事先錄入,和重保通知沒有必然聯繫,能夠獨立存在。在系統中是手工從列表中選擇。刪除重保通知,不影響預案。

6. 割接通知和需求單之間是聚合關係。同理,需求單能夠獨立於割接通知存在。也就是說刪除割接通知,不影響需求單。

7. 通知和回覆是組合關係。由於回覆不能獨立於通知存在。也就是說刪除通知,該條通知對應的回覆也要級聯刪除。

通過以上的分析,相信你們對類的關係已經有比較好的理解了。你們有什麼其它想法或好的看法,歡迎拍磚。

PS:仍是那句話:以上類圖用Enterprise Architect 7.5所畫,在此推薦一下EA,很是不錯。能夠替代Visio和Rose了。Visio功能不夠強大,Rose過重。惟有EA比較合適。

 

 

參考二:

深刻淺出UML類圖
 

做者:劉偉 ,發佈於:2012-11-23,來源:CSDN

 

在UML 2.0的13種圖形中,類圖是使用頻率最高的UML圖之一。Martin Fowler在其著做《UML Distilled: A Brief Guide to the Standard Object Modeling Language, Third Edition》(《UML精粹:標準對象建模語言簡明指南(第3版)》)中有這麼一段:「If someone were to come up to you in a dark alley and say, 'Psst, wanna see a UML diagram?' that diagram would probably be a class diagram. The majority of UML diagrams I see are class diagrams.」(「若是有人在黑暗的小巷中向你走來並對你說:‘嘿,想不想看一張UML圖?’那麼這張圖頗有可能就是一張類圖,我所見過的大部分的UML圖都是類圖」),因而可知類圖的重要性。

類圖用於描述系統中所包含的類以及它們之間的相互關係,幫助人們簡化對系統的理解,它是系統分析和設計階段的重要產物,也是系統編碼和測試的重要模型依據。

1. 類

類(Class)封裝了數據和行爲,是面向對象的重要組成部分,它是具備相同屬性、操做、關係的對象集合的總稱。在系統中,每一個類都具備必定的職責,職責指的是類要完成什麼樣的功能,要承擔什麼樣的義務。一個類能夠有多種職責,設計得好的類通常只有一種職責。在定義類的時候,將類的職責分解成爲類的屬性和操做(即方法)。類的屬性即類的數據職責,類的操做即類的行爲職責。設計類是面向對象設計中最重要的組成部分,也是最複雜和最耗時的部分。

在軟件系統運行時,類將被實例化成對象(Object),對象對應於某個具體的事物,是類的實例(Instance)。

類圖(Class Diagram)使用出如今系統中的不一樣類來描述系統的靜態結構,它用來描述不一樣的類以及它們之間的關係。

在系統分析與設計階段,類一般能夠分爲三種,分別是實體類(Entity Class)、控制類(Control Class)和邊界類(Boundary Class),下面對這三種類加以簡要說明:

(1) 實體類:實體類對應系統需求中的每一個實體,它們一般須要保存在永久存儲體中,通常使用數據庫表或文件來記錄,實體類既包括存儲和傳遞數據的類,還包括操做數據的類。實體類來源於需求說明中的名詞,如學生、商品等。

(2) 控制類:控制類用於體現應用程序的執行邏輯,提供相應的業務操做,將控制類抽象出來能夠下降界面和數據庫之間的耦合度。控制類通常是由動賓結構的短語(動詞+名詞)轉化來的名詞,如增長商品對應有一個商品增長類,註冊對應有一個用戶註冊類等

(3) 邊界類:邊界類用於對外部用戶與系統之間的交互對象進行抽象,主要包括界面類,如對話框、窗口、菜單等。

在面向對象分析和設計的初級階段,一般首先識別出實體類,繪製初始類圖,此時的類圖也可稱爲領域模型,包括實體類及其它們之間的相互關係。

2. 類的UML圖示

在UML中,類使用包含類名、屬性和操做且帶有分隔線的長方形來表示,如定義一個Employee類,它包含屬性name、age和email,以及操做modifyInfo(),在UML類圖中該類如圖1所示:

圖1 類的UML圖示

圖1對應的Java代碼片斷以下:

public class Employee {
	private String name;
	private int age;
	private String email;
	
	public void modifyInfo() {
		......
	}
}

在UML類圖中,類通常由三部分組成:

(1) 第一部分是類名:每一個類都必須有一個名字,類名是一個字符串。

(2) 第二部分是類的屬性(Attributes):屬性是指類的性質,即類的成員變量。一個類能夠有任意多個屬性,也能夠沒有屬性

UML規定屬性的表示方式爲:

可見性 名稱:類型 [ = 缺省值 ]

其中:

  • 「可見性」表示該屬性對於類外的元素而言是否可見,包括公有(public)、私有(private)和受保護(protected)三種,在類圖中分別用符號+、-和#表示。
  • 「名稱」表示屬性名,用一個字符串表示。
  • 「類型」表示屬性的數據類型,能夠是基本數據類型,也能夠是用戶自定義類型。
  • 「缺省值」是一個可選項,即屬性的初始值。

(3) 第三部分是類的操做(Operations):操做是類的任意一個實例對象均可以使用的行爲,是類的成員方法。

UML規定操做的表示方式爲:

可見性 名稱(參數列表) [ : 返回類型]

其中:

  • 「可見性」的定義與屬性的可見性定義相同。
  • 「名稱」即方法名,用一個字符串表示。
  • 「參數列表」表示方法的參數,其語法與屬性的定義類似,參數個數是任意的,多個參數之間用逗號「,」隔開。
  • 「返回類型」是一個可選項,表示方法的返回值類型,依賴於具體的編程語言,能夠是基本數據類型,也能夠是用戶自定義類型,還能夠是空類型(void),若是是構造方法,則無返回類型。

在類圖2中,操做method1的可見性爲public(+),帶入了一個Object類型的參數par,返回值爲空(void);操做method2的可見性爲protected(#),無參數,返回值爲String類型;操做method3的可見性爲private(-),包含兩個參數,其中一個參數爲int類型,另外一個爲int[]類型,返回值爲int類型。

圖2 類圖操做說明示意圖

因爲在Java語言中容許出現內部類,所以可能會出現包含四個部分的類圖,如圖3所示:

圖3 包含內部類的類圖

類與類之間的關係(1)

在軟件系統中,類並非孤立存在的,類與類之間存在各類關係,對於不一樣類型的關係,UML提供了不一樣的表示方式。

1. 關聯關係

關聯(Association)關係是類與類之間最經常使用的一種關係,它是一種結構化關係,用於表示一類對象與另外一類對象之間有聯繫,如汽車和輪胎、師傅和徒弟、班級和學生等等。在UML類圖中,用實線鏈接有關聯關係的對象所對應的類,在使用Java、C#和C++等編程語言實現關聯關係時,一般將一個類的對象做爲另外一個類的成員變量。在使用類圖表示關聯關係時能夠在關聯線上標註角色名,通常使用一個表示二者之間關係的動詞或者名詞表示角色名(有時該名詞爲實例對象名),關係的兩端表明兩種不一樣的角色,所以在一個關聯關係中能夠包含兩個角色名,角色名不是必須的,能夠根據須要增長,其目的是使類之間的關係更加明確。

如在一個登陸界面類LoginForm中包含一個JButton類型的註冊按鈕loginButton,它們之間能夠表示爲關聯關係,代碼實現時能夠在LoginForm中定義一個名爲loginButton的屬性對象,其類型爲JButton。如圖1所示:

圖1 關聯關係實例

圖1對應的Java代碼片斷以下:

public class LoginForm {
private JButton loginButton; //定義爲成員變量
……
}

public class JButton {
    ……
}

在UML中,關聯關係一般又包含以下幾種形式:

(1) 雙向關聯

默認狀況下,關聯是雙向的。例如:顧客(Customer)購買商品(Product)並擁有商品,反之,賣出的商品總有某個顧客與之相關聯。所以,Customer類和Product類之間具備雙向關聯關係,如圖2所示:

圖2 雙向關聯實例

圖2對應的Java代碼片斷以下:

public class Customer {
private Product[] products;
……
}

public class Product {
private Customer customer;
……
}

(2) 單向關聯

類的關聯關係也能夠是單向的,單向關聯用帶箭頭的實線表示。例如:顧客(Customer)擁有地址(Address),則Customer類與Address類具備單向關聯關係,如圖3所示:

圖3 單向關聯實例

圖3對應的Java代碼片斷以下:

public class Customer {
private Address address;
……
}

public class Address {
……
}

(3) 自關聯

在系統中可能會存在一些類的屬性對象類型爲該類自己,這種特殊的關聯關係稱爲自關聯。例如:一個節點類(Node)的成員又是節點Node類型的對象,如圖4所示:

圖4 自關聯實例

圖4對應的Java代碼片斷以下:

public class Node {
private Node subNode;
……
}

(4) 多重性關聯

多重性關聯關係又稱爲重數性(Multiplicity)關聯關係,表示兩個關聯對象在數量上的對應關係。在UML中,對象之間的多重性能夠直接在關聯直線上用一個數字或一個數字範圍表示。

對象之間能夠存在多種多重性關聯關係,常見的多重性表示方式如表1所示:

表1 多重性表示方式列表

表示方式
多重性說明
1..1
表示另外一個類的一個對象只與該類的一個對象有關係
0..*
表示另外一個類的一個對象與該類的零個或多個對象有關係
1..*
表示另外一個類的一個對象與該類的一個或多個對象有關係
0..1
表示另外一個類的一個對象沒有或只與該類的一個對象有關係
m..n
表示另外一個類的一個對象與該類最少m,最多n個對象有關係 (m≤n)

例如:一個界面(Form)能夠擁有零個或多個按鈕(Button),可是一個按鈕只能屬於一個界面,所以,一個Form類的對象能夠與零個或多個Button類的對象相關聯,但一個Button類的對象只能與一個Form類的對象關聯,如圖5所示:

圖5 多重性關聯實例

圖5對應的Java代碼片斷以下:

public class Form {
private Button[] buttons; //定義一個集合對象
……
}

public class Button {
……
}

(5) 聚合關係

聚合(Aggregation)關係表示總體與部分的關係。在聚合關係中,成員對象是總體對象的一部分,可是成員對象能夠脫離總體對象獨立存在。在UML中,聚合關係用帶空心菱形的直線表示。例如:汽車發動機(Engine)是汽車(Car)的組成部分,可是汽車發動機能夠獨立存在,所以,汽車和發動機是聚合關係,如圖6所示:

圖6 聚合關係實例

在代碼實現聚合關係時,成員對象一般做爲構造方法、Setter方法或業務方法的參數注入到總體對象中,圖6對應的Java代碼片斷以下:

public class Car {
	private Engine engine;

    //構造注入
	public Car(Engine engine) {
		this.engine = engine;
	}
    
    //設值注入
public void setEngine(Engine engine) {
    this.engine = engine;
}
……
}

public class Engine {
	……
} 

(6) 組合關係

組合(Composition)關係也表示類之間總體和部分的關係,可是在組合關係中總體對象能夠控制成員對象的生命週期,一旦總體對象不存在,成員對象也將不存在,成員對象與總體對象之間具備同生共死的關係。在UML中,組合關係用帶實心菱形的直線表示。例如:人的頭(Head)與嘴巴(Mouth),嘴巴是頭的組成部分之一,並且若是頭沒了,嘴巴也就沒了,所以頭和嘴巴是組合關係,如圖7所示:

圖7 組合關係實例

在代碼實現組合關係時,一般在總體類的構造方法中直接實例化成員類,圖7對應的Java代碼片斷以下:

public class Head {
	private Mouth mouth;

	public Head() {
		mouth = new Mouth(); //實例化成員類
	}
……
}

public class Mouth {
	……
} 

類與類之間的關係(2)

2. 依賴關係

依賴(Dependency)關係是一種使用關係,特定事物的改變有可能會影響到使用該事物的其餘事物,在須要表示一個事物使用另外一個事物時使用依賴關係。大多數狀況下,依賴關係體如今某個類的方法使用另外一個類的對象做爲參數。在UML中,依賴關係用帶箭頭的虛線表示,由依賴的一方指向被依賴的一方。例如:駕駛員開車,在Driver類的drive()方法中將Car類型的對象car做爲一個參數傳遞,以便在drive()方法中可以調用car的move()方法,且駕駛員的drive()方法依賴車的move()方法,所以類Driver依賴類Car,如圖1所示:

圖1 依賴關係實例

在系統實施階段,依賴關係一般經過三種方式來實現,第一種也是最經常使用的一種方式是如圖1所示的將一個類的對象做爲另外一個類中方法的參數,第二種方式是在一個類的方法中將另外一個類的對象做爲其局部變量,第三種方式是在一個類的方法中調用另外一個類的靜態方法。圖1對應的Java代碼片斷以下:

public class Driver {
	public void drive(Car car) {
		car.move();
	}
    ……
}

public class Car {
	public void move() {
		......
	}
    ……
}  

3. 泛化關係

泛化(Generalization)關係也就是繼承關係,用於描述父類與子類之間的關係,父類又稱做基類或超類,子類又稱做派生類。在UML中,泛化關係用帶空心三角形的直線來表示。在代碼實現時,咱們使用面向對象的繼承機制來實現泛化關係,如在Java語言中使用extends關鍵字、在C++/C#中使用冒號「:」來實現。例如:Student類和Teacher類都是Person類的子類,Student類和Teacher類繼承了Person類的屬性和方法,Person類的屬性包含姓名(name)和年齡(age),每個Student和Teacher也都具備這兩個屬性,另外Student類增長了屬性學號(studentNo),Teacher類增長了屬性教師編號(teacherNo),Person類的方法包括行走move()和說話say(),Student類和Teacher類繼承了這兩個方法,並且Student類還新增方法study(),Teacher類還新增方法teach()。如圖2所示:

圖2 泛化關係實例

圖2對應的Java代碼片斷以下:

//父類
public class Person {
protected String name;
protected int age;

public void move() {
        ……
}

    public void say() {
    ……
    }
}

//子類
public class Student extends Person {
private String studentNo;

public void study() {
    ……
    }
}

//子類
public class Teacher extends Person {
private String teacherNo;

public void teach() {
    ……
    }
}

4. 接口與實現關係

在不少面嚮對象語言中都引入了接口的概念,如Java、C#等,在接口中,一般沒有屬性,並且全部的操做都是抽象的,只有操做的聲明,沒有操做的實現。UML中用與類的表示法相似的方式表示接口,如圖3所示:

圖3 接口的UML圖示

接口之間也能夠有與類之間關係相似的繼承關係和依賴關係,可是接口和類之間還存在一種實現(Realization)關係,在這種關係中,類實現了接口,類中的操做實現了接口中所聲明的操做。在UML中,類與接口之間的實現關係用帶空心三角形的虛線來表示。例如:定義了一個交通工具接口Vehicle,包含一個抽象操做move(),在類Ship和類Car中都實現了該move()操做,不過具體的實現細節將會不同,如圖4所示:

圖4 實現關係實例

實現關係在編程實現時,不一樣的面嚮對象語言也提供了不一樣的語法,如在Java語言中使用implements關鍵字,而在C++/C#中使用冒號「:」來實現。圖4對應的Java代碼片斷以下:

public interface Vehicle {
public void move();
}

public class Ship implements Vehicle {
public void move() {
    ……
    }
}

public class Car implements Vehicle {
public void move() {
    ……
    }
}

實例分析1——登陸模塊

某基於C/S的即時聊天系統登陸模塊功能描述以下:

用戶經過登陸界面(LoginForm)輸入帳號和密碼,系統將輸入的帳號和密碼與存儲在數據庫(User)表中的用戶信息進行比較,驗證用戶輸入是否正確,若是輸入正確則進入主界面(MainForm),不然提示「輸入錯誤」。

根據以上描述繪製初始類圖。

參考解決方案:

參考類圖以下:

考慮到系統擴展性,在本實例中引入了抽象數據訪問接口IUserDAO,再將具體數據訪問對象注入到業務邏輯對象中,可經過配置文件(如XML文件)等方式來實現,將具體的數據訪問類類名存儲在配置文件中,若是須要更換新的具體數據訪問對象,只需修改配置文件便可,原有程序代碼無須作任何修改。

類說明:

類 名
說 明
LoginForm 登陸窗口,省略界面組件和按鈕事件處理方法(邊界類)
LoginBO 登陸業務邏輯類,封裝實現登陸功能的業務邏輯(控制類)
IUserDAO 抽象數據訪問類接口,聲明對User表的數據操做方法,省略除查詢外的其餘方法(實體類)
UserDAO 具體數據訪問類,實現對User表的數據操做方法,省略除查詢外的其餘方法(實體類)
MainForm 主窗口(邊界類)

方法說明:

方法名
說 明
LoginForm類的LoginForm()方法 LoginForm構造函數,初始化實例成員
LoginForm類的validate()方法 界面類的驗證方法,經過調用業務邏輯類LoginBO的validate()方法實現對用戶輸入信息的驗證
LoginBO類的validate()方法 業務邏輯類的驗證方法,經過調用數據訪問類的findUserByAccAndPwd()方法驗證用戶輸入信息的合法性
LoginBO類的setIUserDAO()方法 Setter方法,在業務邏輯對象中注入數據訪問對象(注意:此處針對抽象數據訪問類編程
IUserDAO接口的findUserByAccAndPwd()方法 業務方法聲明,經過用戶帳號和密碼在數據庫中查詢用戶信息,判斷該用戶身份的合法性
UserDAO類的findUserByAccAndPwd()方法 業務方法實現,實如今IUserDAO接口中聲明的數據訪問方法

實例分析2——註冊模塊

某基於Java語言的C/S軟件須要提供註冊功能,該功能簡要描述以下:

用戶經過註冊界面(RegisterForm)輸入我的信息,用戶點擊「註冊」按鈕後將輸入的信息經過一個封裝用戶輸入數據的對象(UserDTO)傳遞給操做數據庫的數據訪問類,爲了提升系統的擴展性,針對不一樣的數據庫可能須要提供不一樣的數據訪問類,所以提供了數據訪問類接口,如IUserDAO,每個具體數據訪問類都是某一個數據訪問類接口的實現類,如OracleUserDAO就是一個專門用於訪問Oracle數據庫的數據訪問類。

根據以上描述繪製類圖。爲了簡化類圖,我的信息僅包括帳號(userAccount)和密碼(userPassword),且界面類無需涉及界面細節元素。

參考解決方案:

在以上功能說明中,能夠分析出該系統包括三個類和一個接口,這三個類分別是註冊界面類RegisterForm、用戶數據傳輸類UserDTO、Oracle用戶數據訪問類OracleUserDAO,接口是抽象用戶數據訪問接口IUserDAO。它們之間的關係以下:

(1) 在RegisterForm中須要使用UserDTO類傳輸數據且須要使用數據訪問類來操做數據庫,所以RegisterForm與UserDTO和IUserDAO之間存在關聯關係,在RegisterForm中能夠直接實例化UserDTO,所以它們之間可使用組合關聯。

(2) 因爲數據庫類型須要靈活更換,所以在RegisterForm中不能直接實例化IUserDAO的子類,能夠針對接口IUserDAO編程,再經過注入的方式傳入一個IUserDAO接口的子類對象(在本書後續章節中將學習如何具體實現),所以RegisterForm和IUserDAO之間具備聚合關聯關係。

(3) OracleUserDAO是實現了IUserDAO接口的子類,所以它們之間具備類與接口的實現關係。

(4) 在聲明IUserDAO接口的增長用戶信息方法addUser()時,須要將在界面類中實例化的UserDTO對象做爲參數傳遞進來,而後取出封裝在UserDTO對象中的數據插入數據庫,所以addUser()方法的函數原型能夠定義爲:public boolean addUser(UserDTO user),在IUserDAO的方法addUser()中將UserDTO類型的對象做爲參數,故IUserDAO與UserDTO存在依賴關係。

經過以上分析,該實例參考類圖如圖1所示:

圖1 註冊功能參考類圖

注意:在繪製類圖或其餘UML圖形時,能夠經過註釋(Comment)來對圖中的符號或元素進行一些附加說明,若是須要詳細說明類圖中的某一方法的功能或者實現過程,可使用如圖2所示表示方式:

圖2 類圖註釋實例

實例分析3——售票機控制程序

某運輸公司決定爲新的售票機開發車票銷售的控制軟件。圖I給出了售票機的面板示意圖以及相關的控制部件。

圖I 售票機面板示意圖

售票機相關部件的做用以下所述:

(1) 目的地鍵盤用來輸入行程目的地的代碼(例如,200表示總站)。

(2) 乘客能夠經過車票鍵盤選擇車票種類(單程票、屢次往返票和座席種類)。

(3) 繼續/取消鍵盤上的取消按鈕用於取消購票過程,繼續按鈕容許乘客連續購買多張票。

(4) 顯示屏顯示全部的系統輸出和用戶提示信息。

(5) 插卡口接受MCard(現金卡),硬幣口和紙幣槽接受現金。

(6) 打印機用於輸出車票。

(7) 全部部件都可實現自檢並恢復到初始狀態。

現採用面向對象方法開發該系統,使用UML進行建模,繪製該系統的初始類圖。

參考解決方案:

參考類圖以下:

類說明:

類 名
說 明
Component 抽象部件類,全部部件類的父類
Keyboard 抽象鍵盤類
ActionKeyboard 繼續/取消鍵盤類
TicketKindKeyboard 車票種類鍵盤類
DestinationKeyboard 目的地鍵盤類
Screen 顯示屏類
CardDriver 卡驅動器類
CashSlot 現金(硬幣/紙幣)槽類
Printer 打印機類
TicketSoldSystem 售票系統類

方法說明:

方法名
說 明
Component 的init()方法 初始化部件
Component 的doSeltTest()方法 自檢
Keyboard的getSelectedKey()方法 獲取按鍵值
ActionKeyboard的getAction()方法 繼續/取消鍵盤事件處理
TicketKindKeyboard的getTicketKind()方法 車票種類鍵盤事件處理
DestinationKeyboard的getDestinationCode()方法 目的地鍵盤事件處理
Screen的showText()方法 顯示信息
CardDriver的getCredit()方法 獲取金額
CardDriver的debitFare()方法 更新卡餘額
CardDriver的ejectMCard()方法 退卡
CashSlot的getCredit()方法 獲取金額
Printer的printTicket()方法 打印車票
Printer的ejectTicket()方法 出票
TicketSoldSystem的verifyCredit()方法 驗證金額
TicketSoldSystem的calculateFare()方法 計算費用

 

 

參考三:

在UML的

類圖中,常見的有如下幾種關係: 泛化(Generalization),  實現(Realization), 關聯(Association), 聚合(Aggregation), 組合(Composition), 依賴(Dependency)

 

1.       泛化(Generalization)

【泛化關係】:是一種繼承關係, 表示通常與特殊的關係, 它指定了子類如何特化父類的全部特徵和行爲. 例如:老虎是動物的一種, 即有老虎的特性也有動物的共性.

【箭頭指向】:帶三角箭頭的實線,箭頭指向父類

 

 

2. 實現(Realization)

【實現關係】:是一種類與接口的關係, 表示類是接口全部特徵和行爲的實現.

【箭頭指向】:帶三角箭頭的虛線,箭頭指向接口

 

3. 關聯(Association)

【關聯關係】:是一種擁有的關係, 它使一個類知道另外一個類的屬性和方法;如:老師與學生,丈夫與妻子

關聯能夠是雙向的,也能夠是單向的。雙向的關聯能夠有兩個箭頭或者沒有箭頭,單向的關聯有一個箭頭。

【代碼體現】:成員變量

【箭頭及指向】:帶普通箭頭(或實心三角形箭頭)的實心線,指向被擁有者

 

上圖中,老師與學生是雙向關聯,老師有多名學生,學生也可能有多名老師。但學生與某課程間的關係爲單向關聯,一名學生可能要上多門課程,課程是個抽象的東西他不擁有學生。

 

上圖爲自身關聯:

 

4. 聚合(Aggregation)

【聚合關係】:是總體與部分的關係, 且部分能夠離開總體而單獨存在. 如車和輪胎是總體和部分的關係, 輪胎離開車仍然能夠存在.

聚合關係是關聯關係的一種,是強的關聯關係;關聯和聚合在語法上沒法區分,必須考察具體的邏輯關係。

【代碼體現】:成員變量

【箭頭及指向】:帶空心菱形的實心線,菱形指向總體

 

 

5. 組合(Composition)

【組合關係】:是總體與部分的關係, 但部分不能離開總體而單獨存在. 如公司和部門是總體和部分的關係, 沒有公司就不存在部門.

       組合關係是關聯關係的一種,是比聚合關係還要強的關係,它要求普通的聚合關係中表明總體的對象負責表明部分的對象的生命週期

【代碼體現】:成員變量

【箭頭及指向】:帶實心菱形的實線,菱形指向總體

 

 

6. 依賴(Dependency)

【依賴關係】:是一種使用的關係,  即一個類的實現須要另外一個類的協助, 因此要儘可能不使用雙向的互相依賴.

【代碼表現】:局部變量、方法的參數或者對靜態方法的調用

【箭頭及指向】:帶箭頭的虛線,指向被使用者

 

 

 

各類關係的強弱順序:

泛化 = 實現 > 組合 > 聚合 > 關聯 > 依賴

下面這張UML圖,比較形象地展現了各類類圖關係:

 

 

====================================================

序列圖主要用於展現對象之間交互的順序。

序列圖將交互關係表示爲一個二維圖。縱向是時間軸,時間沿豎線向下延伸。橫向軸表明了在協做中各獨立對象的類元角色。類元角色用生命線表示。當對象存在時,角色用一條虛線表示,當對象的過程處於激活狀態時,生命線是一個雙道線。

消息用從一個對象的生命線到另外一個對象生命線的箭頭表示。箭頭以時間順序在圖中從上到下排列。

 

序列圖中涉及的元素:

1.   生命線:

生命線名稱可帶下劃線。當使用下劃線時,意味着序列圖中的生命線表明一個類的特定實體。

 

 

2.       同步消息

發送人在它繼續以前,將等待同步消息響應

 

3.       異步消息

在發送方繼續以前,無需等待響應的消息

 

4.       註釋

 

5.       約束

約束的符號很簡單;格式是: [Boolean Test]

 

6.       組合片斷

組合片斷 用來解決交互執行的條件及方式。 它容許在序列圖中直接表示邏輯組件,用於經過指定條件或子進程的應用區域,爲任何生命線的任何部分定義特殊條件和子進程。

經常使用的組合片斷有:

a.       抉擇(Alt)

抉擇用來指明在兩個或更多的消息序列之間的互斥的選擇,至關於經典的if..else..。

抉擇在任何場合下只發生一個序列。 能夠在每一個片斷中設置一個臨界來指示該片斷能夠運行的條件。 else 的臨界指示其餘任何臨界都不爲 True 時應運行的片斷。 若是全部臨界都爲 False 而且沒有 else,則不執行任何片斷。

 

 

b.       選項(Opt)

包含一個可能發生或不發生的序列

c.       循環(Loop)

片斷重複必定次數。 能夠在臨界中指示片斷重複的條件。

 

d.       並行(Par)

 

下表列出了經常使用的組合片斷:

片斷類型

名稱

說明

Opt

選項

包含一個可能發生或可能不發生的序列。 能夠在臨界中指定序列發生的條件。

Alt

抉擇

包含一個片斷列表,這些片斷包含備選消息序列。 在任何場合下只發生一個序列。

能夠在每一個片斷中設置一個臨界來指示該片斷能夠運行的條件。 else 的臨界指示其餘任何臨界都不爲 True 時應運行的片斷。 若是全部臨界都爲 False 而且沒有 else,則不執行任何片斷。

Loop

循環

片斷重複必定次數。 能夠在臨界中指示片斷重複的條件。

Loop 組合片斷具備「Min」「Max」屬性,它們指示片斷能夠重複的最小和最大次數。 默認值是無限制。

Break

中斷

若是執行此片斷,則放棄序列的其他部分。 可使用臨界來指示發生中斷的條件。

Par

並行

並行處理。 片斷中的事件能夠交錯。

Critical

關鍵

用在 Par 或 Seq 片斷中。 指示此片斷中的消息不得與其餘消息交錯。

Seq

弱順序

有兩個或更多操做數片斷。 涉及同一輩子命線的消息必須以片斷的順序發生。 若是消息涉及的生命線不一樣,來自不一樣片斷的消息可能會並行交錯。

Strict

強順序

有兩個或更多操做數片斷。 這些片斷必須按給定順序發生。

 

有關如何解釋序列的片斷

默認狀況下,序列圖代表可能發生的一系列消息。 在運行的系統中,可能會出現您未選擇顯示在關係圖上的其餘消息。

如下片斷類型可用於更改此釋義:

片斷類型

名稱

說明

Consider

考慮

指定此片斷描述的消息列表。 其餘消息可發生在運行的系統中,但對此描述來講意義不大。

「Messages」屬性中鍵入該列表。

Ignore

忽略

此片斷未描述的消息列表。 這些消息可發生在運行的系統中,但對此描述來講意義不大。

「Messages」屬性中鍵入該列表。

Assert

斷言

操做數片斷指定惟一有效的序列。 一般用在 Consider 或 Ignore 片斷中。

Neg

否認

此片斷中顯示的序列不得發生。 一般用在 Consider 或 Ignore 片斷中。

 


====================================================

用例圖主要用來描述 用戶、需求、系統功能單元 之間的關係。它展現了一個外部用戶可以觀察到的系統功能模型圖。

【用途】:幫助開發團隊以一種可視化的方式理解系統的功能需求。

 

用例圖所包含的元素以下:

1.       參與者(Actor)

表示與您的應用程序或系統進行交互的用戶、組織或外部系統。用一個小人表示。

 

2.       用例(Use Case)

 用例就是外部可見的系統功能,對系統提供的服務進行描述。 用橢圓表示

3.       子系統(Subsystem)

用來展現系統的一部分功能,這部分功能聯繫緊密。

 

4.       關係

用例圖中涉及的關係有:關聯、泛化、包含、擴展;

以下表所示:

關係類型

說明

表示符號

關聯

參與者與用例間的關係

泛化

參與者之間或用例之間的關係

包含

用例之間的關係

擴展

用例之間的關係

a.       關聯(Association)

表示參與者與用例之間的通訊,任何一方均可發送或接受消息。

【箭頭指向】:指向消息接收方

 

 

b.      泛化(Inheritance)

就是一般理解的繼承關係,子用例和父用例類似,但表現出更特別的行爲;子用例將繼承父用例的全部結構、行爲和關係。子用例可使用父用例的一段行爲,也能夠重載它。父用例一般是抽象的。

【箭頭指向】:指向父用例

c.       包含(Include)

包含關係用來把一個較複雜用例所表示的功能分解成較小的步驟;

【箭頭指向】:指向分解出來的功能用例

 

d.      擴展(Extend)

    擴展關係是指 用例功能的延伸,至關於爲基礎用例提供一個附加功能。

   【箭頭指向】:指向基礎用例

 

 

e.       依賴(Dependency)

以上4中關係,是UML定義的標準關係。 但VS2010的用例模型圖中,添加了依賴關係,用帶箭頭的虛線表示

表示源用例依賴於目標用例;

【箭頭指向】:指向被依賴項

 

5.       項目(Artifact)

用例圖雖然是用來幫助人們形象地理解功能需求,但卻沒多少人可以通看懂它。不少時候跟用戶交流甚至用Excel都比用例圖強,VS2010中引入了「項目」這樣一個元素,以便讓開發人員可以在用例圖中連接一個普通文檔。

用依賴關係把某個用例依賴到項目上

 

而後把項目-》屬性 的Hyperlink 設置到你的文檔上

這樣當你在用例圖上 雙擊項目時,就會打開相關聯的文檔。

 

6.       註釋(Comment)

 

 

包含(include)、擴展(extend)、泛化(Inheritance) 的區別:

條件性:泛化中的子用例和include中的被包含的用例會無條件發生,而extend中的延伸用例的發生是有條件的;

直接性:泛化中的子用例和extend中的延伸用例爲參與者提供直接服務,而include中被包含的用例爲參與者提供間接服務。

對extend而言,延伸用例並不包含基礎用例的內容,基礎用例也不包含延伸用例的內容。

對Inheritance而言,子用例包含基礎用例的全部內容及其和其餘用例或參與者之間的關係;

 

一個用例圖示例:

 

 

牢騷:

感受用例圖還不成熟,並不能很好地表達系統的需求, 沒有UML背景的用戶幾乎不知道畫的些什麼。

其次,包含關係、擴展關係 的箭頭符號居然是一樣的箭頭,僅靠上方寫個文字來加以區別,翻譯成其餘語言的話,幾乎就不知道表明什麼意思。  擴展關係的箭頭朝向也很難理解,爲什麼要指向基用例,而不指向擴展用例

VS2010添加的「項目」元素,是個很好的創新,可以在用例圖中關聯word,excel這些文檔。但爲何不把這些功能直接集成到用例裏面,雙擊用例就彈出一份文檔豈不更容易理解,非要多此一舉地加一個元件,僅僅爲了提供個連接功能。

 

 

用例描述表:

鑑於用列圖並不能清楚地表達功能需求,開發中你們一般用描述表來補充某些不易表達的用例,下圖的表給你們提供一個參考:

相關文章
相關標籤/搜索