軟件設計實踐

本文首發於個人微信公衆號《andyqian》, 期待你的關注!

前言

  拿破崙曾經說過:“不想當將軍的士兵不是好士兵”。而在軟件行業中,幾乎每個程序員心裏都有一個成長爲架構師的夢想。程序員與架構師之間,不僅僅是角色的轉變,更多的是知識的積累,以及架構,設計能力的轉變。最近有幸參與了一些設計工作,系統算不上覆雜,龐大。但在這過程中將自己的不足暴露的淋漓盡致,如同裸奔,有着涼颼颼的感覺。記錄這篇文章,算是一次小結,同樣也給自己之後系統設計時留下一絲指引。

願景

  願景二字其字面意思是:希望看到的場景。這一詞在潘加宇老師的《軟件方法》中解釋爲:我們希望新系統 / 服務 是怎樣的 ?也就是爲以下幾點:

  1. 我們爲誰編寫系統?也就是尋找到業務 “老大”,可以理解爲解決XX的問題?這個 XX 就是老大。

  2. 我們編寫該系統的目的是什麼?

  3. 希望通過它能夠解決什麼問題?

  4. 沒有該系統前,業務是怎樣運行的?(現狀)

  5. 有該系統後,業務會發生怎麼樣的變化 ?(改進後)

     

在願景中,個人建議添加適量的可量化值,以及圖(交互圖)等更直觀的表達體來體現兩者之間的差異。例如:

  1. 改進前:TPS 是 1000,改進後:TPS 是 2000 等。

  2. 改進前:對接新產品需要 40天, 改進後:對接新產品只需要 20 天。

業務用例

   技術人員一直有個不願承認的事實是:技術是爲業務服務的,而技術是一種業務實現的手段/工具。在這樣的前提下,我們在做新系統設計時,優先需要理清業務,先做業務分析設計。在進行業務分析設計時,我們以組織爲研究對象。組織提供的價值稱之爲業務用例,組織外部與系統交互的人或組織稱之爲業務執行者,組織內的人稱之爲業務工人,組織內非人系統稱之爲業務實體。

進行業務設計分析時,常用工具有:用例圖, 時序圖

  1. 用例圖

其表達的核心價值是:業務組織向業務執行者提供哪些價值,而這些價值通常用業務用例表示。在用例圖中用到的元素有:業務執行者,組織,業務用例。例如:騰訊這個組織,向微信支付用戶,提供小程序支付這個價值的業務用例。如下圖所示:

圖(1) 業務用例圖

  1. 時序圖

在UML中,時序圖是動態的交互圖。其表達的核心價值是:業務執行者,業務實體,業務工人之間在完成該業務時的交互。如下圖所示:

 

圖(2) 業務時序圖,來源於微信支付官方

其中:

  1. 業務執行者:微信支付用戶

  2. 業務實體:商戶系統,微信後臺, 微信小程序

  3. 在上圖中,並沒有業務工人。

系統用例

  上面介紹了業務用例,接下來就是系統用例。上面說到,業務用例是以組織爲研究對象,對外提供的價值稱之爲業務用例。而系統則是以系統爲研究對象,與系統交互的人或系統稱之爲系統執行者,系統提供的價值單元稱之爲系統用例。在系統用例中,比較常用的工具有:用例圖,時序圖

以上面例子所述,系統用例圖,如下圖所示:

圖(3) 系統用例圖

解釋:微信支付系統向微信支付商戶提供:統一下單,訂單查詢,訂單關閉,查詢退款,下載對賬單 等等系統價值,而該價值稱之爲系統用例。

其中:

  1. 系統:微信支付系統就是我們研究的對象。

  2. 系統執行者:微信支付商戶。

  3. 系統用例:統一下單,訂單查詢,訂單關閉,查詢退款,申請退款,下載對賬單 等稱之爲系統用例。

     

如果說:每個系統用例是系統提供的價值封裝。而系統時序圖:則是系統在完成該價值時的內部交交互。

包圖

  包圖是最容易忽略的,恰恰它在項目中發揮着極其重要的作用。倘若一個系統沒有使用包進行歸類,其可維護,可擴展性是不可想象的。例如:我們熟悉的 java.util 下的簡易包圖,如下所示:

圖(4) java.util 包圖

仔細看看上面的包圖,其實不難發現,每個包做的事情都是原子的,如同設計模式中的單一職責一樣。我們在使用包圖時,也要遵循這樣的設計思想。

包的分類

  1. 項目中按照模塊進行劃分,每個模塊就是一個包。

  2. 在模塊內部,則按照職責進行劃分,相同職責的類放在同一個包中。

  3. 當然,在使用包圖時,我們還需要注意包與包之間的關係。

    (在這裏就不展開了,請自行查閱文檔)

類圖

  類圖是UML中常用的靜態結構圖,在系統設計時,我們需要用類圖來表達類的構成,以及類與類之間的關係。
如下所示:

圖(5) ArrayList 類圖

在UML中類圖由以下幾點構成:類名,類屬性,類方法。

常用的類與類之間的關係有:

  1. 實現:

  2. 繼承(在UML工具中用:

    Inheritance 或 Generalization 表示)

  3. 關聯

  4. 聚合

  5. 組合

類圖對編碼工作有着非常大的指導意義,在前期捋清楚類與類之間的關係,編碼時,就可以按照設計進行編碼。

狀態設計

  在覈心對象的狀態變化,需要設計清楚。

  1. 該對象有哪些狀態?

  2. 狀態的轉換條件是怎樣的?

在UML中狀態設計中常用的工具有:狀態圖

例如:訂單有:未支付,支付中,支付完成,支付失敗 等狀態。

  1. 用戶下單完成,但未支付時爲未支付狀態。

  2. 用戶正在支付時,從未支付狀態轉換爲支付中狀態。

  3. 用戶支付完成後,從支付中轉換爲支付完成狀態。

  4. 由於系統原因或其他原因,從支付中轉換爲支付失敗狀態。

關鍵算法

  在進行系統設計時,如有關鍵算法,也是需要在設計文檔中體現的,並需要舉例說明。

數據結構設計

  數據結構設計包括以下幾點:

  1. 使用關係型數據庫,還是非關係型數據庫?(具體到某個實際的組件,例如:MySQL)。

  2. 使用什麼存儲引擎?是Innodb還是MyISAM ?

  3. 使用什麼字符集,是 utf8 還是 utf8mb4 ?

     

例如:

表名:t_user
存儲引擎:Innodb
字符集:utf8

圖(6) 表結構設計

在數據結構設計中,需要注意的是:每個表結構中的公共字段名,類型統一。例如:創建時間,修改時間,邏輯刪除標識,主鍵等等。

部署圖

  部署圖,表達的是部署結構,也就是說系統部署態是怎樣的。如:

  1. 部署到雲服務商,還是自建機房?

  2. 從用戶請求到服務中,執行全過程是怎樣的?

非功能性設計

  在非功能性設計時,需要考慮的點有以下幾點:

  1. 監控體系 :監控體系通常包括 系統監控,業務監控。

  2. 性能指標 :  例如 TPS 等等。

     

無論是監控體系,還是性能指標,其實都是相輔相成的。一來能夠知道系統在運行態的情況,二來可以根據監控,性能指標數據來輔助系統的迭代,完善。

陷阱列表

  在做系統設計時,時常會遇到一些”陷阱”。之所以稱之爲”陷阱”,因爲這些點足夠小,在不經意間就會入坑。例如:

  1. 業務分析用例時,摻雜着系統用例。

  2. 缺少關鍵狀態變化設計。例如:訂單狀態由未支付到支付中,再到支付完成。這些狀態由誰觸發?在什麼條件下觸發?

  3. 數據結構設計時,公共字段屬性不統一,例如:A 表的創建時間使用 created_at, B 表的創建時間爲 created_time,A 表的主鍵是自增,B 表的主鍵又是另外一種等等。

  4. 缺少監控以及性能監控。


  

    一份好的設計文檔,對編碼工作有着非常大的指導意義,既能提高軟件質量,也能提供交付效率。在這方面,我自己也是非常薄弱,在此將自己的一點經驗和感想記錄成文,希望對之後的系統設計能有所啓發!


 

參考文獻:

1. 潘加宇 《軟件方法(上) 業務建模和需求》

 


 

相關閱讀:

讀《產品設計思維》有感 !

JDK SPI 源碼解讀

Java 代碼中幾類典型的 "壞味道"

接口設計的五點建議 !

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章