“洋蔥”式App開發(fā):為什么你的軟件項目越來越冗雜?
編者按:開發(fā)項目的初衷很美好,功能需求你都理得特別清晰??蔀槭裁丛趯嶋H開發(fā)過程中,你的軟件項目總是需要更改和調(diào)整?最終,添加的功能越來越多......要知道,看上去很理所當(dāng)然的功能列表,實際做下去之后你就會發(fā)現(xiàn)事情沒那么簡單。本文編譯自Medium上原題為《Your app is an onion: Why software projects spiral out of control》的文章。
最開始,你的想法很美好。你會雇傭一個開發(fā)者來實現(xiàn)自己的創(chuàng)業(yè)點子。但幾乎每一周,項目似乎都需要進(jìn)行調(diào)整。各種功能開始涌入,范圍越鋪越大。
就好像項目被賦予了生命,而它正在試圖毀掉你的生活。
這一切究竟是怎么發(fā)生的?你雇傭的開發(fā)者不靠譜嗎?還是你沒能做好項目管理?抑或是創(chuàng)意自始至終就很糟糕嗎?
這都有可能。但是有一個核心誤區(qū)通常在一開始就注定了項目最終會失敗。
我們假設(shè)自己的項目是由功能組合定義而成的,我們會將這些功能記在紙上。偶爾再添加一些功能,偶爾又會減掉一些。但你仍然能一眼看到項目的范圍。
但是,這種假設(shè)是錯誤的。
你的項目并非存在于二維空間里,它不是一張紙。它有自己的深度。
軟件的每一個功能都可以被一層一層得剝開。事實上,如果我傾向于做標(biāo)題黨的話,那我會直截了當(dāng)?shù)帽硎灸愕膽?yīng)用就是個洋蔥。讓我來解釋下這到底是什么意思吧。我會告訴你,為什么你在將自己的應(yīng)用一層一層剝下時,它會讓你流淚不止。
終結(jié)所有圖書館的圖書館
我們來聊點具體的例子吧。給我推薦一個想法吧。
人們通常想看的書,附近的圖書館都沒有。但其他地區(qū)的人可能會有。因此,這款應(yīng)用可以讓人們發(fā)送圖書需求,而有這本書的人則會作出響應(yīng)。每一筆交易,我們都會進(jìn)行抽成。
這個想法,很有才吧!
我知道,難道不是嗎?功能列表非常簡潔明了:
現(xiàn)在是時候把產(chǎn)品說明書發(fā)給開發(fā)者,然后開始給公司考慮一個炫酷的名字了。kaBooki?lib.rari.ly?還是reddit?
欸?別急阿。讓我們再稍微深思一下吧。更何況,已經(jīng)有一個軟件叫reddit了。
讓我們帶著下述這些問題來細(xì)究一下你的想法,看看想法最后究竟會發(fā)展成什么樣子吧。
用戶如何交易呢?他們是見面的時候一手交錢、一手交貨還是說通過應(yīng)用來付款呢?
恩,他們應(yīng)該在應(yīng)用上利用信用卡進(jìn)行付款,這樣我們才能抽成啊。
他們該如何發(fā)送圖書需求呢?我的意思是,他們在應(yīng)用上究竟要做些什么呢?是填寫一個包含書名和作者信息的開放式表格嗎?
哦......他們應(yīng)該在應(yīng)用上搜索圖書,然后挑選自己感興趣的。
好的,那么我們就需要建立一個圖書數(shù)據(jù)庫了。
我想應(yīng)該是這樣。
那實際上,究竟什么是圖書需求呢?賣書的人能夠看到所有的書籍需求列表嗎?還是說我們需要像Uber或是Thumbtack那樣發(fā)送通知告知這些賣書的人嗎?
是的,我們需要給那些有書的人發(fā)送需求通知。
那么,賣書的人需要在軟件里填寫自己要賣的書目信息嗎?
恩,是的。
那么書該如何完成交接呢?是用戶自行交接,還是我們幫忙處理配送問題呢?
我們負(fù)責(zé)配送。
那你需要一個系統(tǒng)告訴你哪些書需要取貨,然后要送往哪里。我想你的司機應(yīng)該會想知道最短路線怎么走吧,對嗎?
好吧,這樣可不行。那不如這樣吧?讓用戶相互之間郵寄圖書。
那么,我們就這樣將收貨人的地址信息告知發(fā)貨人?那我們?nèi)绾谓鉀Q運費問題呢?
實際上,你知道的。這些用戶都需要靠得近一些。他們可以上門取貨,順便還能認(rèn)識個新朋友,這樣不好嗎?
所以,我們需要匹配距離相隔較近的用戶。那他們?nèi)绾握业綄Ψ侥?應(yīng)用是否還需要內(nèi)嵌一個實時地圖,這樣才能安排見面呢?
好吧,這樣也行。就這么做吧。
我們需要設(shè)定圖書的價格嗎?還是說買賣雙方自行商定?
他們自己商定吧,然后確定一個價格。
他們?nèi)绾未_定呢?我們是否要在應(yīng)用里嵌入一個聊天功能?
他們可以直接打電話進(jìn)行聯(lián)系啊。
好吧,那我們是否要發(fā)送短信來確認(rèn)號碼的有效性呢?如果......好了,說到這兒你就應(yīng)該懂我的意思了。我們還可以這樣無休止得談下去。
別,別再就此問題繼續(xù)聊下去了。
那不妨現(xiàn)在再來看看功能列表長什么樣吧。
每一行列出來的內(nèi)容都可以多次進(jìn)行延伸。我們只不過剛剛把洋蔥剝開了一層皮,結(jié)果就已經(jīng)變成這樣了。
現(xiàn)在,你可不要哭啊。
到底發(fā)生了什么呢?
我們要弄清楚哪些原因不會導(dǎo)致功能爆炸。
這也并非是我們常說的功能蔓延。
功能蔓延指的是產(chǎn)品不斷添加新的功能。如果你看一下我們最終的功能列表,你會發(fā)現(xiàn)每一條功能的存在都符合最初的想法設(shè)定。
而這也無關(guān)乎任何技術(shù)考量。
舉個例子,什么是最適合的聊天系統(tǒng)架構(gòu)呢?最容易整合的支付平臺是什么呢?
我們在這兒不會就這個問題多加贅述。一個優(yōu)秀的開發(fā)人員會把各式各樣的技術(shù)方案都告知給你。但是他無法幫你決定軟件需要什么功能。
這也無關(guān)什么市場考量。
人們需要這樣一個產(chǎn)品嗎?在用戶數(shù)量很少的情況下,你該如何誘使早期用戶報名呢?用戶愿意為此項服務(wù)付費嗎?
這類問題必須要和想法的驗證、產(chǎn)品市場組合的確定以及定價策略息息相關(guān)。再重申一下,這些問題都非常重要。不過,這也并非是功能列表爆炸的原因。
這與全球變暖或是牙仙也沒有任何聯(lián)系。你是打算告訴我項目變成洋蔥的原因嗎?還是說你打算告訴我每一條非原因項嗎?
你可真無趣。事情其實是這樣的。
我們從根本意義上就曲解了復(fù)雜性的運作原理。
我們原本以為每一項功能的復(fù)雜程度就和我們一開始描述得一樣。嘿,也許程序員是要花些功夫去寫代碼的,但是用商業(yè)術(shù)語中的幾個詞,你就可以輕松描述出產(chǎn)品的功能。比如說“用戶用Y來做X這件事”。不是嗎?
可這種觀點是錯誤的。
軟件功能更像是分形
你離得越近去看,它們就能呈現(xiàn)出更多的細(xì)節(jié)。
洋蔥是分形嗎?
不,我只是換了個隱喻而已。繼續(xù)說吧。
關(guān)于功能,我們一開始是基于一個大的藍(lán)圖去進(jìn)行描述的。但是,當(dāng)開發(fā)人員在開發(fā)這款應(yīng)用時候,抑或是用戶或你本人使用這款應(yīng)用時,其實它是在一個較小的規(guī)模下進(jìn)行的。它是一步一步在軟件內(nèi)完成的。每一個步驟,你都會遇到一些問題。為了解決這些問題,你需要重新規(guī)劃這一步驟、添加新的步驟或是添加全新的功能。
這就像是規(guī)劃一條從你家到辦公室的路線??粗貓D,這段行程似乎就是兩點連起來的一條直線。
但當(dāng)你以更小的比例去看這條路線時,你會發(fā)現(xiàn)自己原先規(guī)劃的那條直線并不符合城市道路網(wǎng)。你會遇到交通站、高地或者道路阻塞。基于你是步行、騎車還是駕車,你可能需要規(guī)劃一條不同的路線。
開發(fā)軟件也與之類似。當(dāng)你離得越近去看,你就可以更為詳細(xì)地意識到你的解決方案是什么樣子的。
那可真是太棒了,一路上都是各種細(xì)節(jié),這還都是我需要去考慮的。這是不是意味著我的產(chǎn)品永遠(yuǎn)都完不成了?
是也不是。之所以會顯得復(fù)雜,原因在于我們在一開始對功能進(jìn)行了描述,這通常是要實現(xiàn)的目標(biāo)。之后,我們就會將其放大處理,一步步設(shè)計解決方案來實現(xiàn)目標(biāo)。當(dāng)我們將細(xì)節(jié)放大,我們就會發(fā)現(xiàn)事情變得愈加復(fù)雜了。
復(fù)雜本身不是問題。問題是我們選擇發(fā)現(xiàn)復(fù)雜性的方式。我們將功能的規(guī)格說明書遞交給開發(fā)人員。幾周之后,我們會拿到應(yīng)用的初始版本并且進(jìn)行測試。這是我們第一次一步一步操作整個軟件,然后我們就發(fā)現(xiàn)很多的漏洞。我們會將修改意見記錄下來,然后將其發(fā)送給開發(fā)人員,讓他開發(fā)第二版應(yīng)用。
在整個過程的最后,經(jīng)過反復(fù)幾次的修改調(diào)整,我們得到了一個較好的解決方案。問題在于,開發(fā)周期實在是太長了。每一個環(huán)節(jié)都需要數(shù)周或數(shù)月時間來完成,
但是,要發(fā)現(xiàn)應(yīng)用存在的內(nèi)部復(fù)雜性,這又是必要之舉。
反反復(fù)復(fù)和開發(fā)人員進(jìn)行溝通來發(fā)現(xiàn)這種復(fù)雜性,耗時還燒錢。
我們希望這樣做:
我們想要在寫代碼之前就能盡可能多得發(fā)現(xiàn)這種復(fù)雜性。我們想要剝下“洋蔥”的皮來發(fā)現(xiàn)一個更可靠的功能清單,最好能以一種快速且便宜的方式。
我們并不想來回修改應(yīng)用,而是想要反復(fù)修改軟件規(guī)格書。
我們想要從這個流程:
變?yōu)檫@個流程:
為了高效做到這一點,我們需要兩個東西。首先,我們需要一種方式來呈現(xiàn)功能列表,以便之后反復(fù)修改調(diào)整。第二,我們需要一種高效的方式來審視這份功能列表。
我們來聊聊該如何實現(xiàn)這兩點吧。
規(guī)劃功能
我們不必再用商業(yè)術(shù)語來考慮這一點,而是要把自己當(dāng)做是一個用戶去思考功能需求。在這個層面上,我們就需要應(yīng)對軟件復(fù)雜性問題了。
首先,列出用戶目標(biāo)。用戶使用你的app要做什么呢?
接下來,你需要規(guī)劃用戶流程。以用戶的角色確認(rèn)實現(xiàn)目標(biāo)所需要的每一個步驟,記錄下這些內(nèi)容。
我們要建立一張用戶使用應(yīng)用的流程圖。
有很多種方式可以實現(xiàn)這一點。你可以簡單做一個所需步驟的略圖。你可以針對用戶看到的每一個界面進(jìn)行版面設(shè)計。你還可以在紙上或是用軟件畫出流程圖。
不管你選擇哪種方式,確保優(yōu)先考慮速度問題。除非你是Photoshop領(lǐng)域的專家,否則還是放棄使用軟件,拿起紙筆來干活吧。
確保略圖中能呈現(xiàn)出每一個界面。舉個例子,如果一個特定的步驟需要在屏幕上以多個界面呈現(xiàn)出來,那你就需要將該步驟分開。我們希望能梳理出更多的細(xì)節(jié)。
此過程應(yīng)該能揭示出應(yīng)用中存在的一些復(fù)雜性問題了。
現(xiàn)在,我們要開始從更深層面來挖掘了。
對一切事情保持疑問
像我們之前問的那些問題未免太過寬泛了。這很難找到切入點。
首先,我列出了一些適用于大多數(shù)軟件的常見問題。這些問題會被分為四大類,你可以將其當(dāng)做是模板來提問自己的軟件略圖。
仔細(xì)觀察略圖中的每一個步驟,拿列表上的每一個問題問問自己。如果答案呈現(xiàn)出了新的步驟,就將其添加在你的軟件略圖里。
用戶輸入:
這些問題是用戶在輸入信息到產(chǎn)品中時候會碰到的。
- 用戶會輸入什么樣的信息?
- 輸入的是信息是開放式的還是交互式的?
- 開放式信息舉例:輸入自由格式文本內(nèi)容、選擇圖片進(jìn)行上傳或錄制視頻。
- 交互舉例:往搜索框輸入文本來顯示可選結(jié)果、在地圖上選擇地址、從預(yù)定義選項組合中進(jìn)行選擇。
- 是否有些輸入的信息應(yīng)該被當(dāng)做是無效的呢?應(yīng)用又將如何處理呢?
- 是否有無源輸入呢?最常見的例子:通過GPS 進(jìn)行用戶定位。
- 產(chǎn)品需要獲取新用戶 (https://www.useronboard.com/)的什么信息呢?用戶后續(xù)可以對信息進(jìn)行修改嗎?
向用戶呈現(xiàn)的信息
如果之前那部分算作是信息輸入,那么這部分應(yīng)當(dāng)是信息輸出。
- 屏幕上哪些信息會被呈現(xiàn)給用戶?
- 信息是以何種方式呈現(xiàn)的?比如說:文本、圖片、地圖、列表或圖表。
- 這些信息需要以某種形式進(jìn)行篩選嗎?比如說:距上次使用時間、用戶距離、相關(guān)性等。
- 產(chǎn)品是否可以主動和外界進(jìn)行交流?比如說:郵件、推送通知、短信。
各部分之間的交互
這部分問題是關(guān)于軟件體驗中各個部分之間的交互。
- 用戶會彼此之間進(jìn)行交互嗎?比如說:短信、添加好友、點贊或是給其他用戶內(nèi)容加標(biāo)簽。
- 用戶是否會和外界服務(wù)發(fā)生交互呢?比如說:付費服務(wù)、物流追蹤、社交媒體賬戶登錄。
- 產(chǎn)品是否會和外界服務(wù)發(fā)生交互呢?比如說:位置查找服務(wù)、天氣應(yīng)用程序接口、社交網(wǎng)絡(luò)(“你的朋友XXX剛剛加入了!查看他們的信息!”)
企業(yè)家功能
這部分問題是關(guān)于企業(yè)家對于產(chǎn)品的需求。
- 你需要通過郵件或其他媒介發(fā)送提醒或介紹嗎?
- 你需要為自己或員工提供專門的系統(tǒng)嗎?比如:為配送人員提供導(dǎo)航軟件,為廚房員工提供實時點餐管理接口。
- 你需要手動批準(zhǔn)用戶/內(nèi)容的接口嗎?
- 你需要一個內(nèi)容管理系統(tǒng)嗎?它可以讓管理員輕松撤除內(nèi)容或讓用戶賬戶失效。
還有很多很多的問題。
這就對了!這其實也是人們通常在開發(fā)應(yīng)用早期會遺忘的一些問題。針對你的產(chǎn)品,還會衍生出更多的問題,你需要慢慢發(fā)現(xiàn)。
總結(jié)
建立軟件略圖和審核軟件的過程會告訴你——你漏掉了哪些內(nèi)容。重復(fù)幾次這一流程,之后你就可以更加自信地提供一份可靠的功能清單了。
你知道,我真的希望你有什么妙招能夠修繕我的項目??蛇@聽上去工作量好像很大的樣子。
事實也確實如此。但是這是你在軟件開發(fā)過程中必須要做的事情,不論在什么階段。
記住我們之所以要這樣做的原因。無論如何,你都需要發(fā)現(xiàn)軟件功能中隱藏的復(fù)雜性問題。你所要做的僅僅是選擇何時剝洋蔥。
從本質(zhì)上來說,你有兩個選擇:
- 你可以發(fā)現(xiàn)用戶目標(biāo)、構(gòu)建版圖設(shè)計或流程圖、質(zhì)疑自己的假設(shè),然后像我們說得那樣將軟件一層一層剝開?;蛘哒f,
- 你可以讓開發(fā)人員直接開始開發(fā)應(yīng)用,然后根據(jù)開發(fā)的每一個版本暴露的問題進(jìn)行修改,一周一次。在幾個月之后,你就會發(fā)現(xiàn)這些問題,你本可以在一周之內(nèi)就用紙筆想明白的。
這也是為什么軟件項目常常會變得非常復(fù)雜,恨不得將你生吞活剝掉一般。
那么,趕快去發(fā)現(xiàn)自己所需要的功能吧。構(gòu)建版圖設(shè)計然后質(zhì)疑自己的假設(shè),用一種快速且省錢的方式發(fā)現(xiàn)大量的問題。
此舉可以將你從壓力和痛苦中拯救出來,幫助你將產(chǎn)品推向全世界,讓它如繁花一般恣意盛開。
洋蔥會盛開嗎?你這比喻可真糟糕。