都說軟件架構要分層、分模塊,具體應該怎么做之一
一、軟件架構設計的生命周期
1. 軟件開發(fā)流程
2. 關于套路
3. 先僵化,后優(yōu)化,再固化
4. 佛說:知我說法,如筏喻者
二、需求調(diào)研和需求分析
1. 功能需求
2. 質(zhì)量屬性
3. 條件約束
4. 畫用例圖
5. 寫用例描述
6. 確定關鍵需求
一、軟件架構設計的生命周期
什么是架構?如果你問十個人,有可能得到十一種不同的答案;如果去翻一下相關的書籍,每一本都可能給出不同的定義。
因此,我們沒必要糾結(jié)于那些概念,只要方法對、能完成項目任務就行,不管黑貓白貓,能抓到耗子的就是好貓!
1. 軟件開發(fā)流程
一個軟件項目,從立項開始到最終的交付,中間經(jīng)歷了諸多環(huán)節(jié)。具體到軟件設計的生命周期來說,可包括這些階段:需求調(diào)研-需求分析-概要設計-詳細設計-架構驗證-開發(fā)-單元測試-集成測試。
上面這幾個步驟,仍然是非常粗略的概念。在實際操作中,其中的每一個步驟又可以細分為很多具體的執(zhí)行環(huán)節(jié)。
例如:
- 需求調(diào)研:應該怎么做?用什么方法?有什么指導思想?有什么好的工具?
- 需求分析:應該怎么分析?所有的需求都應該被分析嗎?如何找出關鍵需求?
- 詳細設計:在軟件工程中有什么實踐性比較好的方法?如何分層?如何分模塊?
以上這些都是軟件設計的過程中,需要涉及到的問題。那么軟件設計的最終目標是什么呢?就是下面幾個文檔:
- 邏輯架構;
- 物理架構;
- 運行架構;
- 開發(fā)架構;
2. 關于套路
我認為,在這個世界上,一切皆有套路,包括任何事情、任何領域、任何行業(yè)。
當我們進入一個新的領域時,比如:讓你設計一個車輛調(diào)度系統(tǒng)、機器人控制系統(tǒng),或者設計一個對講機、一個物聯(lián)網(wǎng)網(wǎng)關,如果你是這個領域的新人,那么肯定是兩眼一抹黑:我對這個領域完全不懂,怎么設計啊?
這讓我想起一個小故事:
有一次我剛?cè)肼氁患倚鹿荆邮忠晃浑x職同事手里的工作。當時執(zhí)行 KPI 考核,bug 直通率(就是一次性把 bug 解決掉的比例,QA 人員不會再把 bug 踢給你),是一個重要的指標。面對系統(tǒng)里那么多的bug,領導問我:這些問題你大概需要多久能解決掉?我說:以前沒接觸過這方面的工作,沒法給出準確的時間。領導說:沒關系,你先給我一個具體的時間就行了。當時我就懵逼了。
在這個時候,最重要的事情就是,快速把這個領域里的基本的、重要的背景知識了解、掌握。那么應該如何做呢?找套路!
不要貪大求全,不要奢望把所有相關的內(nèi)容都掌握,這是不可能的,尤其是在短時間內(nèi)。我們的目標是把活做好,把項目完成。
這個時候,我一般的做法是:找套路!
這么說可能有點虛幻,那么就以軟件開發(fā)中的架構設計來舉例。在軟件工程或者項目管理的書籍、資料中查找下面這些相關內(nèi)容:
- 別人是怎么來設計架構的?
- 設計過程中需要哪些步驟?
- 每一個步驟中,輸入是什么?輸出是什么?
- 每一個步驟中,需要考慮的點是什么?
- 有哪些好的軟件工具?
- 如何與項目的相關人進行溝通(項目經(jīng)理、開發(fā)人員、測試人員、甲方客戶)?
把以上的這些別人的經(jīng)驗進行梳理,總結(jié)出一套適合自己的“方法論”,然后在具體執(zhí)行的時候按照這個套路一步一步的走,根據(jù)實際情況適時的動態(tài)調(diào)整,一般來說都能夠順利的推進一個項目。
3. 先僵化,后優(yōu)化,再固化
這九個字是華為的掌舵人任正非在引進管理體系時提出的,這是一種非常實用的方法。
- 僵化:站在巨人的肩膀上:處于學習初期階段的“削足適履”;
- 優(yōu)化:掌握自我批判武器:在實踐中不斷吸收、改良、創(chuàng)新,優(yōu)化自己;
- 固化:創(chuàng)新是有階段性的、受約束的,如果沒有約束,創(chuàng)新就是雜亂無章、無序的創(chuàng)新,需要像夯土一樣,一層層夯上去,一步步固化階段性的優(yōu)化成果;
對于軟件架構設計,我們也可以按照這樣的步驟走。
第一步就是僵化,也就是按照按照固定的套路走,雖然可能會“落入俗套”,但是至少能保證在正確的道路上,不會走歪,這是最重要事情!
如果被別人認為是“落入俗套”了,說明什么?說明別人已經(jīng)認為你的做法符合這個領域中最“一般的”的做事流程,也就是相當于認可你已經(jīng)真正進入這個領域了,這是好事情!
作為初學者,被別人這樣評價,不應該覺得自豪嗎?畢竟我們自己心里知道:我就是剛剛進入這個領域的小白而已。
4. 佛說:“知我說法,如筏喻者”
我寫這篇文章的目的,主要就是想聊一聊我是如何“僵化”的來進行軟件架構設計的。
我們在剛進入軟件開發(fā)行業(yè)的時候,每天的工作主要是擼代碼,也許還不夠資格來進行整個系統(tǒng)的架構設計。但是這并不妨礙我們自己來主動學習,機會都是留給有準備的人的,如果有一天,項目組里出現(xiàn)了架構設計的這個坑,那么領導會找哪個蘿卜來填坑呢?
因此,這篇文章主要介紹的就是最初級、最基本的軟件設計步驟,以及在每一個步驟中使用的指導思想、順手的工具等等。
如果您已經(jīng)是資深軟件設計工程師,那么可以去喝咖啡、享受人生了,當然也可以分享您的方法論,我們相互學習!
這些內(nèi)容也不是我自己摸索出來的,而是在項目開發(fā)過程中翻閱書籍、搜索資料、總結(jié)而來的,比較適合我所面對的項目,我也僅僅是知識的搬運工。
之前,我主要參考了幾本關于軟件架構設計的書籍,相互借鑒,總結(jié)出適合我的一套方法。上次搬家,好多書籍丟掉了,只剩下電腦里的零碎筆記了。這篇文章的素材來源,就是這些筆記,當然,大部分內(nèi)容都是來源于書本,我只是進行了一些取舍、裁剪而已。
《金剛經(jīng)》第六品,如來常說:“汝等比丘,知我說法,如筏喻者;法尚應舍,何況 非法。”
佛法就像渡人過河的木筏,過了河上了岸,就應該把木筏丟掉,心中不要再想著木筏。木筏就像佛法,佛法尚且應該丟棄,何況不是佛法的東西,你還糾結(jié)他干嘛。
所以,我這里所講的設計套路,也類似于木筏,用來幫助你在剛開始進入軟件架構設計時的一個腳手架。當你進入到第二個段位“優(yōu)化”時,就可以把這個腳手架扔掉了。
到那個時候,你就可以自信的說一句:“道哥寫的都是寫什么東西啊,小兒科的東西,我需要向更高級的段位去探索”。到了這個時候,我就要衷心的恭喜你了!
二、需求調(diào)研和需求分析
大多數(shù)人都認同“需求決定架構”,但是需求究竟是“如何決定”架構的?這部分就來聊一下我的認識。
在立項階段,如果運氣比較好,可能會拿到一份文檔《軟件功能需求規(guī)格書》(話說一些日本公司的需求說明書,寫的真的是變態(tài)的詳細)。如果運氣不好,什么文檔都沒有,所有的需求全部需要自己來收集、整理。
從狹義上來說,需求就是功能;從廣義上來說,還包括質(zhì)量屬性、條件約束這些非功能需求。
1. 功能需求
功能需求部分是最直觀的,就是我們設計的軟件需要完成哪些事情。在一個系統(tǒng)中,各個功能之間不可能有清晰的邊界的,每一個小模塊之間通過一定的交互,形成一條一條的“協(xié)作鏈條”來完成指定的功能。
例如下面這張圖,是我之前寫的一篇文章:物聯(lián)網(wǎng)網(wǎng)關開發(fā):基于MQTT消息總線的設計過程(上) 中,不同模塊之間的交互模型,紅色和藍色部分就是 2 條不同的協(xié)作鏈條。
當然了,這幅圖是最終設計出來的系統(tǒng)架構(分層、分模塊),在得到這幅圖之前,我們首先要把所有的功能需求進行收集、整理。
在這個階段,最重要的事情是做什么,而不是怎么做。另外,作為設計人員,需要經(jīng)常問自己一個問題:掌握的需求全不全?有沒有遺漏?
2. 質(zhì)量屬性
我們可以把質(zhì)量要求,按照不同的階段來進行歸類:
開發(fā)階段
- 可重用性,不要做重復的工作;
- 靈活、容易擴展(想一想發(fā)生的需求變更時開發(fā)人員的心理活動);
- 容易理解(想想你接手別人的項目時);
- 方便測試(單元測試、集成測試);
- 可移植(尤其是嵌入式項目,需要運行在不同過的平臺);
運行階段
- 系統(tǒng)必須可靠;
- 性能必須達到一定要求(吞吐量、響應時間等等);
- 沒有漏洞,系統(tǒng)安全;
- 伸縮性要好,方便擴展部署;
3. 條件約束
約束主要是指一些限制條件,比如:
- 團隊人員的技術棧情況(如果大家都用C,你就不要選擇C++);
- 領導給的資源有哪些;
- 如果利用一些開源軟件,是否存在bug?是否方便二次開發(fā)?
- 項目開發(fā)周期是多久?
- 軟件的運行平臺有哪些?有什么限制?
4. 畫用例圖
關于用例圖的概念,我也總結(jié)不好,這里就直接引用百度知道里的定義了:
用例圖是指由參與者(Actor)、用例(Use Case),邊界以及它們之間的關系構成的用于描述系統(tǒng)功能的視圖。
用例圖(User Case)是外部用戶(被稱為參與者)所能觀察到的系統(tǒng)功能的模型圖。用例圖是系統(tǒng)的藍圖。用例圖呈現(xiàn)了一些參與者,一些用例,以及它們之間的關系,主要用于對系統(tǒng)、子系統(tǒng)或類的功能行為進行建模。
其中有幾個概念:
- 參與者: 不是特指人,是指系統(tǒng)以外的,在使用系統(tǒng)或與系統(tǒng)交互中所扮演的角色。
- 用例:是對包括變量在內(nèi)的一組動作序列的描述,系統(tǒng)執(zhí)行這些動作,并產(chǎn)生傳遞特定參與者的價值的可觀察結(jié)果。
- 系統(tǒng)邊界: 是用來表示正在建模系統(tǒng)的邊界。邊界內(nèi)表示系統(tǒng)的組成部分,邊界外表示系統(tǒng)外部。
- 箭頭: 用來表示參與者和系統(tǒng)通過相互發(fā)送信號或消息進行交互的關聯(lián)關系。
- 作用:(1)獲取需求;(2)指導測試;(3)還可在整個過程中的其它工作流起到指導作用。
我從網(wǎng)上找了幾個用例圖,其中的每一個圓圈,都代表一個功能。
通過用例圖,可以一目了然的看到系統(tǒng)提供的所有功能。
5. 寫用例描述
但是用例圖沒有詳細的描述每一個用例的執(zhí)行過程,也就是說:用例圖從總體上描述了系統(tǒng)的需求,但是沒有描述行為過程。
因此,我們可以對每一個用例,附上一個簡單或詳細的用例描述,這樣就更加具體的確認了這個用例的行為過程。
下面也是從網(wǎng)絡上找的 2 個用例描述示例,可以看到并沒有統(tǒng)一的格式,需要根據(jù)項目的性質(zhì)進行增減。
6. 確定關鍵需求
假設我們在不斷的搜集和分析中,盡可能地列出了所有的需求(功能需求、質(zhì)量屬性、條件約束),下一步需要做什么呢?需求這么多,該從哪一個需求入手呢?
關鍵需求 = 關鍵功能 + 關鍵質(zhì)量。它確定了架構的大方向。
首先要明確一點:不可能所有需求都是一律平等。我們要從眾多的用例出找出下面這 3 類需求:
- 關鍵功能需求:那些涉及到的模塊最多、模塊之間協(xié)作方式最有代表性的功能,篩選出關鍵功能子集;
- 關鍵質(zhì)量屬性:在開發(fā)和運行階段,哪些質(zhì)量屬性對軟件架構的影響比較大,如果質(zhì)量屬性之間存在相互矛盾的地方,應該優(yōu)先考慮哪個?
- 高風險部分:從技術難度上考慮,哪些功能在技術實現(xiàn)上存在風險,需要體驗提前進行技術驗證?
這 3 類需求就是需要我們重點照顧的需求,也是進行下一個步驟(領域建模)的輸入材料。
本文轉(zhuǎn)載自微信公眾號「IOT物聯(lián)網(wǎng)小鎮(zhèn)」,可以通過以下二維碼關注。轉(zhuǎn)載本文請聯(lián)系IOT物聯(lián)網(wǎng)小鎮(zhèn)公眾號。