架構之路(一):目標

文章轉載自自由飛博客,喜歡請去支持原作者!

標準來源于目標

前文說過,評價架構好壞是一個很主觀的東西。既然大家寫出來的程序都能跑,憑什么就說你架構好,我的架構就差?拿出來大家評評理,張三說好,李四說不行,王五說將就……究竟誰說了算?現在已經不是一個迷信權威的時代了,所以不管你多少光環加持,你都得說出子丑寅卯來,都得服眾才行。

我覺得,這種現象的產生,拋開“同行相輕”和“流派之爭”之類無厘頭的東西,一個很重要的原因就是沒有明確判斷標準。所以在網上,常常就出現這樣一種很熱鬧很奇葩很無奈的現象:我和你說性能,你跟我說安全;我跟你說安全,你跟我說擴展;我跟你說擴展,你跟我說維護;我跟你說維護,你跟我說成本……

這是一個很簡單的道理,沒有標準,就無法進行評判!所以,如果不能統一一個評判架構優劣的標準,我們永遠無法達成一致。你說有標準啊,性能安全可擴展……但這樣還是不行,標準過多,一樣等同于沒有標準。假設以100分為滿分,性能占多少分?安全占多少分?可擴展又占多少分?因為要想提高性能,就可能就要犧牲可擴展性;要想安全,就會犧牲性能;要想……就會……;哪一方面更重要,哪一些可以犧牲?如果不是胸有成竹的話,最后還是會左支右絀手忙腳亂,亂成一鍋粥。

所以我再提出一個觀點:以是否實現架構師的設計目標為標準。如果說一個系統的架構,最終實現了架構師的設計目標,我們就可以說這是一個好架構;如果說沒有能實現架構師的目標,這就是一個不那么好的架構。

“等一下等一下”,你要是反應夠敏銳的話,肯定會跳起來,“這是不是太主觀(兒戲)了?我隨便一堆爛代碼,然后告訴你,‘是啊,我設計的目的就是讓他爛,越難越好’,按你的邏輯,這樣也行?”(⊙_⊙),嗯,你要是這樣玩兒我還真沒辦法。但是話又說回來,要讓一堆代碼能跑又還夠“爛”,也還不是一件容易的事,你覺得呢?

總之,我希望大家能明白我的意思:架構師開始一個新項目,應當設立一個適當的設計目標;然后通過架構,努力實現其預定目標。如果最終系統的運行,符合其設計預期,我們就可以說:這個架構不錯還行!反正,架構就出了問題。

我們的目標

軟件行業有各種各樣的系統,每一種系統的開發都可能會有不同的目標。比如導彈發射的系統,我們可以想象,目標(甚至是基本要求)肯定是:1、穩定(絕對不能走火);2、迅速反應(不允許按下發射按鈕后一分鐘導彈才開始發射)。你可能覺得這種要求很好啊!任何系統不都是應該滿足這樣要求的嗎?比如我在淘寶買T恤,結果給我發一條丁字褲,這怎么行?一個網頁半天打不開還有理了?我還真得答一句,它就是有理了。“存在即合理”,這里的合理,合理在成本。我們目前日常使用到的絕大部分軟件,都是有bug的,而且是一堆的bug,但我們仍然在使用它們。如果你想使用像“導彈發射”一樣穩定精確迅捷的軟件,可能最后的結果只有一個:你用不起。(請自行腦補)

所以,其實我們是做了一個妥協,“便宜點,將就用吧”。我們為了達到我們的基本目的,犧牲掉一些“無關緊要”的東西。對于很多追求卓越的程序員來說,這種犧牲妥協是難以接受的。“白玉微瑕,你讓我怎么能夠接受?”——但很多時候,你必須接受。這個問題這個觀點,我們會在整個系列中不斷的提及。請試著接受;如果你暫時還不能接受,請牢記:沒有犧牲,就沒有勝利!

那么,我們的策略是:特色突出、整體均衡。說得更直白一點:有亮點,沒硬傷。這就夠了!而我們的亮點就是:可維護性。(注意:不是可擴展,可維護性包含可擴展,但不僅僅是可擴展)

為什么是可維護性

幸或者不幸,我進入軟件行業之后,絕大部分的工作是幾乎所有程序員都不齒厭惡的維護。我曾經維護過一個有十年歷史的、糅合了C、VB、java、C#各種語言在內的一個物流系統的部件。我在那家公司工作了一年多,說實話,直到我離職,對整個系統,我連邊都沒摸到——這個系統太大了,而且連我們公司都只是其主營公司眾多外包公司中的一個。

在我花了兩周的時間找到一個bug的位置之后,我以為我終于明白了為什么會說:“維護和開發的花費比是80:20”。但這只是我以為——現實更加殘忍:差不多一個月后,我又花了一個星期的時間,找到了另外一個bug的根源,正是我fix前一個bug所產生的。我淚流滿面,有沒有?腦子里一下就蹦出個詞:“按下了葫蘆浮起了瓢”!總之,如果fix前一個bug就會導致后一個bug;如果fix后一個bug,就會導致前面的bug。我忘了最后是怎么處理這個問題的,依稀記得是讓項目經理去和稀泥去了。因為這不是一個很關鍵很常用的功能,所以最后大概是不了了之吧。

后來我了解到,很多的開發項目,是這樣一個流程:一群人根據文檔開始開發,幾個月后通過驗收上線;然后開發團隊解散,留下一兩個項目組里最菜的菜鳥做“維護”。Game Over!皆大歡喜。這種現象,在各種外包團隊(尤其是以項目計價的廉價外包團隊)中更加的突出(這或許也是大家普遍歧視外包公司的一個原因?)

既然是這樣一種開發模式,很多開發人員根本體會不到維護的痛苦。在他們看來,“維護嘛,修修補補,加一兩個if...else而已,讓我們開發人員做更高大上的工作吧!”但他們也不是總這么幸運,有時候,他們會被抓去“填坑”。據說最通常的做法,就是在“老坑”周圍再挖一堆“新坑”,填平之前的老坑即可。周而復始,直到有一天,“受不了啦!我們重寫吧!”——等等,為什么不重構?呵呵,好問題,你覺得呢?

需求變更

很多程序員把這種困境歸咎于“需求變更”。如果不是那些傻逼客戶一天到晚的改需求,我一定會做出一個完美的作品!

或許是因為我是半路出家的原因,和很多程序員相反,我覺得:不是需求變更驅動著軟件的不斷更改,而是“軟件可以隨意更改”的這種特性刺激了不斷的需求變更。你裝修好的房子,是不是住一段時間之后就會覺得這里那里不合適?這里少了一個插座,陽臺上該加一個龍頭,櫥柜用著不順手……“要是能改改就更好了!”,只是這樣的改動太費力,所以大多數時間我們都還是算了。但軟件可以!理論上怎么改都可以。想想軟件真的是一種很特殊的商品——它是可以交付“半成品”的。你先用著,如果有問題我再改改,有新需求我再改改,一直可以改到面目全非。沒有在其他傳統行業里待過的程序員無法理解,“可以隨意更改”是一種多么出色的特質。這意味著產品可以自我進化,應對各種變化,可以永生!想象這樣一臺“汽車”,開始可以在馬路上跑,過段時間改一下就可以在水里游,再拆裝一下可以當摩托拉風,堵車的時候展開翅膀……這是什么樣一種屌爆天的體驗啊?

所以,“擁抱變化”絕不是一句口號,這是一種胸懷。

作為示例的這兩個系統,我是希望能用他們一輩子的。但我甚至無法想象一年之后他們會是什么樣子——他們需要接受市場的檢驗,應對技術的升級換代,會有各種想象不到的變化。所以,可維護性無疑是必須放到首位的。

為了可維護

明確了架構的首要目標,我們就可以做一些基礎的選擇了。比如開發語言,可是是面向對象的C#,不需要“性能卓越”的C。

說道“面向對象”,可能有些同學就會比較high,腦子里就會冒出“抽象”、“封裝”、“設計模式”等各種高大上的東西出來。但我不得不提醒你們:首先,這些都是微觀層面考慮的東西,而架構是宏觀的;然后,這些都不是架構,而是潤滑黏合支持架構的東西;最后,在其他條件不變的情況下,系統中這些東西用得越少,說明架構越好。

我們以“設計模式”為例。大家在學習設計模式的過程中有沒有這樣一種困惑,“這樣繼承封裝多態亂七八糟的繞來繞去的干嘛?”我花了很長一段時間才明白,要理解設計模式,必須要明白三個字:“不得已”。是迫不得已,才用設計模式來解決一些特定的問題,而不是說正常的代碼就應該這樣寫!這種迫不得已,有很多種原因。個人覺得最容易理解的就是“適配器模式”,因為出現了接口的沖突,所以我們不得不進行適配。但一個很自然的問題就是:為什么不直接改接口讓他們自然融洽呢?這不是一種更自然更直觀的解決方案嗎?答案很有可能就是因為架構——大的架構已經確立,局部必須服從整體。那么,如果一個完全理想化的架構,是不是根本就不應該出現這種問題接口沖突的問題,因而根本就不需要這種設計模式?

所以,我說設計模式之類的東西是潤滑劑是黏合劑,他們的作用是彌補架構的局部缺陷,更好的支撐架構。更極端的一種說法可以送給癡迷于設計模式的同學:設計模式是藥,沒病就不要吃藥!

那么,為了可維護性,架構中究竟應該注意些什么?這是一個很大的話題,開篇我們只說一點。

模塊劃分

模塊有大有小,大可以是一個分層一個項目,小可以是一個方法一個類。我們通常的做法是由大到小,逐步細分。

模塊的劃分是相當的考驗架構能力的。良好的模塊劃分,能夠讓我們方便的安排人手、合理的組織項目進度、迅速的定位代碼……各種好處說都說不完。所以還是說說不好的模塊劃分有什么問題更容易一些,嗯,這個好像根本就不要說,想想你在一堆亂七八糟的代碼里不斷的F11的情形吧!

我個人認為,模塊劃分的難度在于“整齊”和“靈活”之間取舍。通常來說,大的模塊我們都是“一刀切”,著重強調的是“整齊”,比如口熟能詳的UI層、BLL層和DAL層,但這種“一刀切”的做法,更多的是一種無奈。我們的人類的思維局限決定了我們在考慮復雜問題時無法深入到每一個細節,所以只能先“大而化之”的把一個復雜問題先進行簡單化。這樣帶來的一個嚴重的副作用就是,限制了代碼的靈活性;而靈活性,正是應對復雜變化的有效武器。所以,在更小一些的模塊(比如說:類)里,我們引入了豐富多彩的抽象繼承設計模式等一系列充滿各種靈活性的機制,以彌合“一刀切”造成的問題。這一松一緊一張一弛中“度”的掌握,就只能說是一種藝術了。

模塊劃分,籠統的說教用處不大,我們將在后面的文章中結合具體情況逐一說明。但我希望大家能夠明白:模塊劃分是必須的——這種必須,是一種無可奈何的選擇。所以,喜歡從頁面直接寫sql到數據庫的同學,老大讓你把你的代碼拆成幾段放到不同地方的時候,不要嫌麻煩;喜歡把一個簡單項目切成七層的同學,先仔細想不想這樣做是不是真的有必要。

代碼之外

為了代碼能夠長期有效的維護,我們還需要做很多工作,比如良好的文檔、完善的項目管理流程。但我想說的,還是不是這個,而是代碼之外的因素對項目架構的影響。比如開發團隊的背景能力偏好,一群C#程序員,你一定要整個node.js,這純粹是給自己找不痛快。除了這些稍稍用腦袋想一想就能明白的東西,有一件事,很多程序員并沒有意識到。

架構的一個天然目的就是:讓代碼更智能讓程序員更傻瓜。換一張說法就是,架構要“創造便利,讓程序員更關注業務”。

這可能是一個讓程序員感到悲哀的事實。正如機械師不停的發明,讓機器變得越來越聰明,取代流水線上的工人,最終取代了他們自己。從某種意義上說,我們都是自掘墳墓的人。一個良好的架構,就應該是讓每一個普通開發人員,都是一個個盡量廉價隨時可以替換的螺絲釘,這樣才能保證系統永遠健康正常的運行下去。告訴你這個事實可能讓你一整天都不開心,但接受這個事實之后能幫助你在工作中變得更加的“心平氣和”。螺絲釘就要有螺絲釘的覺悟;更何況,當好一顆螺絲釘也不是一件很容易的事。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,501評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,673評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,610評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,939評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,668評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,004評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,001評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,173評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,705評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,426評論 3 359
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,656評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,139評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,833評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,247評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,580評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,371評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,621評論 2 380

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,761評論 25 708
  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,829評論 18 139
  • 我想成為背包客,走走停停或許我更快樂一些。
    酸奶兩個閱讀 103評論 0 0
  • 第一次用試試
    薪順喜閱讀 93評論 0 0
  • 字符串“PAYPALISHIRING”以給定行數的鋸齒形圖案寫成:(您可能希望以固定字體顯示此模式以獲得更好的可讀...
    安東可閱讀 1,294評論 0 0