軟件行業(yè),苦樂自知
今年是我從事軟件開發(fā)的第17個年頭。從非科班出生的業(yè)余計算機愛好者,到成為走過無數(shù)彎路的老碼農,或者偶爾也被人稱為架構師?;仡櫸页蔀榧軜嫀煹牡缆?,可能要追溯到最初的工作階段,干過碼農、做過美工、當過項目經(jīng)理,這些經(jīng)歷讓我幸運地在實踐中體會了從醞釀誕生到后期維護的整個階段,然而當時苦于沒有經(jīng)過系統(tǒng)的訓練和學習,對整個軟件工程和架構的認知是懵懂的。十余年前,我參加并通過了系統(tǒng)分析員的考試(當年軟件架構師認證還沒有從系統(tǒng)分析師中分離出來),然后又陸續(xù)作為“架構師”被某些大公司聘用(然而自認其實還不夠格),逐漸地,在一些大型項目的歷練和個人業(yè)余作品的開發(fā)種,才彌補了我技術上的短板。
回首十余年軟件從業(yè)的道路,從開發(fā)到項目經(jīng)理再到部門管理,然后回歸開發(fā),到最后成為架構師,期間的坎坷真實苦樂自知。而讓我能在這個行業(yè)一直堅持下來,并且不斷適應這個行業(yè)變化的,我認為最大的收獲來自于同事和前輩的指導,其次就是不斷的自我反省和教訓總結。因為走彎路好比交學費,工作就是不斷地在錯誤中前行,必須時刻警惕不要讓自己犯下相同的錯誤—如果一次次掉到同樣的坑里,是很難在這個行業(yè)的研發(fā)崗位上堅持下來的。
為此,我愿意分享我的經(jīng)驗和教訓,或許有緣者能從中體會一二。
如何做好一個架構師
1. 關注用戶行為動機和利益
軟件工程的源頭,在于用戶需求,而用戶需求恰恰是軟件項目中最難的,也是很容易被大家忽視的點。架構師必需從源頭來引導軟件開發(fā)這條河流,不要讓它流到溝里去。
讓我首次明白業(yè)務分析的重要性,是在我工作不久的時候。當時,我負責某省廳檔案系統(tǒng)的項目開發(fā),第一次作為主力程序員,在走訪了幾個業(yè)務員后,很快便開發(fā)出了第一個版本,當時內心還是挺得意的。
開發(fā)完成后我便去給用戶報告,剛見到用戶,還沒來得及把軟件打開給對方看,用戶表示上次談的需求只是一點點,復雜的問題還沒和我說呢,然后張嘴說出一大堆業(yè)務名詞和術語,把我說得云里霧里,感覺好像完成的軟件功能不到實際業(yè)務需求的三分之一。如此往復、修改下來,才粗略了解到用戶業(yè)務的概況。這才發(fā)現(xiàn)實際要開發(fā)一款被用戶接受的軟件,并不如預期得那么容易。
然后真正的磨煉還在后面。當我終于第一次將自認為完整的功能上線拿給用戶試用,得到的是“幾乎沒辦法使用”的評價。用戶一改過去積極配合的態(tài)度,產(chǎn)生了諸多抱怨。比如,多余的輸入框,要求輸入框有記憶功能(就是后來的“自動完成”功能,也就是希望將Excel表格的操作方式搬到軟件上來,當時的Web開發(fā)技術幾乎不能支持)等等,很多需求以當時的技術能力很難實現(xiàn)。
這簡直沒法干了,我?guī)缀跻艞壛?,這個問題最終被上級領導反映給了負責建設這套系統(tǒng)的廳辦公室主任(多年以后,我終于知道,他是“客戶”而不是“用戶”)。在主任安排下,次日我坐在用戶辦公室觀察他的日常工作。原來用戶上午要處理的文書案卷有一百多件,我們的檔案系統(tǒng)不但需要用戶逐個瀏覽所有待填寫字段,還要求用戶將檔案掃描后錄入系統(tǒng)(主任要求的),用戶的工作量不但沒有降低,反而大為增加!
這里有兩個問題。第一、由于數(shù)量原因,錄入效率要求非常高,但在設計開發(fā)中沒有得到重視。第二、系統(tǒng)上線后反而加重工作負擔,用戶有了抗拒心理。但業(yè)務的框架是主任定的,這是用戶“不愿意”說出口的原因。
很多時候用戶訴求猶如冰山,訪談和書面的需求說明上能獲得的只有冰山浮在水面上的部分,大量的潛在訴求隱藏在水面之下,不深入學習用戶業(yè)務細節(jié)是無法真正掌握用戶訴求。在分析用戶需求時,需要關注用戶的動機和出發(fā)點,而這往往是用戶利益息息相關的,我們需要分析清楚這種動機和利益關系。
在知道了原因后問題就好辦了,主任很快就根據(jù)系統(tǒng)上線后的工作負載情況,從另一個工作量大幅減少的崗位上安排人員來負責文檔錄入,同時我們也對軟件交互進行了大幅改進。最后系統(tǒng)再次上線后,整個軟件的實施就變得非常順利了。
多年后,我終于知道分析業(yè)務全貌的工作叫“業(yè)務建?!?,如果說反映冰山浮在水面上的部分是需求,那么“業(yè)務建?!本凸蠢粘稣麄€冰山的全貌。構造業(yè)務模型是架構師的基本功之一,一個好的架構師一定會做“涉眾利益分析”,將產(chǎn)品設計得符合用戶真正的需要。
很多朋友可能認為,用戶需求主要來自用戶(代表)的口述或者訪談意見,其實這是個誤解。在另一個省廳做無紙化辦公的項目時,為了得到這些“隱含”的業(yè)務信息,在征得同意后,采取了以下方法:
觀察關鍵崗位,記錄操作人員的日常行為。
查閱了兩年內所有文書檔案材料(絕密除外)。在文書材料的手跡當中,我們看到了很多不在“明面上”的東西。比如過程中的周期性工作(例如一年才發(fā)生一次),這種用戶在反饋中遺漏的事項。進一步地,我們還看到了矛盾、爭論、政治因素等這些用戶不會說出口的部分。
分析這些業(yè)務數(shù)據(jù),并勾勒出了業(yè)務的全貌后,我發(fā)現(xiàn)來自于直接收集的“明面”需求-包括用戶訪談和需求描述材料中的業(yè)務信息不到20%,大約80%以上的業(yè)務需求來自于各種觀察和材料檢索分析。這是一個稍稍令人吃驚的比例,但足以說明業(yè)務建模工作的重要。
2. 讓軟件真正地“靈活可塑”
上一節(jié)我們講了業(yè)務建模,將業(yè)務模型化,不僅可以把需求做深入,更重要的是業(yè)務模型可以引導我們做出好的軟件設計。
做產(chǎn)品也好,做項目也好,研發(fā)人員厭惡的事情會有很多—比如趕進度、調錯、維護別人的代碼等等。但是,最為深惡痛絕的事情,無疑就是變更需求。只有符合用戶業(yè)務模型的設計,才能在頻繁的需求變更下保持穩(wěn)定。
就如上面提到的無紙化辦公項目中,一樣碰到了需求的復雜變化,以及用戶的業(yè)務多變。
最終,我們丟掉了數(shù)百頁的需求和流程描述;放棄了之前開發(fā)好的所有功能(這些功能曾被反復詬病不夠靈活);放棄了過去那種按局長、處長、科長等分別設置角色進行授權的權限模型—這些頭銜僅僅只是人員的屬性。人員的權限實際上是受任務決定的,這才是真實的業(yè)務模型(若干年后,才知道那叫TBAC權限模型,也就是基于任務的權限模型,早已作為理論被國外軟件科學家提出)。
而基于不變的用戶責任模型,我們抽象出了基本的職責行為模型,然后將可變的業(yè)務歸納到了一個配置層中。也就是說,不是直接去實現(xiàn)業(yè)務功能,也不假定用戶具有什么職務就能干什么,而是將復雜的業(yè)務功能拆解成幾個基本行為。然后用配置層將這些行為組合起來供用戶使用,就像搭積木一樣。
這樣開發(fā)出來的軟件,做到了原先根本不敢想象的事情—用戶上午找我談心的業(yè)務流程和想法,下午兩點上班后,立刻就在系統(tǒng)中能夠使用這個功能。這種敏捷和響應能力,堪比“飛機在飛行中更換發(fā)動機”,這讓用戶非常滿意。
更為難得的是,數(shù)年后,包括我在內的幾名開發(fā)骨干陸續(xù)離開了那家軟件公司,這家軟件公司也不復存在了。然而,這套沒有人維護的系統(tǒng)一直被用戶保留了下來,至今已連續(xù)工作了近15年,期間沒有經(jīng)過大的升級和開發(fā)。現(xiàn)在依然每天有數(shù)百人在操作和使用,累計運行數(shù)據(jù)也有了幾十TB。
軟件沒有針對用戶的“具體需求”來設計,而是通過抽象的模型來設計開發(fā)。能夠十幾年無需升級而滿足各種業(yè)務變化,無疑是那套抽象了所有業(yè)務模型的配置層帶來的。
然而并不是所有的項目和產(chǎn)品都能像這個項目一樣完美收官。在項目過程中,我們還認識到要實現(xiàn)業(yè)務靈活性的重大代價。因此,不要讓完美主義耽誤了時機,畢竟天下武功,唯快不破,很多時候客戶需要的是及時響應而不是完美無缺。
3. 非功能性的問題也對架構有著高要求
隨著系統(tǒng)規(guī)模越來越大,單純做好業(yè)務模型和業(yè)務設計,并不足以保證軟件的成功。隨著架構工作的深入,架構師需要一一或者說不得不更多考慮非功能性的設計要點。
2011年,我參加了某省移動通信公司BOSS系統(tǒng)升級和重構項目。所謂BOSS系統(tǒng),是行內的一個叫法,正式名稱是Business&Operation Support System,在通信行業(yè),一般分為四個部分:計費及結算系統(tǒng)、營業(yè)與賬務系統(tǒng)、客戶服務系統(tǒng)和決策支持系統(tǒng)。
這樣的一個系統(tǒng),是由我當時所在的公司杭州、南京兩個研發(fā)中心加上北京研發(fā)中心的部分專家,有數(shù)十個團隊參與開發(fā)和測試,近百人在現(xiàn)場進行系統(tǒng)集成。我當時負責的是營業(yè)與賬務系統(tǒng)和部分計費系統(tǒng)的核心框架設計。
我們對營帳系統(tǒng)的交易鏈路進行壓力測試。測試的結果不容樂觀,服務整體并發(fā)性能未達到客戶要求的數(shù)據(jù),接下來要推動整個系統(tǒng)的性能優(yōu)化。這個任務的困難在于大型分布式系統(tǒng)關系錯綜復雜,整個營帳系統(tǒng)的鏈路是一條很長的集群,涉及到另外兩個系統(tǒng)的調用,同時每個系統(tǒng)內部都有好多組件,彼此形成了復雜的調用關系。而大多數(shù)組件來自不同團隊,我們團隊提供的RPC框架和基礎框架只覆蓋了65%的組件,剩余來自其他省市研發(fā)團隊的組件架構不明,設計也完全不了解。在這種情況下,我認為需要解決以下問題:
1. 搞清楚每個測試案例的調用鏈順序。在核心調用鏈上,應該將非核心的系統(tǒng)剔除。
2. 造成整體鏈路性能不佳的短板在哪里?
3. 找到存在性能短板的組件后,如何發(fā)現(xiàn)性能瓶頸。
針對問題1,我們基于RPC框架輸出結果的分析,初步完成了一個調用關系圖,然后配合軟件設計文檔,編寫流量轉發(fā)代理工具補充完整了調用鏈路圖。
問題2,我們在RPC框架基礎上增加了分析模塊,自動對每次吞吐的數(shù)據(jù)量進行記錄,還用于分析響應時長排名、報文長度等Top10等,根據(jù)排名情況列出一大堆所謂“慢接口”,但是我們不能因為一個接口慢,就認為它有問題。我們針對數(shù)據(jù)庫的訪問研發(fā)了自己的ORM框架,解決了一部分慢性能問題。
問題3,我們發(fā)現(xiàn)慢的接口往往集中在幾個組件上,這和這些組件的設計質量有一定關系。
這個故事告訴我們,大部分研發(fā)團隊在項目之初對非功能性的特性考慮往往不多,架構師在設計技術架構時,需要成為軟件質量底線的保障者,讓軟件具備足夠的自我糾錯能力,以及一致的可集成、可維護的能力。
走出成為架構師的關鍵道路
1. 追根,抽象,把握事物本質
在過去的經(jīng)歷中,促使我從普通的編程者向架構師轉變的根本因素,我認為是一種試圖追尋事物本質的好奇心。這種好奇心是促使人思考和訓練思維的源泉。人類的大腦在記憶力和理解力上是有其局限的,因此人不得不通過抽象,屏蔽事務的無關要素和細節(jié),才能把握事物的本質。
中國古代哲學中,有很多這一類思辨,比如—“時有風吹幡動。一僧曰風動,一僧曰幡動。議論不已。惠能進曰:非風動,非幡動,仁者心動?!睂τ谶M修禪心者來說,直指人心的思辨,毫無疑問抓住了問題的本質。因為在參照系為“人心和佛性”的禪學中,世界的本質已經(jīng)“不在你的心外”(王陽明語)。參照系的不同,帶來的結論也就不同。哲學中相對與絕對、運動與靜止、唯心與唯物、存在與虛無都有很多對思維的訓練,通過思辨,能提升個人的思維抽象能力,因為抽象是哲學思維的基本特征。
2. 不停的學習和傳播知識
在技術架構中,各種架構方法可能是大家容易關注到的—面向對象、面向模式、自頂向下分解、自底向上分層等等,從馮諾依曼體系到通信協(xié)議、UML等有很多設計方法和架構理念可以學習。
但是在做業(yè)務分析和設計時,如何考慮業(yè)務模型,如何兼顧涉眾利益?大家都知道人性是復雜的,但是在組織內部,人的行為和動機是有軌跡的,人類所表現(xiàn)出來的無外乎正常成年人的社會人格和動機,而這正是普通心理學和組織行為學的研究范圍。所以做業(yè)務架構的伙伴要去學一些這方面的知識。其實老祖宗早就告訴過我們,“世事洞明皆學問,人情練達即文章”就是這個道理。
架構師無法“獨善其身”,缺少了實現(xiàn)架構的研發(fā)和項目團隊,架構就會成為空中樓閣。因此,成功的架構師只有讓組織成功才能真正的成功。架構師要樂于將自己的知識、想法和同事、朋友分享。如果孤芳自賞,那就沒有了用武之地。
3. 追求簡約與平衡的架構之美
大多稱為架構師的人,都有追求完美的偏好,但實際在項目和產(chǎn)品開發(fā)中,既沒有機會,也沒有必要實現(xiàn)完美的架構與軟件。因為完美就意味著脫俗,脫俗就意味著無先例、無參照,這往往會帶來巨大的風險和不可控因素。
KISS原則是架構師要注意遵循的一個原則,因為越復雜的東西就越精密,越精密的東西在工程中就越不可靠。尤其在分布式系統(tǒng)設計中,異常和故障的可能性太多了。將系統(tǒng)設計得絲絲入扣而沒有任何預防措施,那么一旦出現(xiàn)任何意外,異常情況就會像滾雪球那樣蔓延開來,直到整個系統(tǒng)奔潰。在二戰(zhàn)中,德國的坦克大量使用交錯式負重輪。這是一種非常復雜的機械構造,性能優(yōu)良,穩(wěn)定性好。然而就是生產(chǎn)復雜,維修繁瑣,產(chǎn)量輸給對手老大一截,而且容易出故障。據(jù)記載,虎式、豹式坦克的戰(zhàn)損率和機械故障發(fā)生率幾乎相等。種種因素下,性能強悍的虎式、豹式最終只能被淹沒在廉價坦克T-34的海洋之中。
架構師最終需要站立在大地上,才能仰望天空。平衡好成熟技術和新技術之間的關系、平衡好硬編碼和業(yè)務引擎之間的取舍、平衡好性能與資源占用之間的矛盾等等,這些都是架構師需要把握的。這種平衡往往來自于環(huán)境需求,而不應當是架構師的個人喜好。比如在預研性的項目中,可以適當采取更激進的技術策略,但是對于有緊迫上線時間要求的產(chǎn)品,就需要更保守和穩(wěn)妥的解決方案。
所謂平衡,并不是平均,更不是平庸。而是在所處場景中,態(tài)度鮮明地取舍—在性能中取舍,在功能中取舍等等。這種存乎在心的取舍最終會形成架構師獨特的審美,這種審美源自環(huán)境(或者場景)與架構的和諧。這種和諧之美體現(xiàn)在業(yè)務整體,而不是來自于某頂高精尖的局部構造—就像我們在山林中搭建的小木屋和在都市中搭建的混凝土大廈一樣,如果交換了場所,那就失去了和諧之美。
回顧與總結
在軟件行業(yè)工作,就是在多變的需求、緊湊的工期、古怪的bug中不斷掙扎的過程,回首過往,十余年來很多同事在這樣的顛簸中或轉型管理、或轉型售前、或離開了這個行業(yè),這是非常遺憾的。對于我們很多人來說,在邁過所有這些坎坷后,就會發(fā)現(xiàn)軟件開發(fā)工作是“踏遍青山人未老,風景這邊獨好”。
回首向來蕭瑟處,也無風雨也無晴。當你真正體會了這個行業(yè)的酸甜苦辣之后,還有什么能讓你放棄這個職業(yè)呢?
--是“枯燥的編碼生活”嗎?不,怎么會有人覺得編碼枯燥呢?多年來,我內心一直以作為碼農自豪,堅持每天寫代碼。最能體現(xiàn)軟件從業(yè)人員“像上帝一樣”編排一切的工作,無疑就是編碼了。你從哪里還能得到創(chuàng)造一個世界那樣的滿足感?
--是“用戶頻繁的變更需求”嗎?不,每個用戶都是理性的體驗者,他們追求的一直都是更好地完成業(yè)務,流水般變動的只是業(yè)務的形態(tài),始終如一的是管理學、組織行為學和普通心理學作用下的業(yè)務本質。領會到這一點,你會從用戶的微笑和感謝中找到前進的動力。
--是“繁重到不加班就完成不了的任務”嗎?不,任何成就哪有不經(jīng)過汗水和痛苦就能達到的呢?辛苦和汗水帶來的不僅僅是疲勞,還有榮譽和滿足感。
堅持走技術發(fā)展的道路,用技術手段解決客觀世界的問題,然后在軟件設計和編碼的汪洋大海中尋找樂趣,這是所有軟件技術人的最好歸宿。最后,我希望有志于成為架構師的年輕人能在技術軟件研發(fā)和架構的道路上堅持下去,直到體會到真正樂趣的時刻。