越做越複雜的軟體工程專案

dimple11發表於2017-12-11

你的APP就像個洋蔥:為什麼軟體開發專案一路失控

你最開始想得很好。僱傭開發人員來構建出你的創業想法。但是幾乎每一週,都感覺似乎專案需要做做調整,於是各種功能開始混進來,範圍逐漸蔓延。

彷彿這專案擁有了自己的生命,而且還試圖毀掉你的生活。

越做越複雜的軟體工程專案

怎麼會這樣呢?你僱傭的開發人員很差勁嗎?你對專案管理也只是摸著石頭過河嗎?還是這個想法從頭到尾就是糟糕的?

有可能。但一個核心誤區通常會在一開始註定專案的失敗。

我們的假設是,給產品定義一系列的功能並記在紙上後,雖然偶然有時候要新增功能,有時候要去除功能,但是你一眼就能看出專案的範圍大小。

這個假設是錯誤的。

你的專案不像一張紙一樣是二維的,它還有深度。

軟體的每個功能都可以被一層一層剝開。事實上,如果我想當標題黨的話,我會說你的app就是個洋蔥。我來講一下我的意思,來告訴你為什麼當你把自己的 app 一層層剝開時,它會讓你淚流滿面。

終結所有圖書館的圖書館。

我們們通過具體的例項來看吧,給你推薦一個我的想法。

人們經常會想要附近圖書館沒有的書,而在這附件其它的人可能會有。因此,這款 app 可以讓人們傳送用書請求,然後有這本書的人會響應。我們從每一次這樣的交易中獲利。

太有才了。

這我知道,好吧?軟體的功能直截了當 :

越做越複雜的軟體工程專案

現在該把規格說明書交給開發人員,並且給軟體想個精彩的名字了。叫 kaBooki?lib.rari.ly?reddit?

好吧,稍等一下,我們仔細來看看。而且已經有軟體叫reddit了。

我們帶著問題探究一下你的想法,看看會發現什麼。

使用者彼此之間如何付款呢?見面的時候付現金還是在 app 上付款呢?

哦,他們應該在app上用信用卡支付,這樣我們能夠獲得提成。

他們實際上怎麼傳送用書請求呢?我的意思是,他們到底在 app 上要怎麼操作呢?要填寫一個包含了書名和作者的開放式表格嗎?

噢,嗯。他們應該對書進行檢索並且選擇一本想要的。

好,所以我們需要建個書的資料庫。

我猜是要這樣。

實際上,什麼是用書請求呢?拿著書並且準備把書賣出去的人能看到請求的書單嗎?還是說我們要向這些要賣書的人傳送通知,像 Uber 或 Thumbtack 那樣?

是那樣,我們將用書請求發給持有書的人。

所以,賣書者需要往 app 中填充所有在售書籍的資訊嗎?

呃,是的。

怎麼進行書的交接呢?使用者自己送書,還是我們處理配送問題?

我們處理配送問題。

所以你需要一個系統來告訴你要拿什麼書,以及書應送往的地方。我猜你的司機想知道最短的送書路線,對吧?

好吧,這樣不可行。那讓使用者彼此之間寄書怎麼樣呢?

所以我們要將收書人的地址給發書的人?怎麼處理運費問題呢?

實際上,你知道的,這些使用者需要捱得比較近,這樣他們就可以直接過去拿書了,還能交個新朋友,對吧?

所以我們需要把捱得近的使用者匹配起來。他們怎麼找對方呢?App 有沒有實時地圖好讓他們安排見面呢?

好,行,就這樣吧。

我們要給書定價嗎?還是他們自己商量價格?

他們自己談個明白,給書定好一個價格。

他們怎麼做決定?我們是不是需要在 app 裡建個交流平臺呢?

他們彼此只需要用電話談就行了。

好吧,所以我們是不是要用 SMS (Short Messaging Service 簡訊服務)簡訊來確認號碼呢?還是……你懂我的意思了,我們真的可以永遠無休無止地進行下去。

請別這樣。

我們來看一下現在功能清單是什麼樣的:

越做越複雜的軟體工程專案

每一條專案的功能都可以進行多次擴充套件,我們只把洋蔥撥開了一層,就已經成這樣了。

越做越複雜的軟體工程專案

現在啊,現在可別哭。

發生了什麼呢?

我們要清楚哪些東西不是導致功能激增的原因。

這不是我們通常所知的功能蔓延。

功能蔓延是指產品中不斷增添新的功能,而如果你看一眼我們最終列的功能清單,裡面每一條都支援最初的功能設定。

這無關乎科技因素。

比如說,聊天系統最適宜的結構是怎樣的呢?什麼支付平臺是最容易整合的呢?

我們在這兒不討論那些。一個好的開發人員可以通過各式各樣的技術手段與你溝通,但是不能替你決定軟體需要具備什麼功能。

這也無關乎技術考量。

人們想使用這樣的產品嗎?當其他使用者還很少時,有什麼因素會誘使早期的使用者來登陸軟體呢?使用者願意為這項服務付費嗎?

這些問題與想法的落實、產品市場匹配度的確認、定價的策略等息息相關。再重申一次,這些項都是非常重要的,但卻不是軟體功能清單中內容多到炸的原因。

當然這也與全球變暖或者牙仙沒有絲毫關係,你要告訴我變成專案變成洋蔥的原因嗎?或者說看完覺得每個其實都並沒什麼理由?

噢,你這樣很無聊,事實是這樣:

我們基本上對複雜性是怎麼凸顯的存在誤解。

我們以為每個功能的複雜程度就像我們開始描述的那樣。嘿,也許程式設計師寫程式碼要花費時間,或者隨便程式設計師做什麼,但是商業用語區區幾個詞就可以完全描述軟體的功能,像“使用者通過 y 使用 x”,對吧?

這種觀點是錯的。

軟體功能更像是分形。

你離得越近去看,細節就會展現得越明顯。

越做越複雜的軟體工程專案

洋蔥是分形?

不是,我已經換了比喻。我們們繼續。

我們從全域性視角來開始描述軟體的功能。但是,當構建好 app,或是使用 app 時,是處在一個較小規模下的。它的完成一步一步進行的,每一個步驟都有可能遇到問題。為了解決問題,你可能需要重新設計這一步、新增新步驟、或是增添全新功能。

這就像是規劃一條從你家到單位的行程。看地圖的話,行程好像是直的。

越做越複雜的軟體工程專案

當你開始從更小的視角來看,你會發現直的路線並不會城市道路網相契合。你會遇到交通站、高坡和道路阻塞。根據步行、騎行或者開車的不同,你的行程路線也會不同。

建立軟體很大程度上是一樣的,你離得越近去看,對解決方案就能有越細緻的認識。

這下好了,一路到處都充斥著細節,還都是我需要考慮的。這是否意味著我的產品永遠也不可能做完呢?

這麼想也對也不對,之所以複雜性凸顯,是因為我們一開始就巨集觀描述了軟體功能,也通常就是要實現的目標。然後我們將細節放大,為實現這一目標而一步步建立解決方案。細節放得越大,就會發現越多複雜的問題。

但複雜性並不是問題所在,問題是我們如何來發現複雜性的。我們把軟體功能規格書叫個開發人員,幾周過後,我們拿到了第一版的 app 並開始測試。這是我們第一次一步一步操作軟體,會從中發現大量漏洞。然後我們做好修訂說明,把它交給開發者,讓他們再開發第二版 app。

越做越複雜的軟體工程專案

在整個流程的最後一步,我們在多次進行之後,得到了很好的解決方案。

問題是開發週期真的太長了,每一環節都要耗費好幾周或好幾個月。

但是發現 app 的潛在複雜性又是必要之舉。

通過來回反覆和開發人員交涉來發現這種複雜性,既耗時又燒錢。

我們想這樣做:

越做越複雜的軟體工程專案

我們想在開始寫程式碼之前就儘可能多得發現它的複雜性,將軟體層層剝開來,看到一個更加健壯的功能清單,而且想做得又快又省錢。

我們想在軟體規格書上來回修改,而不是在app上反覆折騰。

我們想從這個過程:

越做越複雜的軟體工程專案

 

走到這個過程:

越做越複雜的軟體工程專案

我們需要兩個東西來行之有效地實現這個過程:第一,我們需要一種方式來展示功能清單,以便反覆修改;第二,我們需要一種方式來高效地就功能清單進行稽核協商。

我們來看看怎麼做。

規劃功能

我們不想以商業用語來談,而是像使用者一樣的身份來考慮軟體功能。在這個層面就需要處理軟體的複雜性問題了。

首先,列一張使用者目標表。你想讓使用者通過你的 app 獲得什麼呢?

接下來,你需要規劃使用者流程,以使用者的身份走每一步,來實現使用者目標,並記錄這些步驟。

我們建立一張使用者使用 app 的流程圖。

有很多種做的方式,你僅需為每一步勾勒一個簡單的略圖即可。你可以為使用者走過的每一個介面繪製模型,也可以在紙上或軟體上畫流程圖。

越做越複雜的軟體工程專案

無論你選擇哪種方式,確保優先考慮速度問題。除非你是 Photoshop 專家,否則把軟體收起來,拿紙和筆畫吧。

確保每個介面在你的軟體略圖中都能夠得以體現。比如說,如果一個特定的步驟會經過 app 的好幾個介面,那麼把該步驟切分開。我們想要梳理出更多的細節,而不是更少的。

這個單獨的過程應該將 app 中一些複雜的問題平面化。現在,我們要往更深處挖。

對一切保持疑問

我們要是像之前那樣提問的話,範圍太寬泛了,無從下手。

首先我們將適用於大部分軟體的一些常見問題列到一起,這些問題可以歸為四個大類,你可以把它當做框架來組織軟體略圖。

看著軟體略圖的每一步,問你自己清單上寫的每一個問題。如果答案會展現出一個新的步驟,那就把它新增進軟體略圖。

清單在這兒:

使用者輸入

這些問題與使用者提交到產品的資訊有關

  • 使用者會輸入什麼資訊?
  • 輸入的是資訊是開放式的還是互動式的?
  • 開放式資訊範例:輸入自由格式文字,上傳圖片,錄製視訊。
  • 互動舉例:往搜尋框輸入文字來顯示可選結果、在地圖上選取地址、選擇那些預定義選項。
  • 是否有些輸入應該被當做無效呢?App 又該如何處理呢?
  • 是否有無源輸入呢?最常見的例子:通過 GPS 進行使用者定位。
  • 產品需要獲取新使用者 (https://www.useronboard.com/)的什麼資訊?使用者之後可以對資訊進行修改嗎?
呈現給使用者的資訊

如果之前的部分是輸入,你可以把這個當成輸出。

  • 螢幕上哪些資訊是呈現給使用者的?
  • 這些資訊是以怎樣的形式呈現的?比如:文字、圖片、地圖、清單、圖表。
  • 這些資訊需要以某種方式進行分類嗎?比如:最近使用頻率、距上次使用時間、關聯性。
  • 產品是不是可以主動對外通訊?比如:郵件、推送通知、SMS 訊息。
各部分之間的互動

這些問題有關軟體體驗的不同部分(使用者、產品、其他服務)之前是如何互動的。

  • 使用者彼此之間有互動嗎?比如:收發郵件、加好友、 “喜歡”、或者給其它使用者的內容打標籤
  • 使用者與外部服務有互動嗎?比如:付費服務、物流跟蹤、社交登陸。
  • 產品與外部服務有互動嗎?比如:位置查詢服務、天氣 API、社交網路(“你的朋友X剛加入了!看看他們的簡介!”)
企業家功能

有關你——企業家,需要從產品中獲得什麼。

  • 你需要通過郵件或其他媒介接收提醒或摘要嗎?
  • 需要為你自己或員工提供專門的系統嗎?比如:為配送人員提供導航軟體,為廚房員工提供實時點餐管理介面。
  • 你需要手動批准使用者/內容的介面嗎?
  • 你需要一個內容稽核系統嗎?它可以讓管理員輕鬆地進行使用者內容移除和使用者賬戶失效的操作。

簡直有……數不清的問題。

這就對了!這也真的就是人們在早期開發過程常常忘記的東西。你的產品還有很多特定的問題,隨著時間你就會慢慢發現。

把它整合到一起

建立軟體略圖和進行軟體稽核的過程可以讓你知道少了什麼東西,這個過程重複幾次之後,你就能更自信得拿出一個 非常可靠的功能表 了。

你知道,我真的很希望通過這種好像挺奇怪的訣竅,可以使專案得到修繕。聽上去工作量還蠻大的。

的確。但這是你在過程中的某些點上,無論如何都必須要做的工作。

記住我們為什麼要這樣做。你無論如何都要找到軟體功能所潛藏的複雜性因素,你要做的就是選擇何時來將洋蔥層層剝開。

基本上來說,有兩種選擇:

  1. 根據使用者找準開發目標,對此建立模型或者流程圖,對自己的假想保持疑問態度,並且像我們上面所做的那樣將軟體層層剝開。或者,
  2. 讓開發人員直接開始開發軟體,然後根據每一版暴露的問題一次次改版,每改版一次就要花一週時間。幾個月後,你通過改版會發現很多問題,而這些問題和你本在一週內用紙筆就可以搞定的問題一模一樣。

所以這讓軟體專案變得複雜到爆,恨不得能一下子將你生吞活剝。

所以,去發掘功能吧,建立軟體略圖,對自己的假想保持疑問態度,以既迅速又省錢的方式發現軟體存在的主要問題。

讓自己從壓力和痛苦中解脫出來,放手讓產品走向外面的世界,讓它恣意綻放。

難道洋蔥也會開花綻放嗎?你的隱喻太蠢了。

越做越複雜的軟體工程專案

噢說得好。

如果你覺得這篇文章挺有用,可以幫我分享它!也可以訂閱我的郵件,確保不錯過我的下一篇文章。

相關文章