FAQ-開發時需要先完成全部詳細設計/類圖嗎,如果需要那要詳細到什麼程度?

簡便起見只考慮單線程。

如果要開發一個功能,雖然步驟都很明晰了,但功能調用子功能,層層調用到最深層的基本功能,各功能之間的調用關係還是挺龐雜的。

現在有兩種選擇(或許有更多?):

  • 先畫出類圖/函數調用圖,而且把類的功能細節全部設計完成再開始動手開發
  • 大致設計幾個類的成員變數/成員方法,然後立刻開始從最底層的功能開始開發

我在工作中,從最底層開始開發的時候,開發了一段時間才發現此前設計時太粗糙導致這個底層類完全沒必要存在或者功能和預設的完全不一樣。但如果先把所有的類和調用關係都設計好,畫出UML圖,是不是會變成過度設計?特別是不知不覺就變成了大量的介面/繼承之類的,如果開發中途遇到問題要修改設計,面對幾十個類的UML圖,改動起來也是束手束腳。從TDD的觀點看,應該是測試驅動設計,而不是花大量時間設計好了才開始開發/測試。

那麼,開發時,完整詳細的設計(包括所有類的詳細類圖)是應該先全部完成了再開發嗎?還是先從底層小類開始開發?還是有其他的步驟?


但如果先把所有的類和調用關係都設計好,畫出UML圖,是不是會變成過度設計

企圖把所有的類和關係都設計好,這很可能是一種過度設計,這種想法也是一種常見、低效的瀑布思維:要把所有設計圖都畫好了,才能寫代碼。

高手的做法:

先把實現一個功能的(所有)關鍵的類和動靜態關係設計好,而不是「所有」;畫 UML 圖也不需要畫出所有的細節。

請注意,「所有的」與「所有關鍵的」含義上有所不同,後者的元素要少於前者。

我在工作中,從最底層開始開發的時候,開發了一段時間才發現此前設計時太粗糙導致這個底層類完全沒必要存在或者功能和預設的完全不一樣。

設計太粗糙導致後來重構、返工,這通常是因為開發者的設計技能與經驗不足造成的,比如不熟悉 OOAD 因而不能像高手那樣能很快地獲得簡潔、穩定的設計,也可以說是設計的預見性差。

開發時,完整詳細的設計(包括所有類的詳細類圖)是應該先全部完成了再開發嗎?

從TDD的觀點看,應該誰測試驅動設計,而不是花大量時間設計好了才開始開發/測試。

XP 的 TDD 是一個極端(極少的 OOAD 與 upfront design,一上來就寫單測),瀑布做法(畫出所有的類,詳細設計)則是另一個極端,其實寫代碼前的設計太少或太多兩者都不可取。在極左與極右之間,有沒有中間狀態、中間派呢?當然有了,例如 UP、太極敏捷的 BP(平衡編程)等等。

TDD(測試驅動開發)是否已死? - 編程

十多年的敏捷運動讓很多人產生了誤解,以為敏捷開發就是要 XP、TDD,你們不 TDD 就不敏捷了,這是不對的,是成功的洗頭。大家可以去查早期的敏捷文獻,當時有多個敏捷流派,主流聲音是 Just Enough,也就是敏捷的程序設計要做到剛剛好,既不要太多也不要太少。至於什麼是「剛剛好」,不同的行業、不同的產品、不同的團隊定義是不同的。

還是先從底層小類開始開發?還是有其他的步驟?

合理、成熟的做法不是每次都從底層小類開始開發的,而是從實現一個功能的關鍵類和關鍵方法開始開發。「底層」、「小類」不是重點,重點是「關鍵類」,或用 UP 術語叫 architectural significant(架構級的)。這些架構級的、關鍵類可能是底層類,也可能是高層類;可能是小類,也可能是大類。「關鍵」的解釋是:important、key 或 critical 等等。


這是不可能的。程序那麼複雜,總是會寫到一半突然發現之前的設計不合理。所以總是應該從可以執行的需求分析開始寫,一邊完成介面,一邊完成實現。等到最後全都做完了,再出設計文檔。


不同項目、不同團隊不一樣,但是設計階段絕對不可能跳過去,是整個開發中最重要的一環。把類圖和調用關係全畫好也不好,因為很多都是拍腦袋想的,並不是按照合適的方法劃分模塊,只是湊了一堆類而已。

我習慣的設計方式首先是講整個問題概括出來,它可以拆成多少個子問題,每個問題的輸入和輸出是什麼,這是非常重要的第一步。一般來說,不要一次性拆得太細,對同一個功能,最好拆分出兩三個子問題就好,每一個子問題會對應一個頂層模塊,如果拆得太細可能導致調用關係過於複雜,難以改進;進一步每個子問題可以遵循相同的方法進行拆分,一層一層拆下去,直到變成最簡單的邏輯。採用分層的設計,子層邏輯的變動不會嚴重影響頂層邏輯,頂層邏輯的變動不會嚴重影響子層邏輯,以後調整起來會比較方便。

比如說我們現在要設計一個搶月餅的系統,它可以簡略分成這樣幾個功能:

1. 提示用戶操作方法

2. 搶

3. 展示搶的結果

那麼首先我們需要有一個資料庫來存儲狀態變動,可以將系統分成邏輯部分和存儲部分兩塊,存儲的話就MySQL資料庫應該夠用了,搶的過程可以用TRANSACT來保證事務性,所以拆開成A:業務邏輯,B:數據邏輯兩部分,中間的介面大致是:

1. A調用B:查詢

2. A調用B:搶

B可以劃分成資料庫適配層和MySQL兩部分。

再說A,我們需要用戶從瀏覽器里搶,所以可以採用前後端分離的方式將A分成A1(瀏覽器端)和A2(伺服器端),中間的介面大致是:

1. A1調用A2:查詢是否可以搶

2. A1調用A2:搶

3. A1調用A2:查詢搶的結果

對A2來說,查詢是否可以搶一般根據設置裡面的系統時間就可以了,搶和查詢都是直接調用後端,沒什麼難度,這樣A2的設計基本結束了

對A1,主要的邏輯是:

1. 開始前,展示提示頁面;

2. 能搶,顯示搶的form

3. 提交form,轉到搶的結果

4. 結束後,顯示搶的結果

根據A1的邏輯,我們可以將A1調用A2的查詢是否可以搶,修正成查詢搶的狀態:開始前,過程中,開始後。這樣的變更在一開始設計不充分的階段也是常見的。

對於搶的界面,我們需要前後端配合提供驗證碼和CSRF校驗,防止有人用腳本搶然後被開除,所以接下來我們要添加一個驗證碼和校驗子模塊,從位置上可以是和A並列,也可以是A的子模塊,我們假設簡單一些是A的子模塊A3,那麼:

1. A1調用A3:生成CSRF信息,返回CSRF字元串,同時將CSRF存進Session中

2. A1調用A3:生成驗證碼,返回圖片,同時將正確答案存進Session中

3. A1提交給A2的表單中,附帶CSRF和驗證碼輸入結果

4. A2調用A3:檢查CSRF和驗證碼是否與Session中的數據一致

這樣我們差不多把複雜的邏輯都拆分出來變成子模塊了,畫出類圖問題也不大,即使不畫,按這個介面設計去做,也不會出大問題了。


做項目不知道,做產品往往拼的是執行力,圖畫的再好,不能很快出東西也沒用,不畫圖直接上,問題不大,手中無圖,心中有圖,有IDE,代碼即使是圖。實際還是有圖?


不需要太詳細,當前層級的「技術業務」邏輯架構即可。


要善用各種畫圖工具啊少年

類圖自動生成visual studio和Intellij(付費版)自帶

第三方類圖生成有graphviz

快速畫各種UML有PlantUML

有了這些還愁類圖不能和代碼同步更新?


一般一個需求,基本都是有

需求評審,概要設計,設計評審,自測用例。

然後什麼類圖流程圖時序圖活動圖都得上。

別問為什麽,這是規定。

___________

雖然很痛苦,但是幫後邊給你擦屁股的人很大忙。


文檔是個依靠也是累贅。按要求來,沒有要求就得自己摸索經驗了。


本人是創業者、產品創始人兼半桶水的「產品經理」、「交互設計師」,我來說說:

你給你家蓋房子,你是不是要自己畫圖?

答:在沒有其它資料可供模仿照抄情況下,絕對需要!

精確到什麼程度,視乎你職責和心態.

因為我是創始人,我對我自己的要求是——「能安心去睡覺」

圖紙沒畫好,就開始先打地基或者先找來要用的工具?就先去採購原材料?

答:傻

———————————————————————

土豪另當別論


我的看法,類圖活動圖啥的也就算了

詳細設計是肯定要的,流程圖時序圖也是要的

但是沒必要精確到類圖這個級別


推薦閱讀:

從接觸編程到工作,你們對編程的認識是一個怎樣的變化過程?
為什麼C語言的Hello,world都是用printf輸出而不是puts?
C#與VC++在桌面軟體的開發比較?
一行 JS (以分號結束)能實現什麼喪心病狂的功能?
Matlab求一個矩陣中所有元素的平方和,兩種循環寫法為什麼性能相差很大?

TAG:軟體開發 | 編程 | 敏捷開發 | UML建模 | 測試驅動 |