移动架构师第一站UML建模
回想一下自己的Android生涯已經經歷過N多個年頭了,基本都是在編寫業務代碼,都知道35歲程序員是一個坎,當然如果有能力能做到Android架構師的職位其生命周期也會較長,畢境不是人人都能輕易做到這個崗位的,而在我的職位生涯中“Android架構師”一直是想做為一個自己前進的動力,但是一直都是空有其想法,木有實際行動,而這個博客專欄也已經創建多年了,但是還是0沉淀,所以接下來痛定思痛,一點點來打造自己的架構夢。
首先得要系統的復習UML相關的東東,架構圖在實際做架構中是必不可少的,而這項技能也早已經忘得差不多了,為了完美性,這里集中再復習一下它。這里采用的繪圖工具是用的PowerDesigner,如下:
我想應該搞程序的木有人不知道它了,很強大,主要是它可以對其進行Java代碼生成及逆項,但是它只有Windows版的,而我的個人電腦是個MAC。。所以當然得裝個虛擬機,這里推薦一個MAC上我在用的虛擬機“Paralles Desktop”:
在它上面裝了個Wind8,對于學習已經綽綽有余了,另外該模擬器有一個比較好的功能就是說可以將系統裝在一個擴展盤上,由于我的MAC是15年款的,硬盤容量只有256G容量比較小,要是裝在MAC上內置的盤里有點浪費空間,畢境該模擬器只是偶爾用,于是乎我就將其裝到了外接盤里了,非常之方便。
UML概念【了解】:
定義:
是統一建模語言,是一種開放的方法,用于說明、可視化、構建和編寫一個正在開發的、面向對象的、軟件密集系統的制品的開放方法。
作用:
1、幫助開發團隊以一種可視化的方式理解系統的功能需求。
2、有利于開發團隊隊員間在各個開發環節間確立溝通的標準,便于系統文檔的制定和項 目的管理。因為UML的簡單、直觀和標準性,在一個團隊中用UML來交流比用文字說明的文檔要好得多。
3、UML為非專業編程人士理解軟件的功能和構造,提供了一種直白、簡單、通俗的方法。
4、使用uml可以方便理解各種框架的設計方式。
感受一下微信支付官方時序圖:
在正式學習各種UML圖的畫法之前,先來感受一下APP集成微信支付的官網https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_3的一個時序圖,如下:
其整個交互的時序圖為:
當然啦微信的這個支付集成流程有些復雜,但是通過來閱讀這個時序圖能讓集成者對整個的流程有一個比較好的認識,所以UML圖對于程序員而言是可以用最少的語言描述達到一個比較容易理解功能流程的非常直觀有效的一種表達方式,所以在程序員的交流中如果有必要的話用一張清晰明了的流程圖來表達要勝過千言。 在之后的UML學習中會要參考該時序圖的。
面向對象模型(OOM)圖【標紅的則為重點圖,需掌握】:
接下來直接開始復習各種UML圖的畫法,總共有12張,我們在PowerDesigner新建圖時也能看到:
用例圖(The Use Case Diagram)【重要】:
定義:
系統功能的視圖。用例圖(Use Case)是外部用戶(被稱為參考者)所能觀察到的系統功能的模型圖。用例圖是系統的藍圖。用例圖呈現了一些參考者,一些用例,以及它們之間的關系,主要是用于對系統、子系統或類的功能行為進行建模。
組成元素:
接下來咱們建立一下用例圖實踐一下:
然后對應的工具條上就有相關的元素:
這里以一個人去按摩店進行消費來進行一個用例描述,首先來列舉一下該店里面提供的功能:
然后再畫上參與者----人,分為大人和小孩:
接下來需要畫上人之間的關系,很明顯是一種繼承關系,所以關系符用:
接下來參與者與用例之間得關聯一下:
咱們先來畫大人的:
當然此時的關聯關系木有箭頭,可以編輯改一下,這樣好看一點:
此時再把其它的關聯線也給改了:
好,再把小孩的用例關聯上:
其中對于每一個用例其實都包含一個支付功能,所以包含關系就出來了:
此時就得用到工具欄的這個關系了:
然后再在包含關系的線上加上包含的字樣,這樣就比較明了,如下:
也可以使用英文:
最后將其完善:
而對于支付有多種支付方式,比如:
而它跟支付功能是一種擴展關系,而非包含關系,如下:
而它的畫法需要注意一下方向:
其中包含與擴展這倆比較容易混淆,包含是必要條件,也就是我們要享受按磨服務時一定得要支付,而支付時并不是每一種都必須要有,只要其中的一個就成了,也就是支付方式就變為了一種非必要條件了,需要好好體會一下。
結構圖:
它包含有四種圖,其中最最重要的是類圖,這個是必須要掌握的。
類圖(The Class Diagram)【重要】:
定義:
是面向對象系統建模中最常用和最重要的圖。主要是用來顯示系統中的類、接口以及它們之 間的靜態結構和關系的一種靜態模型。是唯一可以直接映射到面向對象的語言。
作用:
1、分析和設計應用程序的靜態視圖。
2、描述一個系統的責任。
3、基地組件圖和部署圖。
4、正向和逆向工程。
正向工程是通過從特定實現語言的映射而把模型轉換為代碼的過程。
逆向工程是通過從特定實現語言的映射而把代碼轉換為模型的過程。
組成元素:
下面對其各種關系進行一個理論上的闡述:
- 泛化(Generalization):是一種繼承關系,表示一般與特殊的關系,它指定了子類如何特化父類的所有特征和行為。例如:老虎是動物的一種,既有老虎的特性也有動物的共性。
- 實現(Realization):是一種類與接口的關系,表示類是接口所有特征和行為的實現。
- 關聯(Association):是一種擁有的關系,它使一個類知道另一個類的屬性和方法;如:老師與學生,丈夫與妻子。關聯可以是雙向的,也可以是單向的。雙向的關聯可以有兩個箭頭或者沒有箭頭,單向的關聯有一個箭頭。
- 依賴(Dependency):是一種使用的關系,把一個類的實現需要另一個類的協助,所以要盡量不使用雙向的互相依賴。
- 聚合(Aggregation):是整體與部分的關系,且部分可以離開整體而單獨存在,如車和輪胎是整體和部分的關系,輪胎離開車仍然可以存在。
- 組合(Composition):是整體與部分的關系,但部分不可以離開整體而單獨存在,如公司和部門是整體與部分的關系,沒有公司就不存在部門。
下面新建一張類圖:
此時的工具欄上就多了一些按鈕了:
下面還是以支付為例子來畫一下類圖:
先畫一個下單接口:
雙擊對它進行一下編輯:
點擊確定:
此時可以預覽一下它生成的代碼:
這就是所謂的正向工程,然后給這接口添加一些方法,如下:
預覽一下代碼:
確定:
既然有接口,那就肯定得有實現類,所以下面新建一下:
接下來則是需要畫一下關系:
此時可以看一下代碼預覽:
有了這個代碼預覽功能就可以驗證我們畫的UML類圖是否畫得對,接下來在具體類中需要實現接口中的抽象方法,所以:
點擊確定:
此時再看一下代碼預覽:
接下來再來新建一個下單管理類:
然后在里面添加一些方法:
其中這個有4個訪問修飾符:
package:
private:
protected:
public:
咱們這還是定成private的,接下來再來定義方法,由于該管理類是一個單例對象,所以定義一個getInstance()方法:
并且該方法是靜態的,所以:
此時再看一下代碼預覽:
點擊確定:
接下來再定義一個下單方法:
接下來再創建一個網絡管理類:
然后里面添加一個屬性:
然后可以給它生成下構造方法:
再加兩個網絡類型判斷方法:
好,接下來畫一下關系,對于下單管理類肯定是要依賴于網絡管理類的,所以:
而下單管理類跟下單接口實現類是關聯關系:
此時看一下生成的代碼:
/************************************************************************ Module: OrderManager.java* Author: xiongwei* Purpose: Defines the Class OrderManager***********************************************************************/import java.util.*;/** @pdOid c38fa9ae-97d1-4b62-989d-172e9277a938 */ public class OrderManager {/** @pdOid 2cb8adc1-665f-403e-a8e6-243d9446c01a */private boolean isNetWork() {// TODO: implementreturn false;}/** @pdRoleInfo migr=no name=OrderAchieve assc=association1 coll=java.util.Collection impl=java.util.HashSet mult=0..* */public java.util.Collection<OrderAchieve> orderAchieve;/** @pdOid befe4d63-177a-4866-a6d7-55e88a7acf98 */public static OrderManager getInstance() {// TODO: implementreturn null;}/** @pdOid 0976ab18-6bfc-48e7-b598-57d0edd083c3 */public void submit() {// TODO: implement}/** @pdGenerated default getter */public java.util.Collection<OrderAchieve> getOrderAchieve() {if (orderAchieve == null)orderAchieve = new java.util.HashSet<OrderAchieve>();return orderAchieve;}/** @pdGenerated default iterator getter */public java.util.Iterator getIteratorOrderAchieve() {if (orderAchieve == null)orderAchieve = new java.util.HashSet<OrderAchieve>();return orderAchieve.iterator();}/** @pdGenerated default setter* @param newOrderAchieve */public void setOrderAchieve(java.util.Collection<OrderAchieve> newOrderAchieve) {removeAllOrderAchieve();for (java.util.Iterator iter = newOrderAchieve.iterator(); iter.hasNext();)addOrderAchieve((OrderAchieve)iter.next());}/** @pdGenerated default add* @param newOrderAchieve */public void addOrderAchieve(OrderAchieve newOrderAchieve) {if (newOrderAchieve == null)return;if (this.orderAchieve == null)this.orderAchieve = new java.util.HashSet<OrderAchieve>();if (!this.orderAchieve.contains(newOrderAchieve))this.orderAchieve.add(newOrderAchieve);}/** @pdGenerated default remove* @param oldOrderAchieve */public void removeOrderAchieve(OrderAchieve oldOrderAchieve) {if (oldOrderAchieve == null)return;if (this.orderAchieve != null)if (this.orderAchieve.contains(oldOrderAchieve))this.orderAchieve.remove(oldOrderAchieve);}/** @pdGenerated default removeAll */public void removeAllOrderAchieve() {if (orderAchieve != null)orderAchieve.clear();}}其中就在里面是擁有一個下單接口的集合,然后還針對集合自動生成了一大堆的輔助方法。。當然咱們可以將其修改為1對1,則就沒有這么多的集合相關的方法了,如下:
此時再看一下代碼預覽發生的變化:
然后再新建一個課程類:
里面定義點屬性:
而它跟下單管理類是一種組合的關系,為啥,因為下單時離不開課程類,需要根據課堂的價格來進行下單,所以:
其中下單管理類的關系應該只有1個,所以改一下:
好,接下來再來回到下單管理類中的下單方法中增加一個參數,如何增加?
此時點擊確認:
接下來再新建一個學員類,下單肯定是學員來觸發的:
里面定義一下它的屬性:
而學員又分為普通學員和VIP學員:
此時可以很方便的來繼承父類的屬性,如下:
同樣的:
其中Vip學員是不需要下單的,只有普通學員需要下單變為Vip學員,所以普通學員和下單管理類則有一層關系:聚合
因為沒有學員,其實也可以進行下單的,所以下單管理類可以離開學員而單獨存在,所以畫一下:
好,這個例子的關系已經畫得差不多了,接下來,弄一個好玩的,將其正向工程生成Java代碼:
這樣通過類的關系模型就生成了我們想要的Java代碼了,是不是很方便,不過目前生成的代碼里面有大量沒啥意義的注釋,比如:
/************************************************************************ Module: NetWorkManager.java* Author: xiongwei* Purpose: Defines the Class NetWorkManager***********************************************************************/import java.util.*;/** @pdOid 96c6bb5b-31fa-4524-884f-5ca6de5e29be */ public class NetWorkManager {/** @pdOid 79cb90f0-5b97-4fd7-a9d3-33aa88e5792a */public boolean isNetwork;/** @pdOid 38ad5e7b-a1c3-48e6-80bc-10ba86891eeb */public NetWorkManager() {// TODO: implement}/** @pdOid 972b9a4f-5df1-42a2-838f-17f6aee2a896 */public boolean isMobileNetwork() {// TODO: implementreturn false;}/** @pdOid 361bd5ab-9cc9-48bf-a17c-7bb0024ca889 */public boolean isWifiNetwork() {// TODO: implementreturn false;}}其實是可以去掉的,這里再重新生成一次:
點確定之后再來生成一次,則就干凈了:
/************************************************************************ Module: NetWorkManager.java* Author: xiongwei* Purpose: Defines the Class NetWorkManager***********************************************************************/import java.util.*;public class NetWorkManager {public boolean isNetwork;public NetWorkManager() {// TODO: implement}public boolean isMobileNetwork() {// TODO: implementreturn false;}public boolean isWifiNetwork() {// TODO: implementreturn false;}}以上是一個正向工程的過程,也就是將模型轉換成代碼的過程,而PowerDesigner還能逆向工程,也就是把代碼轉換成模型的過程,下面來試一下,咱們就將已經生成的Java代碼逆成模型,先新建一個新的類圖用來呆會逆向用:
然后再執行逆向菜單,如下:
點擊確定就可以逆向成圖啦。不過對于類圖重點不是正向和逆向,而是要學會怎么來畫類圖。
組合結構圖(Composite Structure Diagram):
定義:主要是用于描述類中的內部結構,和類與類之間的關系。它是比類圖更加抽象的表示,一般來說先畫組合結構圖再畫類圖。注意事項:側重類的整體特性,就使用類圖;而如果側重類的內部結構則使用組合結構圖。
組成元素:
下面來實踐一下,新建一張組合結構圖:
然后下面還是以下單為例,先定義一個下單管理類:
可見對于組合結構圖中的類來說就看不到具體細節了,接下來它里面會依賴于這幾個東東,就得這樣畫了:
接下來再來畫一個用戶類,它里面的屬性也可以當成它的一個部件,如下:
然后描述一下用戶跟下單管理類的關系,可以用組合:
其關系的畫法跟類圖是一模一樣的,只是圍度不一樣,這個圖只關心類的一個結構。?
對象圖(Object Diagram):
定義:顯示某一時刻對象和對象之間的關系,比如好理解,也就是描述對象的一些關系,而非類。
組成元素:
下面畫一下:
然后還可以給該對象添加一些屬性,如下:
再定義一下其它對象:
再來新建:
再表述一下它們的關系:
還有一個依賴關系,畫一下:
包圖(Package Diagram):
定義:顧名之意就是用來描述包與包之間的關系的。
組成元素:
下面新建一下簡單使用一下,比較簡單:
動態圖【包含以下四種圖】:
時序圖(Sequence Diagram)【重要】:
定義:又名序列圖、循序圖、順序圖,是一種UML交互圖。它通過描述對象之間發送消息的時間順序顯示多個對象之間的動態協作。它可以表示用例的行為順序,當執行一個用例行為時,其中的每條消息對應一個類操作或狀態機中引起轉換的觸發事件。
組成元素:
如開篇我們看到的微信支付的時序圖一樣,下面咱們來畫一下:
下面以用戶下單為例子來簡單的畫一下:
接著開始下單:
在連線到下單之前得在這塊增加一個控制焦點:
接著就會調用統一下單接口:
此時該接口會生成一個訂單,則需要這樣畫了:
此時則會返回消息了,則需要用:
通信圖(Communication Diagram):
定義:和時序圖相同,只是表示形式不同,可直接轉換。
組成元素:
下面咱們來將上面畫的時序圖直接轉換成通信圖來瞅瞅:
這樣就將其轉換成了通訊圖了,不過默認生成的布局有些亂,得自己稍加排一下位置:
活動圖(Activity Diagram)【重要】:
定義:表示一個過程,有點像流程圖。這個在實際工作中是基本都會要用到的。
組成元素:
下面來畫一個:
活動以圓點開始:
接下來有個條件分支:
另外為了可讀,可以給這兩條分支線上加入Y或N標識,如:
接下來在調起微信支付時又會有一個條件分支:
而對于查詢服務器也存在成功與失敗的分支,如下:
當支付成功之后,則整個流程也就結束了,所以畫一個結束符:
以上是一個異步的流程圖,下面再來看一下同步的流程圖得如何來畫?
接下來就得畫同步處理了,需要用到它:
狀態圖(Statechart Diagram):
定義:表示過程中的狀態情況。
組成元素:
這里就不畫了,直接看一下例子就秒懂了:
交互縱橫圖(Interaction Overview Diagram):
定義:用來表示多張圖之間的關聯
組成元素:
基本都沒聽說過,下面來用一下:
然后它只能關聯時序圖和通信圖,所以先來添加到我們的這張圖上,點擊:
點擊到圖上時,就會立馬彈出一個框讓我們選擇相關的圖,這里先選一下之前畫過的時序圖
再添加一張通訊圖,這樣才能表達兩者的關系:
了解一下既可,基本上實際不會用它。
交互圖:
組件圖(Component Diagram):
定義:主要目的是顯示系統組件間的結構關系。
組成元素:
比較簡單,大致看一下示例了解既可:
部署圖(Deployment Diagram):
定義:多數用于表示硬件結構,做系統集成很方便。
組成元素:
看一下示例:
可能搞運維的會有畫這種圖的需求,下面還是稍加演練一下,新建一張部署圖:
先畫幾個結點:
然后再搞一個部件:
其中每一個元素都可以換一張直觀的漂亮圖,比如說:
艾瑪~~以上就完整的將整個UML的各種圖的畫法過了一遍,真是不容易,以后UML就不想再學了,僅此這篇作為以后的備忘。。
總結
以上是生活随笔為你收集整理的移动架构师第一站UML建模的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: RGB,CMY(K),YUV,YIQ,Y
- 下一篇: 深度残差网络+自适应参数化ReLU激活函