UML複習和麵向物件設計
UML筆記
UML的主要內容就是畫圖和麵向物件的分析設計。
畫圖的過程中我們要注意每種圖的元素和每種圖的作用。
面向物件的分析設計中我們要了解OA和OD的思想。
這些都是考試的重點
1. 用例圖
1.1 什麼是用例
用例是一個活動者(Actor)使用系統的一項功能時所進行的互動過程的一個文字描述序列。
用例的作用
- 用例是軟體從需求分析到最終實現的最後一步,它顯示了使用者希望系統實現的功能,有利於使用者和軟體開發人員之間的溝通。
- 用例視覺化地表達了使用者的需求和系統功能,克服了純文字的說明性不足。
- 用例是從外部定義系統,使用者不用關心繫統內部是如何實現各個功能的。
Actor的描述
Actor包括系統之外的需要使用系統與系統進行互動的事物,包括人、裝置、外部系統等。
用例的讀者
開發人員、使用者、專案經理、測試人員等
用例中的關係
Actor與uc之間的關係
actor與use case之間是關聯關係,所以他們之間用直線連線
uc與uc之間的關係
- 泛化
泛化關係是父子關係,用空心三角箭頭表示。箭頭指向父uc - 包含
包含關係是完成一個uc動作同時需要完成的動作,一般是多個uc做之前都需要完成這個動作我們把它抽象為一個包含關係,就是很多uc都包含這個uc。
包含關係使用虛線箭頭表示,箭頭指向被包含的這個uc。 - 擴充套件
擴充套件關係是我在當前uc上擴展出新的uc,但是我不一定要做這個uc的關係。
擴充套件關係也是用虛線箭頭表示,箭頭指向需要擴充套件的當前uc。
1.2 如何畫一個用例圖
確定系統
用例圖本身就是為系統設計的,一般我要做的這個東西就是系統。
確定actors
識別活動者一般有以下幾個思路
- 誰使用了系統的功能
- 誰修改了系統的資料
- 誰從系統處得到資訊
- 誰需要對系統進行維護
- 系統需要哪些硬體裝置的支援?
確定use case
用例例項
語法測試:【使用者】使用系統來【用例】
用例例項是在系統中執行的一系列動作,這些動作將產生活動者想要的價值結果。一個用例是由多個用例例項組成的。
避免CURD
確定uc的時候很容易犯的錯誤是看到增加、修改、查閱和刪除等操作就把他們列為use case,這樣會花費自己很多精力但得不償失。
1.3 案例:郵箱系統
目標:構建一個語音郵箱系統
郵箱系統描述:
語音郵箱系統中,可以為每個系統使用者(郵箱主人)分配一個語音郵箱號碼.
進行留言時, 撥打語音郵箱系統的主號碼, 在聽到提示音“請輸入郵箱號”後,輸入語音郵箱號,聽到主人設定的問候語後,進行留言然後結束通話電話.
郵箱主人撥打語音郵箱系統的主號碼,在聽到提示音“請輸入郵箱號”後,輸入語音郵箱號,聽到主人設定的問候語後, 輸入密碼進行郵箱管理. 此時系統提供三種服務:1.接收資訊; 2.更改問候語; 3.更改密碼.其中接收留言包括收聽新留言、儲存留言、刪除留言等。
確定系統:
郵箱系統
確定actor
郵箱主人和留言者
確定use case
共同:
- 撥打語音郵箱
郵箱主人:
得到語音郵箱號碼- 接受資訊
- 更改問候語
- 更改密碼
留言人:
- 給郵箱主人留言
畫出用例圖
這張圖很精妙,可以看出上面3步走的時候遇到的一些問題和對use case之間關係的理解。
總結
use case不單純是動作,而應該是actor想要經過某一個操作達到某一個效果。(這句話有些彆扭,但是在理)。在郵箱系統案例中:
郵箱主人想完成的互動:
- 接受資訊
- 更改問候語
- 更改密碼
留言人想完成的互動:
- 留言
這4個互動過程都可以抽象為use case,但是主人和留言人想要完成以上4個互動的時候都需要在語音郵箱系統撥號,所以這就是一個多個uc抽象出來的帶有include屬性的use case。郵箱主人想要修改系統資訊,還需要登入系統。
以上”撥打郵箱號碼“,”登入系統“就是分析過程中漏掉的兩個use case
2. 類圖
2.1 介紹類圖
作用
- 為開發人員提供模仿現實世界的表達方式
- 以使用者的術語與客戶進行交流,方便促使客戶說出需要解決的重要細節。
2.2 類與類之間的關係
- 泛化
泛化就是繼承關係。實線三角箭頭指向父類。 - 介面
interface嘛。虛線三角箭頭指向父類。 - 組合
整體由部分組成,部分可以獨立於整體而存在。實心菱形箭頭指向整體類。 - 聚合
整體由部分組成,部分不可以獨立於整體而存在。空心菱形箭頭指向整體類。 - 關聯
擁有的關係,一個類知道並可以呼叫另一個類的屬性和方法。
雙向關聯:老師可以有多名學生,而一個學生也可以有多名老師。
單向關聯:一個學生可以有多門課程,但是課程是抽象類無法擁有學生。 - 依賴
一個類的實現需要另一個類的幫助。
依賴關係用虛線箭頭表示。箭頭指向被依賴的物件。
2.3 類的版型
邊界類
邊界類是系統與外界的皎潔。如UI、窗體等類。
控制類
控制類用於體現應用程式的執行邏輯,提供相應的業務操作,將控制類抽象出來可以降低介面和資料庫之間的耦合度。
控制類一般是由動賓結構的短語(動詞+名詞)轉化來的名詞,如增加商品對應有一個商品增加類,註冊對應有一個使用者註冊類等
實體類
實體類儲存要放進持久儲存體(資料庫/檔案等)的資訊。一般我們建立的類都是實體類,比如書類、計算機類等。
2.4 類圖的抽象層次
2.5 如何構造類圖
- 尋找案例中的名詞
- CRC原則(Class、Responsibility、Collaboration)
案例:圖書管理系統
2.6 物件圖
3. 順序圖和協作圖
3.1 順序圖
基本概念
順序圖顯示的是物件之間互動的圖,按照時間順序排列。時序圖是一個模型,用於描述物件如何隨著時間在某些行為方面進行協作。
順序圖的命名
- objectName:className
- :className
- objectName
所以看到奇怪的命名方式不要感到害怕
構成要素
- 物件
- 生命線
- 控制焦點
案例:圖書管理系統
案例描述:
課件裡的案例比較奇怪,邊界類比較少講但是在這個案例裡用了很多。會顯得比較亂。
常見問題
- 訊息迴圈傳送
*[i:= 1..n ]:Message2() - 訊息條件傳送
1.[a>b]:message()
2.使用文字說明 - 類圖和順序圖中物件的關係
需要相互參考、相互補充、相互協調
3.2 協作圖
概念
協作圖是表示物件間的互動圖,側重強調物件間的協作。
轉換成協作圖也比較容易,找到最開始的類,然後根據開始類延伸出一系列的類,類似畫腦圖一樣的方式畫出來就是協作圖了。
如果一個協作圖中的兩個物件之間的互動超過了兩個該怎麼畫這樣的協作圖?
答:一條狀態線上可以有多個互動,也就是多個箭頭。➡️➡️
3.3 順序圖&協作圖
相同
- 都支援所有的訊息型別
- 都確定了傳送者和接受者的責任
- 都能在一定程度上衡量系統的耦合度
不同
- 協作圖不能反映物件的建立、撤銷等操作
- 順序圖強調的是時間順序上的互動,協作圖強調的是物件與物件之間的的互動
- 協作圖必須要有訊息的序列號
4. 狀態圖和活動圖
4.1 狀態圖
定義
狀態圖描述的是一個物件生命週期中的狀態序列,以及引起狀態變化的事件和伴隨狀態變化後的動作。
組成狀態圖的元素
- 實心圓圈:初態
- 實心圓圈外一個圈:終態
- 圓角矩形:狀態
- 箭頭:轉換。描述包括觸發事件、監護條件和動作等。turnOn[water exists]/boil water
細節
- 可以設定某個狀態進入和退出的時候執行什麼:
entry/balabala和exit/balabala - H:
表示歷史狀態
4.2 活動圖
定義
活動圖是描述系統行為的模型,用來描述過程中活動及其遷移。
活動圖中可以包含多個物件,在圖中 有客戶、系統和供應商三個物件。
組成活動圖的元素
- 實心圓圈:初態
- 實心圓圈外一個圈:終態
- 橢圓矩形:活動節點
- 菱形:分支與監護條件
- 粗直線與箭頭:分岔與匯合
- (泳道)(物件流)
4.3 狀態圖&活動圖
相同
- 都是對系統的動態行為建模。
不同
- 狀態圖主要表示物件之間的互動關係,活動圖主要表示過程中活動的互動關係。
- 狀態圖中能夠表現出併發
5. 構件圖與部署圖
5.1 構件圖&部署圖
構件圖用來建模系統的各個構件,包括原始碼檔案、指令碼檔案、可執行檔案等。它們是通過關係或者包的形式組織在一起的。構件圖可以幫助我們了構件實現了軟體的哪些功能和構件位於軟體的什麼位置。
部署圖幫助我們瞭解各個構件駐留在什麼硬體位置,以及硬體節點之間的互動關係。
5.2 構件圖
構件是系統中可更換的程式碼模組。
構件圖的解讀
- 構件可以由構件組成
- 構件之間的關係主要是依賴:include、import和implement等。
關係表示為虛線箭頭上的文字 - 構件還可以和類圖中的物件產生聯絡。
5.3 部署圖
案例:web server
描述:
例 建模一個網上掃描系統的部署圖。其詳細的需求如下所示:
掃描器通過內部的PCI匯流排連線到網絡卡。需要編寫程式碼來控制掃描器,程式碼駐留在掃描器內部。
掃描器通過無線網絡卡與插入到Web伺服器KONG的無線hub通訊,伺服器通過HTTP協議向客戶PC機提供Web頁。
Web伺服器安裝定製的Web伺服器軟體,通過專用資料訪問構件與產品資料庫互動。
在客戶的PC機上將提供專用的瀏覽器軟體,它執行產品查詢外掛,只與定製的Web伺服器通訊。
畫部署圖的過程
-
確定節點
注意案例中出現的硬體中網絡卡和無限模組的關係。所以最後確定下來的節點有:
Scanner、NetworkCard、WirelessHub、KONG:WebServer和ClientPC。共5個
-
新增通訊關係
根據案例的描述很容易確定通訊關係
-
新增構件
在硬體中有什麼軟體基本上就是需要尋找的構件。本案例中把DB作為一個構件而不是一個硬體放在部署圖中,可能是因為確實需要用到的地方實在比較小不作為一個硬體。
-
確定關聯關係
easy
6. GRASP原則
GRASP(General Responsibility Assignment Software Patterns),中文名稱為“通用職責分配軟體模式”,GRASP一共包括9種模式,它們描述了物件設計和職責分配的基本原則。
案例:購物車、商品
6.1 基本模式
資訊專家(Expert)
通俗點來講,就是一個類只幹該乾的事情,不該乾的事情不幹。在系統設計時,需要將職責分配給具有實現這個職責所需要資訊的類。資訊專家模式對應於面向物件設計原則中的單一職責原則。
創造者(Creator)
如果符合下面的一個或者多個條件,則可將建立類A例項的職責分配給類B:
- B包含A;
- B聚合A;
- B擁有初始化A的資料並在建立類A的例項時將資料傳遞給類A;
- B記錄A的例項;
- B頻繁使用A。
此時,我們稱類B是類A物件的建立者。如果符合多個條件,類B聚合或者包含類A的條件優先。
低耦合模式(Coupling)
耦合是評價一個系統中各個元素之間連線或依賴強弱關係的尺度
為了降低改變帶來的影響和類與類之間的依賴,並提高重用性提出了低耦合的思想。
低耦合的基本原則
-
Don't Talk To Strangers
不需要通訊的兩個類就誰也別理誰好了。
-
Transfer
如果一個職能分配給A不合適(提高了耦合度或者不符合資訊專家原則),可以把這個職能分配給和A有連線的B
-
no connection between inner class
兩個不同模組的內部類之間不能直接連線
高內聚模式(Cohesion)
內聚是評價一個元素的職責被關聯和關注強弱的尺度。
在一個低內聚的類中會執行很多互不相關的操作,操作與操作之間沒有聯絡會顯得這個類非常雜亂,難以理解。
控制器模式(Controller)
問題:誰應該負責處理一個輸入系統事件?
分析:一個控制器是接受並處理系統事件的非圖形使用者介面的物件。通常一個控制器需要把接收的任務委託給其他物件,它只負責控制和協調,本身不完成太多的功能。控制器不用包含太多的業務邏輯,所以一個系統可以也應該設計多個控制器實現對不同模組的控制。
6.2 拓展模式
多型(Polymorphism)
就是我們學習的多型,可以通過不同的子類實現不同的功能。
純虛構(Fabrication)
目的
純虛構模式用來處理低耦合與高內聚之間的矛盾。高內聚需要拆分出更多數量的類,但是物件之間需要協作來完成任務,這又造成了高耦合,反之亦然。
定義
和C++中的純虛擬函式類似,將實體類中的一部分功能抽象出來成為純虛類。
中介模式(Indirection)
不影響耦合和情況下把兩個類連線起來
受保護變化模式(Variation)
定義
預先找出不穩定的變化點,使用統一的介面封裝起來,如果未來發生變化的時候,可以通過介面擴充套件新的功能,而不需要去修改原來舊的實現。也可以把這個模式理解為OCP(開閉原則)原則,就是說一個軟體實體應當對擴充套件開發,對修改關閉。
6.3 補充:單一職責原則
“就一個類而言,應該僅有一個引起它變化的原因。”也就是說,不要把變化原因各不相同的職責放在一起,因為不同的變化會影響到不相干的職責。
案例:
圖形繪製程式和Area()之間沒有任何聯絡,違反了單一職責原則,應改為:
7. 面向物件設計原則
7.1 OO的原則
單一職責原則
應該只包含單一的職責,並且該職責被完整地封裝在一個類中。
就一個類而言,應該只有一個引起它變化的原因。
開閉原則
軟體實體應該對擴充套件開放,對修改關閉。
軟體應該具有穩定的抽象層+靈活的具體層,找到系統的可變因素並將其封裝起來。
里氏替換原則
所有引用基類的地方必須能夠透明地使用其子類的物件。
在軟體中將一個基類物件替換成它的子類物件,程式將不會產生任何錯誤和一異常,反過來則不成立。
我喜歡動物——>我喜歡狗
依賴倒轉原則
高層模組不應該依賴低層模組,他們都應該依賴抽象。
在程式中儘量使用抽象層進行程式設計,而將具體類寫在配置檔案中。
介面分離原則
客戶端不應該依賴哪些它不需要的介面。
當一個介面太大的時候,可以將它分割成更小的介面。每一個介面應該承擔一種相對獨立的角色,不該做的事情不要做。
7.2 其他原則
合成複用原則
優先使用物件組合,而不是繼承來達到複用的目的。
繼承複用實現簡單、易於拓展,但是破壞了系統的封裝性。組合/聚合的耦合度較低,可以有選擇性地呼叫物件的操作。
迪米特法則
一個軟體實體應當儘可能少於其他實體發生相互作用來降低耦合度。
不要和陌生人說話就是迪米特法則的內容。
8. 面向物件的分析設計
OOA的主要構成
如何使用OOA進行分析
OOD的方法
7.1 為什麼需要面向物件的分析設計?
由於現實世界中的問題通常較為複雜,分析過程中的交流又具有隨意性和非形式化等特點,往往客戶對軟體的需求是站在使用者的角度,而作為軟體構架的工程師要按照軟體的角度來分析客戶的需求。為了保證軟體需求規格說明的正確性、完整性和有效性就需要進一步驗證,我們需要有一套完整並且具有相當可信力的分析設計體系,以便及時加以修正。所謂分析就是理解客戶腦子中的概念,跟客戶來溝通,分析出專業術語。設計就是對分析出來的專業術語進行歸納,讓程式設計師能夠思路更加清晰、更加順利進行軟體的開發活動。
7.2 OOA(Analysis)
面向物件分析方法(Object-Oriented Analysis,OOA),是在一個系統的開發過程中進行了系統業務調查以後,按照面向物件的思想來分析問題。OOA所強調的是在系統調查資料的基礎上,針對OO方法所需要的素材進行的歸類分析和整理。
OOA的主要部分
OOA的主要部分分為需求模型、基本模型、輔助模型和模型規約。
需求模型的主要表現方式就是我們使用做多的用例圖,這是我們進行面向物件分析的起點,我們設計人員根據客戶的需求來建立和解釋用例圖,用來描述軟體應具備哪些功能模組以及這些模組之間的呼叫關係,用例圖包含了用例和參與者,用例之間用關聯來連線以求把系統的整個結構和功能反映給客戶,最終我們會得到軟體的結構和功能分解。
基本模型的主要表現方式是我們經常用到的類圖,而基本模型可以分為3個層次:物件層、特徵層和關係層。物件層給出所有問題域和系統責任有關的物件,用物件類表示。特徵層定義每個物件類的屬性與服務。關係層通過一定義的關係描述物件類之間的關係。
輔助模式的主要表現方式包括互動圖、活動圖、狀態圖和包圖等。這些圖都能夠幫助我們更好地理解和分析整個系統開發的業務和邏輯。
模型規約對模型中的所有元素進行詳細說明。
OOA方法的基本步驟
首先確定需求和系統。系統是指事物的總體概貌和總體分析模型,對系統進行大致的規劃是開始系統分析的第一步。
然後捕捉系統系統中的物件。這裡所說的物件是對資料及其處理方式的抽象,它反映了系統儲存和處理現實世界中某些事物的資訊的能力。同時我們需要將捕捉到的物件進行分類為系統和系統之外的,分離出使用者、用例並畫出用例圖。
之後劃分類和類的屬性。類是多個物件的共同屬性和方法集合的描述,它包括如何在一個類中建立一個新物件的描述。屬性就是資料元素,可用來描述物件或分類結構的例項,可在類圖中給出,並在物件的儲存中指定。
最後識別物件間的關係。結構是指問題域的複雜性和連線關係。類成員結構反映了泛化-特化關係,整體-部分結構反映整體和區域性之間的關係。
如果有特殊需要,還可以建立詳細說明,對模型中的成分進行規範的定義和文字說明,可以集中進行,也可以分散在各個活動中。
OOA的主要原則
(1)抽象:從許多事物中捨棄個別的、非本質的特徵,抽取共同的、本質性的特徵,就叫作抽象。抽象是形成概念的必須手段。抽象是面向物件方法中使用最為廣泛的原則。抽象原則包括過程抽象和資料抽象兩個方面。過程抽象是指,任何一個完成確定功能的操作序列,其使用者都可以把它看作一個單一的實體,儘管實際上它可能是由一系列更低階的操作完成的。資料抽象是根據施加於資料之上的操作來定義資料型別,並限定資料的值只能由這些操作來修改和觀察。資料抽象是OOA的核心原則。它強調把資料(屬性)和操作(服務)結合為一個不可分的系統單位(即物件),物件的外部只需要知道它做什麼,而不必知道它如何做。
(2)封裝:把物件的屬性和服務結合為一個不可分的系統單位,並儘可能隱蔽物件的內部細節。
(3)繼承:特殊類的物件擁有的其一般類的全部屬性與服務,稱作特殊類對一般類的繼承
(4)分類:就是把具有相同屬性和服務的物件劃分為一類,用類作為這些物件的抽象描述。分類原則實際上是抽象原則運用於物件描述時的一種表現形式。
(5)聚合:又稱組裝,其原則是:把一個複雜的事物看成若干比較簡單的事物的組裝體,從而簡化對複雜事物的描述。
(6)關聯:是人類思考問題時經常運用的思想方法:通過一個事物聯想到另外的事物。能使人發生聯想的原因是事物之間確實存在著某些聯絡。
(7)訊息通訊:這一原則要求物件之間只能通過訊息進行通訊,而不允許在物件之外直接地存取物件內部的屬性。通過訊息進行通訊是由於封裝原則而引起的。在OOA中要求用訊息連線表示出物件之間的動態聯絡。
(8)粒度控制:一般來講,人在面對一個複雜的問題域時,不可能在同一時刻既能縱觀全域性,又能洞察秋毫。因此需要控制自己的視野:考慮全域性時,注意其大的組成部分,暫時不詳察每一部分的具體的細節;考慮某部分的細節時則暫時撇開其餘的部分。這就是粒度控制原則。
(9)行為分析:現實世界中事物的行為是複雜的。由大量的事物所構成的問題域中各種行為往往相互依賴、相互交織。
7.3 OOD(Design)
OOD(Object Orient Design)是一種解決軟體問題的設計正規化,一種抽象的正規化。抽象可以分成很多層次,從非常概括的到非常特殊的都有,而物件可能處於任何一個抽象層次上。另外,彼此不同但又互有關聯的物件可以共同構成抽象:只要這些物件之間有相似性,就可以把它們當成同一類的物件來處理。
OOD設計
OOD的主要工作是使用OOA的結果,將OOA得出的問題,給予設計方案解決。這一階段需要做的是對軟體系統的設計和規劃,包含的工作為:
①問題域部分的設計;
對OOA的物件和類的模型進行細緻修改,詳細考量類的屬性、刪除不必要的類、抽象需要的繼承層次、組織物件的包含結構、物件間訊息的傳遞方式和整體訊息順序安排;
②人機互動與應用控制部分的設計;
互動介面子系統的設計:與介面有關的類及類間結構的設計,以及有關演算法的設計;
互動介面子系統和應用之間介面的設計;
應用控制部分的設計:這部分物件主要完成應用的驅動工作。這部分物件不同於從現實世界中抽象出來的物件,在現實世界和問題域中沒有原型,它們同介面子系統中的物件及問題物件發生作用,控制系統的執行。
OOD階段就需要細緻到軟體的具體實現,然後是人機互動方面,如何使UI合理的提供互動,是否便於後續的功能擴充套件等。
OOD的目標
OOD的目標是管理程式內部各部分的相互依賴。為了達到這個目標,OOD要求將程式分成塊,每個塊的規模應該小到可以管理的程度,然後分別將各個塊隱藏在介面的後面,讓它們只通過介面相互交流。比如說,如果用OOD的方法來設計一個伺服器-客戶端應用,那麼伺服器和客戶端之間不應該有直接的依賴,而是應該讓伺服器的介面和客戶端的介面相互依賴。
OOA和OOD的區別
OOA重點在於業務需求的分析,而OOD需在前述的問題基礎上設計軟體結構。