信息系统分析与设计 第十章 系统总体设计
文章目錄
- 10.1 軟件架構的設計
- 10.1.1 什么是軟件架構
- 10.1.2 多層應用架構設計
- 10.1.3 軟件框架
- 10.2 高層結構設計
- 10.2.1 包
- 10.2.2 子系統及接口
- 10.2.3 構件及接口
- 10.3 結構化設計方法
- 10.3.1 模塊
- 10.3.2 結構圖
- 10.3.3 模塊的聯系
- 10.3.4 模塊間的耦合
- 10.3.5 模塊的內聚
- 10.4 面向對象設計方法
- 10.4.1 根據架構設計軟件類
- 10.4.2 設計類的屬性
- 10.4.3 設計類的方法
- 10.4.4 設計類的關系
- 10.5 面向服務設計方法
- 10.5.1 面向服務的基本概念
- 10.5.2 服務設計
- 10.6 設計原則
- 10.7 設計模式
10.1 軟件架構的設計
10.1.1 什么是軟件架構
1、架構的概念
建筑、文學、音樂、機械、電子、計算機軟硬件等領域都會使用“架構(architecture)”這一概念。架構都提供了系統最高層的設計方案,以確保建筑、小說、樂曲、設備、計算機等系統滿足期望的特性。
-好的建筑應該美觀、堅固、實用
-好的計算機應用系統應該實用、好維護、可靠、性價比高
架構師(architect)需要發現特定系統的最重要的關注點,設計某種折衷的總體方案以滿足關注點。
架構包含系統的一組基本結構(structure),每種結構都有各種類型的部件(component)及其關系構成,架構描述了這些部件的組合、相互調用參照、通信以及其他動態交互。
架構和結構的關系
架構是抽象無形的,體現高層全局的決策,就像文章的中心思想和提綱。
結構是具體有形的,體現決策的貫徹,如同文章的每個段落及細節描述。
架構包含了結構的初步描述和決策。
相同架構的系統,具體結構允許有差異。
使用橋梁來比喻:
橋梁的架構設計可以使用草圖描述,架構決定了橋梁的基本結構部件。
-橋梁有梁式橋、拱橋、斜拉橋、懸索橋等架構
斜拉橋的基本結構:索塔 主梁 斜拉索
橋梁的結構設計則需要考慮各種部件的數量、材料、重量、形態等方面,是可以施工的嚴謹的結構圖。
-架構是抽象的,對結構進行了設計和限定,每座橋的結構是具體有形的、元素組合千變萬化
2、軟件架構
軟件架構(software architecture)的定義沒有統一的版本,一般認為:一個應用程序或計算系統的軟件架構是一個或一組結構,它包含組成系統的軟件元素、這些元素對外可見的性質以及它們之間的關系。對外可見的性質指軟件元素能夠提供的服務、性能特征、錯誤處理、共享資源的用法等。
-軟件的一個結構元素可能是一個子系統、構件、進程、庫、數據庫、計算結點、遺留系統等等。
軟件架構是最高層次的系統分解,它不會囊括所有的結構和行為的定義,它只關注那些被認為是重要的元素。
-架構難以更改,一旦修改,意味著整個系統重建,而結構修改只影響局部。
軟件架構(software architecture)包括邏輯設計和物理部署兩方面。
邏輯設計:通過對系統的層、包、類、接口和子系統的組織方式來描述;
物理部署: 描述了進程分配和網絡配置。
3、軟件架構模式
大部分的架構來源于有相似關注點的系統的總結和抽象,這些相似性被描述成某種特殊模式的架構風格,也就是架構模式(architectural pattern)。
一種架構模式就是一個經驗秘籍,架構師在設計不同系統時可以重復使用這些先進經驗。
-中國建筑有一種攢尖模式,被廣泛應用在古典園林中,如三角、四角、五角、八角等亭子,宮殿、壇廟大量應用
軟件架構模式就是可重復使用的軟件結構風格。
10.1.2 多層應用架構設計
1、分層的含義
基于組件的軟件開發,組件根據橫向位置劃分為多層(N-Layer):
下層組件負責對上層組件提供服務
上層組件可以使用下層組件定義的服務,但下層組件對上層組件一無所知。
層與層之間通常是不透明的,每一層都具有獨立的職責
不同層的軟件構件可以分布在多臺機器上,也可以部署在同一臺機器上,形成物理上的多層(N-Tier)
層次模型的理念就是將整個任務橫向劃分為不同級別,而不是縱向
-比如學校管理縱向劃分有教學、人事、財務、后勤等任務
-橫向按管理層次劃分有主管校長(高層)、部門領導(中層)、普通員工(基層),或處、科、室,按對外接待層次從公司前臺、到部門秘書、再到辦事人員……
計算機程序的組織結構也可以有縱向劃分和橫向劃分
-縱向:教師管理功能、學生管理功能、課程管理功能……
-橫向:界面窗體、業務邏輯類、數據訪問類……
自從C/S出現之后,軟件就被分層了:
Client端的軟件完成前臺任務,Server端的軟件完成后臺任務(一般是DB Server);
Client使用Server端的服務,依賴于Server端。
自從Internet出現之后,軟件進一步分層:
Client端的軟件(IE瀏覽器)完成輸入輸出任務,Web Server上的程序提供業務邏輯處理,后臺DB Server完成數據的存取。
C/S常被稱為傳統的兩層,B/S稱為三層。
本書的分層將不包含有關系統軟件(屏蔽如IE、DBMS等內容),僅討論應用系統本身的設計,即應用架構設計。
2、三個基本層次
應用軟件內部也可以進行多層的劃分。
比如一個用戶注冊程序可以劃分為兩層:
-Register.aspx/Register.aspx.cs窗體:負責界面數據的輸入和格式檢驗,結果的輸出等。
-UserDal類:負責數據庫訪問和注冊規則檢查等。
-從應用層面上看,如果整個應用軟件都是采用這種方式編程(如訂單處理由PlaceOrder.aspx窗體負責界面交互,由Order、Product等類負責數據庫訪問和訂單金額計算等業務邏輯處理),那么稱之為兩層的應用架構。
可以有兩層、三層、四層等不同分層模式。
-Register.aspx/Register.aspx.cs窗體
-UserBll類:負責注冊規則檢查等業務邏輯。
-UserDal類:負責數據庫訪問。
傳統的C/S應用程序
界面窗口程序中包含所有的內容,如輸入輸出、界面邏輯控制、業務邏輯運算等。
系統架構是兩層,應用架構沒有分層。
經典的三層架構
1 表現層:處理用戶和信息系統之間的交互。
-可以是簡單的命令行窗口,也可以功能完善的圖形用戶界面(胖客戶端程序),如基于HTML的瀏覽器界面(瘦客戶端程序),也可以是手機界面。
2 業務邏輯層:也稱為領域層或應用層,是信息系統所有和領域相關的工作。
-如根據輸入數據或已有數據進行計算,可以是類庫或Web服務。依賴于數據訪問層獲取數據或保存數據。
3 數據訪問層:一般指與數據庫的交互,主要責任是數據庫記錄的存取。
-如組件中包含專門的數據訪問類,或每個表對應一個數據訪問類
3、擴展的五層架構
1 表現層:等同于三層中的表現層。
2 控制層/中介層:是表現層和領域層的中介層,也稱應用控制器。
主要表示業務邏輯中的工作流,一般針對于用例的事件流控制。此外還負責會話狀態、數據的合成或分解等事務。
3 領域層:業務邏輯中的領域類的集合,不包含復雜工作流。
4 數據映射層:負責將基于對象的領域層數據映射到數據庫關系表中的記錄。也稱為數據持久層,可自行開發或采用持久化框架。
5 數據訪問層:負責數據庫表的增刪改查等操作。持久化框架中包含該層組件。
4、MVC架構模式
模型(Model)
-代表數據,使用對象及其屬性實現。
控制器(Controller)
-是模型與視圖的聯系紐帶,客戶的請求由控制器處理,它根據客戶的請求調用模型的方法,完成數據更新,然后調用視圖的方法將響應結果展示給客戶。相應的,模型的更新與修改將通過控制器通知視圖,保持視圖與模型的一致性
視圖(View)
-是模型的外在表現形式,視圖可以直接訪問模型;查詢數據信息,當模型中數據發生變化時,它會通知視圖刷新界面,顯示更新后的數據。
MVC架構示意圖
MVC模式和三層模式有共同特點(業務邏輯、數據和表示的分離),但不完全遵守分層約定。
5. 多層的物理配置
由于應用軟件封裝成不同層次的獨立組件,這給軟件部署帶來了靈活性:
物理一層:所有應用軟件的組件都安裝配置在一臺機器上。比如全部Web程序、DBMS都在Web服務器上。
物理兩層:應用軟件的組件配置在兩臺機器上,比如一部分安裝在客戶端,另一部分配置在應用服務器上。
物理多層:客戶端、一臺或多臺應用服務器、數據庫服務器,即多臺服務器的方式,這是分布式結構的一種形式。
多層體系結構的優勢
客戶對數據的訪問通過中間層進行了隔離,數據庫的安全性提高了。
應用程序分布部署在多個物理節點上成為可能,從而增強了處理大量的用戶負載或計算任務的能力,系統可靠性和響應速度得到了提高。
業務邏輯處于不同的中間服務器,當業務規則變化后,客戶端程序基本不做改動,當組件接口不變時,某一層的改動不會影響其它層,這也意味著更好的重用和可維護性(如從窗口界面變更到Web界面)。
將不同層的開發任務在開發者之間適當地分配(如一些人專注頁面表現,另一些人專注于業務邏輯),有效地利用開發人員的專長和開發技巧,并且能夠提高并行開發能力。
10.1.3 軟件框架
“不要重復發明輪子”
軟件復用:
-從代碼角度(開發態)看有子過程、函數、類等
-從部署角度(運行態)看有類庫、Web服務等二進制可執行組件、中間件和平臺
架構模式同樣可以復用,當架構模式的復用形式不僅僅停留在邏輯層面(如藍圖、方案),而以物理的二進制組件的方式提供重用時,就產生了框架。
軟件框架(software framework)是對整個或部分系統可重用的設計和實現。
框架可以選擇對某種架構模式的基本結構和接口機制進行編程實現,不僅封裝該架構模式的基本元素對外提供類庫,還封裝底層公用的流程控制邏輯,從而直接為應用軟件提供了最初的骨架。
框架就是一個半成品軟件平臺,軟件框架和應用軟件:
八股文 => 具體文章 (按照規范填空即可,“聽課容易,解題很難,且聽且珍惜”)
架構模式/框架/應用程序 => 菜譜菜式/半成品/成品菜
引入軟件框架之后,整個開發過程變成了“分三步走”:
決定應用架構
選擇實現應用架構的現成框架
基于框架之下編寫程序(簡單、統一)
優點:
代碼具有相同規范和結構,易于理解和維護;提高效率;更穩定更可靠。
局限:
囿于框架所限定的“框框”之內構建應用程序,比較死板,缺乏靈活性
典型框架產品
支持MVC架構模式的框架:
Java開源MVC框架Struts
微軟平臺的MVC4框架
PHP的Zend框架
多種框架產品的組合使用:
如SSH(Struts、Spring、Hibernate)
Struts2簡介
MVC:
View:由JSP頁面實現
Model:由自行編寫的Action對象完成,Action類就是一個普通的Java類,里面封裝了領域對象的屬性和方法,可以用于存取數據和執行有關業務邏輯。屬性和方法也可以分開到不同類中。
Controller:由Struts2的內置過濾器(dispatcher filter)、攔截器(interceptor)或自行編寫的攔截器來實現,過濾器和攔截器可以截獲JSP頁面請求,解析http請求中的參數,賦值給Action對象中對應的屬性,還可以在調用Action之前或之后進行預處理或后處理。
10.2 高層結構設計
高層結構討論系統比較大的組成部件(如包、構件、子系統等)及其接口設計。
10.2.1 包
包(Package)是一種邏輯分組手段,可以取UML模型中的任何一種事物,將相關成分聚在一起,以構成更高層的組織單元——包。
最常用的方法是將類以包為單位進行分組,比如上一節提到的層,每一層中的所有類組成一個包。
一個包可以包含其它的包,高層包被分成若干子包,子包又可以在分成更小的包。
-但在Java中,包還指代了物理的組織手段
分包(軟件類的分組)有兩種原則:
-共同封閉原則(Common Closure Principle)。一個包中的各個類應該是由于相似的原則而改變,即將一組職責相似、但以不同方式實現的類歸為一個包中。比如按照層來進行分包就是這種類型。
-共同復用原則(Common Reuse Principle)。一個包中的各個類應該一起被復用,復用其中一個可能需要同時考慮同一個包中的其它協作類。通常和業務功能相關。
包圖用來描述包及其依賴關系。
當表現層包中的類要使用領域包中的領域類提供的服務時,表示包就依賴于領域包。
10.2.2 子系統及接口
當按照相對完整和獨立的業務功能或管理職能組織包,并對這樣的包進行封裝后,一個高層的具有特定功能的可以運行的獨立構件就產生了,稱為子系統(Subsystem)。
子系統對外可以提供有限的接口,只要接口不改變,不管子系統內部發生什么變化,也不會影響到依賴于該子系統接口的其它子系統。
子系統及其關系使用UML構件圖(component diagram)描述。
理解接口概念
詞典釋義
-兩個不同系統(或子程序)交接并通過它彼此作用的部分。
人類與計算機之間的接口稱為用戶接口。
計算機硬件元件間的接口叫硬件接口。
計算機軟件元件間的接口叫軟件接口。
-內部接口:系統內部各元件間的接口
-外部接口:系統對外提供給其他系統使用的接口
-API:應用編程接口(Application Programming Interface),一種應用程序提供的外部接口的說法
區分子系統和包
子系統與包在語義上具有差異:
子系統是一種通過一個或多個它所實現的接口來提供行為的軟件單位,可運行,具有物理意義。
包并不提供行為,包只不過是用來容納各種其他模型元素的容器,一般是邏輯意義上的。
子系統的關系
財務子系統將內部操作進行了封裝,但對外提供必要的接口(比如一組函數)
銷售子系統在執行銷售業務過程中可以使用該接口對銷售數據執行某些財務操作。對于銷售子系統而言,依賴的是財務子系統的接口,并不需要關心財務子系統的具體實現。
采用UML2.0的構件圖表示如下:
10.2.3 構件及接口
構件(component)是系統中實際存在的可更換部分,它實現特定的功能,符合一套接口標準并實現一組接口。
構件是可復用的軟件組成成份,可被用來構造其他軟件。
-在系統中采用構件軟件程序不需要重新編譯,也不需要構件自身的源代碼并且不局限于某一種編程語言,所以構件的復用也稱為二進制復用(binary reuse),因為它是建立在接口而不是源代碼級別的復用。
構件及其關系使用UML構件圖描述。
構件之間存在依賴關系:
DataAccess構件用于實現數據存取訪問,對外提供接口名為SearchInDB(查詢數據庫,接口參數等細節省略)。
Book構件實現圖書的管理,對外提供SearchBook(查詢圖書)和ExportToXml(導出圖書為XML文件)兩個接口。
Book構件需要使用DataAccess構件提供的接口,即構件Book依賴于DataAccess構件。
區分子系統和構件
子系統和構件在結構上具有差異:
子系統是一個系統,是有特定功能的整體,可以直接使用,不會被復用。
構件只是構成系統的元素,不具備單獨使用的能力,用于復用。
10.3 結構化設計方法
結構化設計的基本思想
結構化:自頂向下,逐層分解求精
結構化設計:軟件模塊化,按層次劃分
使用功能分解一定程度上能夠簡化系統結構,使系統容易修改和理解。
具體做法:
把整個軟件劃分為部分,其中每一部分的功能簡單明確,即程序模塊(可以是子過程或函數)
劃分模塊的工作按層次進行,上層模塊調用下層模塊
每一個模塊應盡可能獨立
模塊間的調用接口要闡明(模塊名稱、輸入數據、輸出數據)
10.3.1 模塊
模塊(Module)一詞使用很廣泛。通常對應于用一個名字就可以調用的一段程序語句(子程序或函數)。
模塊具有輸入和輸出、邏輯功能、運行程序、內部數據四種屬性。
10.3.2 結構圖
結構圖(Structure Chart)描述系統的模塊結構及模塊間的聯系
結構圖中的主要成分有:
-模塊:用長方形表示
-調用:從一個模塊指向另一模塊的箭頭表示前一個模塊調用后一個模塊。有循環調用和條件調用
-數據:用帶圓圈的小箭頭表示從一個模塊傳遞給另一模塊的數據(有實義)
-控制信息:帶涂黑圓圈的小箭頭表示一個模塊傳送給另一模塊的控制信息
結構圖的畫法
結構圖無嚴格的模塊調用順序,但一般習慣從左至右
因為約定遵從從上向下的調用,調用關系也可以不使用箭頭,而直接使用直線
模塊間傳遞的信息如果出現在數據字典中,則視為數據,否則為控制信息
一個完整的結構圖
簡單畫法的結構圖
簡化后,忽略信息傳遞的結構圖如下:
借書模塊還可分解:
驗證讀者身份、修改圖書狀態、保存借閱記錄等
10.3.3 模塊的聯系
為了衡量模塊的相對獨立性,提出了模塊間的耦合(Coupling)與模塊的內聚(Cohesion)兩個標準
-耦合:模塊和模塊之間的聯系程度
-內聚:模塊內部各元素之間的聯系程度
設計目標:
模塊內的聯系越緊越好
模塊間的聯系越少越好
高內聚低耦合
10.3.4 模塊間的耦合
兩個模塊之間存在聯系
影響耦合度的因素
如果使用模塊A需要了解模塊B,那么A和B是耦合的。影響模塊間耦合程度有三方面的因素:
聯系方式--模塊間通過什么方式聯系
來往信息的作用--模塊間來往信息作什么用
數量--模塊間來往信息的多少。
離坐標原點越遠,耦合程度越高
耦合分類如下:
數據耦合:采用子程序調用,調用模塊將需要進行處理的數據傳遞給被調模塊。數據耦合是不可避免的。
標記耦合:如果調用模塊將整個數據記錄傳遞給被調模塊,而被調模塊只使用了部分數據項,則稱為標記耦合或特征耦合。
控制耦合:一個模塊將控制信息傳遞給另一個模塊,以控制被調模塊的內部處理邏輯。(可以分解)
公共環境耦合:如果兩個模塊共享同一全局數據,稱為公共耦合。
內容耦合:兩個模塊之間的內部屬性有直接關聯,也稱病態耦合。(某些GOTO語句)
10.3.5 模塊的內聚
模塊內部各元素(變量、語句)之間存在聯系
內聚的好處
模塊的內聚反映模塊內部聯系的緊密程度。
一個模塊只需要做好一件事情,不要過分關心其它任務。
高內聚性的好處是可以提高程序的可靠性。
模塊的內聚可以分以下七類:
1、偶然內聚(coincidental cohesion)
2、邏輯內聚(Logical cohesion)
3、時間內聚(temporal cohesion)
4、步驟內聚(procedural cohesion)
5、通信內聚(communicational cohesion)
6、順序內聚(Sequential cohesion)
7、功能內聚(functional_cohesion)
1、偶然內聚(coincidental cohesion)
當同一個子程序中的操作之間無任何聯系時,為偶然內聚性,也叫作“無內聚性”。
比如只是為了將程序中某幾處湊巧相同的一些語句組合起來形成的一個模塊:
2、邏輯內聚(Logical cohesion)
將幾個邏輯上相似的功能放在一個模塊中
溫度轉換函數(攝氏和華氏溫度的互相轉換,if-else語句)
常見的出錯處理模塊,工作模塊發現錯誤后,調用錯誤處理模塊,將錯誤號作為控制參數傳入,然后出錯處理模塊根據不同的錯誤號執行相應的操作(switch…case分支語句)
3、時間內聚(temporal cohesion)
將在有限時間單元內處理的成分組合為同一模塊
比如在窗口load事件過程:
可視化程序設計中初始化窗口中的缺省選項
還比如:C++的構造函數、析構函數
4、步驟內聚(procedural cohesion)
當子程序中的操作是按某一特定過程結構進行的,就是步驟內聚。
例如:用戶想按一定的順序打印告,子程序設計成是用于按順序打印銷售收入、開支、雇員電話表的。
步驟內聚在時間內聚的基礎上增加了次序的約束。
5、通信內聚(communicational cohesion)
當模塊內的成分引用共同的數據,而不存在其他聯系時,稱為通信內聚
6、順序內聚(Sequential cohesion)
模塊中某個成分的輸出是另一成分的輸入,順序內聚有較強的內聚性,是步驟內聚和通信內聚的結合。
但仍然不是最高的內聚類型,包含功能不單一。
比如顯示期末成績通知:
7、功能內聚(functional_cohesion)
一個模塊包括并且僅僅包括為完成一個具體任務所需要的所有成分,稱為功能內聚。
功能內聚性是最強也是最好的一種內聚
-例如:打印職工名單,PrintStaffList()
-例如:計算平均分,CalculateAvg()
僅用一個動賓詞組能明確指出這個模塊的所有功能
耦合和內聚的概念是Stevens等人提出的, 是測量一個模塊化系統好壞的標志。
按他們的觀點, 給上述七種內聚評分如下:
功能內聚10分
順序內聚9分
通信內聚7分
步驟內聚5分
時間內聚3分
邏輯內聚1分
偶然內聚0分
可以給一個軟件的所有模塊打分,最后計算平均分,作為軟件結構質量評價的參考
10.4 面向對象設計方法
10.4.1 根據架構設計軟件類
一種3層的分層模式:
從分析模型的領域類導出設計階段中的實體類
增加邊界類和控制類完成程序的交互和控制。
為了分辨出類的這三種不同類型,可以采用UML提供的擴展機制——構造型(stetreotype)及其表達符號來定義模型元素構造型
Rose中不同構造型的圖符
1、邊界類
邊界類的職責是完成系統與其參與者之間的交互。
-接收來自用戶和外部系統的信息與請求
-將信息與請求提交給用戶和外部系統
通過用例圖可以得知每個邊界類至少應該與一個參與者有關,參與者類型不同,邊界類的設計也不同
邊界類包括屏幕窗口、通信接口、打印機接口、傳感器、終端以及專用API(應用程序編程接口)等軟件對象。
-對于圖書館系統來說,參與者都是系統用戶,因此邊界類只有窗口界面這一種形式。
-假如考慮提供館際互借業務,那么系統就會產生與其它外部合作的圖書館系統的交互,這時與外部系統間的通信接口也是一種邊界類
識別邊界類
根據用例圖,每個參與者與一個用例交互,必定導出一個邊界類
2、實體類
實體類來源于領域模型中的類。
實體類是一個軟件對象,表示了領域對象的信息,以及具有與它所表示的信息有關的操作。
實體類反映的信息需要在系統中進行處理,并需要進行持久化存儲。 持久化存儲可以由實體類來實現,也可以設計專門的數據訪問類來完成。
邊界類和實體類的交互
邊界類僅負責數據的輸入和輸出,不應承擔和數據處理有關的業務邏輯,可負責部分不太復雜的數據校驗功能(如非空檢查、多個輸入域之間的約束和聯動)。
邊界類通過與實體類的交互,獲得有關數據處理的結果
3、控制類
控制類代表協調、排序、事務處理以及對其它對象的控制,經常用于封裝與某個具體用例有關的控制流。
控制類處理和協調用例事件流中的主要動作和控制流,并將部分任務委派給其它對象。
根據分層原則,控制類不封裝與參與者交互有關的內容,也不封裝與系統處理的長效持久的信息有關的問題,這些問題分別由邊界類和實體類進行封裝。
識別控制類
當用例邏輯較為復雜,并涉及到多個實體類時,可以考慮采用控制類
簡化方案:控制類的職責合并給邊界類
不同類的職責分配
向下依賴的關系:
邊界類
-負責與參與者的交互(輸入數據、顯示數據)
-為GUI的每個彈出式屏幕創建一個邊界對象。
控制類(可選)
-負責一個用例的事件流,或部分復雜數據流
實體類
-負責數據的封裝
-為每個領域類創建一個實體類
圖書館系統的界面類
圖書館系統的控制類
圖書館系統的實體類
10.4.2 設計類的屬性
1 屬性類型和初值
-屬性的類型和默認的初始值應該在設計模型中表示出來。類型和屬性名之間用冒號隔開,等號之后寫初值。選擇的數據類型最好是目標語言中可用的。
-關聯屬性
2 屬性的可見性
-類中的每個屬性可以有可見性定義,指定該屬性可以被其它類利用的程度,
-UML定義了4種屬性可見性:
公有(public) “+”
受保護(protected) “#”
私有(private) “-”
包(package) “~”
10.4.3 設計類的方法
交互圖中的消息映射為接受消息的對象類的方法(操作)
消息表達式中的參數和返回值等映射為類方法函數的參數和返回值
同義詞釋疑:
-操作是關于行為的定義,方法是行為的實現,服務是行為的對外表現,消息是行為如何協作,它們用于不同的角度、場合、時機和模型中,但可以將它們認為是同義詞
1、職責
類的方法是對象應該執行的操作,也稱為對象的職責和義務。
職責是在設計過程中分配給每個類的,可以采取的方法有:
-使用交互圖
-使用CRC技術
職責完成的兩種情況
一項職責的完成有以下兩種情況:
-1. 由某個對象獨立承擔,比如“計算超期天數”由一個Loan對象負責。
-2. 主要由一個對象負責,但該對象將職責進行了二次分配或分解。比如“負責計算訂單總額”應該由一個Order對象負責,Order類為了完成該職責,需求OrderItem對象的協作,OrderItem對象負責提供每個訂單項的小計金額(數量*單價)。
軟件對象的職責分配可以映射到現實世界中的分工和協作,例如:
-部門經理A布置業務人員B完成一項任務x,B可能一個人獨立承擔該任務,B也可能將任務分解為x1、x2、x3,自己負責x1和x2,請C負責x3。
職責有兩種類型:
1、行為型:即對象本身的方法。比如進行一項計算、被創建時的初始化、執行控制或協調的各項活動。
2、了解型:對象應掌握的信息。比如對象自身的數據和屬性、相關聯的對象以及能夠派生或計算的對象(set/get方法),如Loan類需要了解借出和歸還日期(屬性),以及所借資源的有關情況,即ResourceItem或ResourceTitle對象(關聯對象)。
CRC卡片法
CRC卡片法是一種職責分配技術,CRC是類-職責-協作(Class-Responsibility-Collaboration)的簡稱。具體實踐過程:
首先為系統中每個軟件類制作一張卡片
選取一個用例,確定該用例的參與類
取出上述確定的類卡片
通過移動卡片來討論類如何協作完成用例功能
最后將形成的職責概念記錄在類所在的卡片上。
雖然它不是UML的組成部分,但也是一種快捷有效的的OO設計技術。
直接建模(繪制順序圖)同理。
2、對象交互建模
交互模型的設計內容:
1 對象職責的識別,意味著對象協作過程中消息的分發
2 定義消息的完整格式
3 將消息映射為類的操作,并在實現時轉化為類的方法
交互模型舉例
消息的含義:
-對象A向對象B發送消息X(服務員發炒菜消息給廚師)
-對象B為對象A提供消息X規定的服務(廚師提供炒菜服務)
-對象B有響應消息X的行為(廚師有炒菜行為)
-B的類里有X方法
交互圖
多個對象的行為采用對象交互來表達,UML2.0提供的交互圖有順序圖、交互概覽圖、通信圖和計時圖。最常用的是順序圖。
交互的類型:
-參與者和系統之間有交互
-系統內部元素之間也有交互
每個用例對外展示了用戶和系統的交互(人-機交互),而內部實現則需要多個對象交互以完成用例事件流規定的各種功能。
順序圖(Sequence Diagram)
順序圖的元素:
參與者
對象
生命線
激活框
消息
控制框架(分支、循環、可選)
系統順序圖
每個用例可以建模為參與者與系統之間的人-機交互:
順序圖(參與者與對象)
參與者(Actor)實例是一個交互過程(用例)的發起者,通常放置在最左邊。
對象(Object)——對象就是類的一個實例,在順序圖中上方以和類相同的圖形符號表示,并帶有一條叫做“生命線”的垂直虛線。生命線上的矩形條表示對象在特定時間的生存期。
UML規定了對象實例的表示方法:
順序圖(生命線與激活框)
生命線(lifeline)說明了對象的生命周期。
對象如果被銷毀了,其生命線就會中斷。
激活框(activation box)表明交互中對象何時起作用,激活框在順序圖中是可選的
順序圖(消息)
消息是對象之間的通信,消息傳遞的同時對應活動隨之發生。
在順序圖中,消息被表示為從一個對象的生命線到另一個對象的生命線的水平箭頭。
箭頭通過消息名稱及消息參數來標記,箭頭自上至下的垂直位置來表示時間的先后順序。
消息響應后可能會回送結果,發送請求的消息采用實線箭頭,返回結果的消息采用反向的虛線箭頭。但為了模型的清晰,對顯而易見的返回通常不必繪出。
順序圖(控制流)
如果用例的備選事件流的步驟較多,可另外為備選事件流單獨繪制一個順序圖。
一個順序圖中也可以描述控制流(UML2.0):
-利用交互框架來標示
-框架可以將順序圖中的某個區域框起,并劃分成若干片斷
-每個框架有一個操作符。對于循環操作,可以使用loop操作符,條件操作則使用alt操作符
-每個分支片斷有一個監護條件,滿足該條件才會執行該片斷內的事件流
復雜控制邏輯由活動圖描述更清晰,但活動圖不能標識消息。
順序圖舉例
包含循環和分支的順序圖
協作圖/通信圖
協作圖一般可由建模工具自動從順序圖生成,與順序圖是等價的。
另一種交互圖:
-UML1.X稱為協作圖(Collaboration Diagram)
-UML2.0稱為通信圖(Communication Diagram)
元素和表示方法與順序圖基本相似,但不表達生命線和消息物理位置,而增加對象消息連接。
消息連接顯示為兩個對象之間的一條實線,其上附帶消息、消息流向和消息的順序號。
更直觀地顯示了對象的關系,它更有利于理解對給定對象的所有影響。
圖書館順序圖1
借書(初步設計,消息使用中文)
圖書館順序圖2
還書(備選事件流使用opt框架,表示可選分支):
3、消息的設計
消息規范化設計,需要使用以下表達式語法:
-return := message (parameter : parameterType):returnType
-如果類型信息非常明顯或不重要的話,可以省略書寫,如:
-reader := getReader(cardID : String)
消息的序號
-消息的次序用自小到大的順序號來表示。按照消息的完成情況,消息可以有嵌套消息(代表任務分解)。
-嵌套消息的序號按照層次編號,所有嵌套的子消息都是服務于其上層消息。
嵌套消息
嵌套消息含義與結構化方法中的模塊調用相同
結構化方法中模塊都是單個的,沒有分組。面向對象方法也強調模塊的概念,但模塊都有一個主人——對象
OOD中的模塊劃分要解決兩個問題:
-任務如何分解為子任務?
-各個任務應由誰承擔?
嵌套消息示例
計算超期罰金,最高不超過書價
Loan對象在計算超期罰金時還需要獲取資源的價格和罰金標準,因此向ResourceItem發送請求價格的消息,向FineRule發送超期罰金標準,而ResourceItem對象并不記錄價格,因此請求價格的消息還需要發送給ResourceTitle對象。
返回消息
很多消息發送之后,消息的接收對象會在響應后產生一些結果回傳給發送者,這就是返回消息。
在UML交互圖中,返回消息以虛線箭頭線表示。為了簡潔,一般省略返回消息。
自身消息
有些消息是對象發給自己的。
-比如借書界面中要增加一個借閱項目,首先發送消息給控制類請求業務邏輯的處理(makeNewLoan消息),然后在窗口的列表中將新的借閱記錄添加進來(addListItem)以備瀏覽和打印,添加列表的功能是界面類的職責,消息應發給窗口對象自身
-通常是一個類內部的private方法
4、為類添加方法
對象職責體現為順序圖中類所收到的消息,也就是類的方法。
類的方法可以定義可見性,當然順序圖中的絕大多數消息是公有方法。
10.4.4 設計類的關系
設計四種關系的具體實現:
泛化(類)
關聯(對象)
實現(類)
依賴(對象)
1、泛化設計
泛化在面向對象語言中使用繼承來實現,繼承機制實現了子類擁有父類特性的這一過程。
泛化設計還有一個更重要的目的在于如何實現多態性。
2、關聯設計
實現對象關聯的一個簡單策略就是:
-在關聯的源類中聲明一個屬性來保存對目標類的實例的引用,這種屬性稱為關聯屬性或引用屬性。
根據關聯的導航性,有單向關聯和雙向關聯。
根據關聯重數,有一對一、一對多和多對多關聯,多對多關聯通過建立關聯類分解成1對多的關聯。
限定關聯。
關聯可以在對象一產生就已經存在,也可以在運行期間動態建立。
對于那些比較持久并且不會發生變化的關聯,或者具有很強歸屬關系的聚集關聯,一般在主對象的構造函數中創建關聯對象或記錄下關聯對象的引用
較為松散的對象關聯,一般當某項業務邏輯發生時,兩個對象的關聯才被確立,可以設計特定方法建立或解除關聯
3、接口與實現的設計
所有的實體類都具有這些數據庫操作行為,將這些操作抽象出來封裝到一個IEntityOperate接口中
4、依賴設計
在類圖中依賴關系通常指明一個類的對象實例使用了另一個類的屬性和方法。
界面層使用了控制層對象,控制層對象使用了數據訪問層對象。
類的耦合
類之間的聯系的緊密程度就是類之間的耦合度。
四種關系的耦合程度從高至低:
-泛化
-實現
-關聯
-依賴(上層對象依賴于下層對象)
類的內聚
類的合理封裝
-內部屬性和方法的關系緊密
單一職責的類
-不要雜湊類
-不要大而全的類
10.5 面向服務設計方法
10.5.1 面向服務的基本概念
1、什么是服務
一個“服務”定義了一個與業務功能或業務數據相關的接口,以及約束這個接口的契約,如業務規則、安全性要求、質量要求等。
接口和契約采用中立的、基于標準的方式進行定義,它與實現服務的硬件平臺、操作系統和編程語言無關,使得服務能以統一的方式在異構系統之間互相理解和交互。
服務是自治、獨立的、無狀態的,既要符合能獨立的完成進化,并且進化過程不影響其他的邏輯單元。
服務可以被其他服務或程序利用。這種服務之間的應用,是基于相互理解的基礎之上,即服務描述。描述文件中描述了服務的名稱,服務所需要的數據,處理后返回的數據。
2、SOA的概念
SOA(Service-Oriented Architecture)
是一種架構模式,系統基于服務構件來開發,多個服務通過它們定義良好的接口和契約聯系起來。
最早由Gartner公司于1996年提出SOA概念時,是這樣描述的:“客戶端/服務器的軟件設計方法,一個應用系統由軟件服務和軟件服務使用者組成……SOA與大多數通用的客戶端/服務器模型的不同之處在于它著重強調軟件構件的松散耦合,并使用獨立的標準接口。”
狹義的SOA:一種IT架構風格,是以業務驅動、面向服務為原則的分布式計算模式。
廣義的SOA:包含架構風格、編程模型、運行環境和相關方法論等在內的一整套企業應用系統構造方法和企業環境,涵蓋分析、設計、開發整合、部署、運行和管理等整個企業信息系統建設的生命周期。
SOA特點
可從企業外部訪問
松耦合、粗粒度
面向業務
內部實現可以基于對象,但是作為一個整體,它是面向業務的,而不是面向對象的。
設計服務可以解決:
企業內的應用集成
企業間的應用集成
軟件和數據重用
按需業務流程
(1) 企業內跨平臺應用集成
企業里經常都要把用不同語言寫成的、在不同平臺上(異構)運行的各種程序集成起來,而這種集成將花費很大的開發力量。例如Windows應用程序需要從運行在IBM主機上的程序中獲取數據;或者把數據發送到主機或UNIX應用程序中去。
即使在同一個平臺上,不同軟件廠商生產的各種軟件也常常需要集成起來。
(2) 跨企業跨行業應用集成
企業所關注的流程跨越了企業的邊界,衍生到組織外部,跨企業的應用集成是必然趨勢。
例如生產企業與供應商簽訂了采購訂單,供應商的訂單系統(或ERP)記錄和跟蹤訂單,所有訂單數據及狀態變化直接影響到生產企業的供應系統(或ERP),跨企業的兩個信息系統之間需要無縫集成。
另外在互聯網和電子商務背景下,不同組織間的協同工作模式也在不斷創新,比如圖書電子商務網站和出版、銀行、運輸等行業也存在應用系統集成的需求。
(3) 軟件和數據復用
SOA是對構件技術的演進,在軟件復用上更加優越。數據提供商的數據如何被不同的服務提供商重用?
例如在互聯網上提供一個多語種翻譯的服務,可以集成到很多應用系統中。
數據生產商或供應商可以利用服務將數據出賣或出租給使用者,并與使用者的應用系統進行整合,例如114黃頁信息、天氣預報信息、證券信息的擁有者可以基于SOA對外提供數據服務,授權的用戶程序(如新浪等門戶網站、數據分析軟件)能獲取這些信息并集成到自己的應用中。證券交易出賣行情的授權。
(4) 按需業務流程定制
傳統管理軟件將企業的業務功能和流程固化到軟件代碼中,當企業業務發展導致需要變更IT系統的業務流程時,IT部門并不能快速的滿足最新的需求。
SOA關注業務流程和使用標準接口,以服務組件的方式實現流程中的任務或活動。
-SOA提供了業務流程服務化的手段,變化后的業務流程可以通過對服務的重新編排而實現快速定制。
-在 SOA 術語中,業務流程包括依據一組業務規則按照有序序列執行的一系列操作。操作的排序、選擇和執行稱為服務或業務流程編排。
3、SOA技術概覽
SOA技術架構
(1) 現有應用資產層:這一層包括所有已開發、定制或打包的應用軟件或數據庫等資產
(2) 服務構件層:包含軟件構件,提供服務的實現。
(3) 服務層:服務層由所有在 SOA 中定義的邏輯服務構成。該層的服務可被發現、調用、編排進行形成組合服務,也可以直接被業務流程層和用戶表示層使用。
(4) 業務流程層:該層定義服務層中這些服務的組合和編排,將一組服務組合或編排成一個流程。
(5) 用戶表示層:也稱消費者層,基于服務提供軟件功能和數據給最終用戶,并具備建立不同應用的連接能力。通過信息門戶、富客戶端(Ajax、Flex)等技術,為業務流程、組合應用提供了快速創建客戶前端的能力,以響應市場變化。
(6) 服務集成層:集成層支持和提供調節能力,確保服務發起者能夠向正確的服務提供者傳輸服務請求,包括路由、協議支持和轉換、消息傳遞/交互風格、異構環境支持、適配器、服務交互、服務實現、服務虛擬化、服務消息傳遞、信息處理和轉換等。
企業服務總線(enterprise service bus,ESB)就是一個可靈活整合和連接不同應用和服務的基礎設施,支持:轉化請求者和服務之間的傳輸協議;處理分離資源間的業務事件;轉換請求者和服務之間的消息格式;路由服務間的消息傳遞。
(7) 服務質量層:支持SOA各層非功能性需求,提供了監視、管理和維護諸如安全、性能和可用能力。
(8) 數據和商務智能層:這一層包括信息架構、業務分析和商務智能(business intelligengce,BI)、企業元數據(meta data)管理等等。
(9) 治理層:治理層確保一個組織中的服務和SOA解決方案遵守指定策略、指導方針和標準,SOA治理活動符合企業和IT治理準則和標準。
10.5.2 服務設計
服務分析與設計的步驟:
識別服務
描述服務
服務實現
1、識別服務
目前有三種策略幫助我們識別候選服務:
自上而下的分解
自下而上的現有系統分析
業務目標對齊
圖書館系統的候選服務
以讀者的整個服務流程出發,識別出的候選服務:
1 辦理讀者卡
1.1 提交辦卡申請
1.2 發放讀者卡
2 借書
2.1 檢查讀者信息
2.2 處理圖書借閱 (2.2.1 保存借閱記錄 2.2.2 更新圖書信息)
3 還書
3.1 獲取借閱記錄
3.2 銷記借閱記錄
3.3 更新圖書信息
4 注銷讀者卡
4.1 獲取借閱記錄
4.2 轉入歷史檔案
圖書館系統的服務
封裝了為3個服務,服務及其操作如下:
2、描述服務
描述服務細節,定義服務規約,包括輸入/輸出消息等功能性屬性,以及服務各種約束定義、服務之間的關系等等。
-首先選擇可以暴露的候選服務為最終服務
-然后對服務各方面屬性進行描述
圖書館系統的服務
挑選可組裝、松耦合、無狀態的服務對外進行暴露,例如1.1、2.1、3.1、4等 ,然后進行描述,例如:
2.1 檢查讀者信息
輸入參數:讀者卡號
輸出參數:讀者信息(姓名、身份證號、郵箱、電話、借書限額、已借數量、狀態)
其他說明:該服務用來獲取讀者信息和狀態,可以被其他服務使用。
4 注銷讀者卡
輸入參數:讀者卡號
輸出參數:讀者注銷是否成功
其他說明:該服務用來注銷讀者卡號,并將讀者資料轉入歷史檔案,返回是否成功注銷的結果。該服務可以被其他服務使用。本服務先使用4.1服務獲得讀者借閱信息,在不存在借閱信息的情況下,再調用4.2服務完成讀者資料歸檔。
3、設計服務的實現
服務如何包裝,是全新設計還是重用已有構件和軟件類?方案的設計包括:
分析現有系統。了解應用主要功能和對外接口,尋找可復用的構件,例如圖書館系統已有類庫。
確定服務分配。確定服務構件和現有系統軟件構件間的映射關系,如果映射后發現的數據(消息)不匹配的現象需要設計服務中介進行格式轉換,映射不成功的需要設計新的構件等。
確定服務實現策略。選擇服務包裝的技術方案,如采用web service或其他技術。
設計服務基礎設施。如流程引擎、規則引擎等。
10.6 設計原則
總的原則
-抽象與復用(封裝、信息隱藏)
-松耦合
面向功能模塊
-設計功能內聚的模塊,避免使用全局數據
-模塊傳遞的參數作數據用,并且盡可能少
-模塊內語句數一般為50-100
面向對象
-單一職責、開放封閉、里氏替換、依賴倒置…
面向服務
-標準化服務合約、服務松散耦合、服務抽象、服務可復用、服務自治、服務無狀態、服務可發現性和服務可組合性
抽象與復用
模塊化:模塊是廣泛意義上的建模元素,可以是子過程或函數、類、構件、服務、流程等。模塊化強調抽象和封裝。
-好的抽象能讓人們集中精力考慮問題實質,而忽略問題中與主旨無關的次要部分。
-好的封裝能讓一個部件暴露出其最本質的內容,讓人們快速理解和使用它,不讓復雜性蔓延。
模塊化的另一個好處就是復用。
-不同業務流程中重復對一組數據執行同一操作,對這類數據和操作進行合理抽象和封裝后,就能在多個地方進行復用,節約了成本,提高了效率。
松耦合
任何事物只要相互之間存在某種關系,就意味著事物間的耦合。
-緊耦合:是指應用系統的各部件在功能上、數據上或結構上是緊密相連的,因而每當某個部件發生變化時,相關部分的也要隨之進行部分甚至整個應用程序的調整。
-松耦合:面對變化則具有很好的適應能力和應變能力。
耦合和內聚有著密切關系,通常高內聚就會帶來松耦合
單一職責原則SRP
即內聚性原則。
單一職責的模塊 →單一職責的類。
一個類承擔的職責過多,某個職責的變化可能會削弱或者抑制該類完成其他職責的能力,并影響到構建、測試和部署等活動。
多職責會導致脆弱的和不易理解的設計。
開放封閉原則OCP
軟件實體(類、模塊、函數等)應該是“可擴展”的,但又是“不可修改”的。
“變化才是不變的真理”,但通過設計使得系統能夠適應改變又能保持相對穩定,避免僵化的設計。
開放-封閉原則實現兩個目標:
-“對于擴展是開放的”(open for extension)。這意味著模塊的行為是可擴展的,從而使其具有滿足那些改變的新需求。
-“對于更改是封閉的”(closed for modification)。當對模塊進行擴展時,不必改動模塊的源代碼或二進制代碼(如dll/jar文件)。
Liscov替換原則LSP
實現OCP的主要機制是抽象和多態。怎樣設計最佳的繼承層次,Barbara Liskov在1988年首次提出LSP:子類型(subtype)必須能夠替換掉它們的基類型(base type)。
假設S是T的子類型,所有使用了T對象的程序(也稱客戶程序),用S對象替換T對象后,仍能成功執行。
LSP是多態順利實現的保證,從而使OCP成為可能。因為正是子類型的可替換性才使得使用基類的模塊在無需修改的情況下就可以擴展。
增加或修改任何一個子類型,基類不用修改(封閉)
基類的使用者(客戶程序)通過多態得到擴展或修改過的行為(開放)。
依賴倒置原則DIP
A 高層模塊不應該依賴于低層模塊,二者都應該依賴于抽象(也稱針對抽象編程);
B 抽象不應該依賴于細節,細節應該依賴于抽象。
結構化設計時,高層模塊總是依賴于低層模塊。面向對象的分層模式中也是高層的類依賴于底層的類。
按照自上而下的依賴關系,高層的策略設置模塊往往是無法重用的,如果設法讓高層模塊獨立于低層模塊,則實現重用就變為可能。
依賴倒置原則的啟發式建議是“依賴于抽象”,具體做法是將高層需要的服務聲明為抽象接口,高層使用這些接口,低層模塊實現這些接口,使得高層不再依賴于低層,而是依賴于抽象接口,同樣低層也依賴于抽象接口。
10.7 設計模式
GRASP對象職責分配模式
GRASP(General Responsibility Assignment Software Pattern)是一組通用的基本原則和慣用的設計方案,用來指導對象職責的分配和交互圖的創建。OOAD經典著作《UML和模式應用》進行了總結和應用。
GoF23種設計模式
由四人組的專著《設計模式》一書總結了廣為應用的23種設計模式,每種模式解決了一個特定問題,包括一組合適的對象和對象接口,以及對象間協作的方式。
模式是對成功應用經驗的總結與復用
好萊塢電影模式
-社會題材、動作片、言情片、歷史題材片…
中國象棋開局
-當頭炮、順炮、列炮、屏風馬…
圍棋布局
-星小目、三連星、中國流、宇宙流…
古代行軍布陣
-八陣圖、天門陣、一字長蛇陣…
建筑、服裝、交通、社會、文化…諸多模式
設計模式的基本思想
軟件是在不斷進化的
-需求在不斷改變,所以軟件應該適應變化
-設計模式是為了讓軟件更加適應變化,有更多的可復用性;就是有變化時你不用從頭重寫一次這個軟件
如何適應變化?
-就應該封裝變化,讓變化的影響最小
-封裝復雜性,提供簡單的接口
遵守上述設計原則:
松耦合
針對接口編程,而不是針對實現編程
使用繼承、組合、委托、多態、泛型
設計模式的基本要素
名稱:用于助記,形象表示這個模式
問題:這個模式可以解決什么問題
解決方案:這個模式怎樣解決這個問題的步驟與方法
效果:使用這個模式與不使用這個模式有什么區別,它有什么優點和缺點
一個問題可以有多種解法,好的解法都可以找到很多種,每種都有優缺點,某個模式也不一定永遠是最好的。
總結
以上是生活随笔為你收集整理的信息系统分析与设计 第十章 系统总体设计的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vue-Vant组件上传图片
- 下一篇: 冰桶挑战”的火爆程度与朋友圈?