架構學習總結
架構漫談(一):什麼是架構? -王概凱 - 轉
架構漫談(一):什麼是架構?
架構漫談是由資深架構師王概凱Kevin執筆的系列專欄,專欄將會以Kevin的架構經驗為基礎,逐步討論什麼是架構、怎樣做好架構、軟體架構如何落地、如何寫好程式等問題。專欄的目的是希望能丟擲一些觀點,並引發大家思考,如果你有感觸或者新的感悟,歡迎聯絡專欄負責人Gary(微信greenguolei)深聊。
本文是漫談架構專欄的第一篇,作者將會通過類比的方式來介紹什麼是架構以及為什麼會產生架構。
緣起
一直以來,在軟體行業,對於什麼是架構,都有很多的爭論,每個人都有自己的理解。甚至於很多架構師一說架構,就開始談論什麼應用架構、硬體架構、資料架構等等。我曾經也到處尋找過架構的定義,請教過很多人,結果發現,沒有大家都認可的定義。套用一句關於big data流行的笑話,放在架構上也適用:
Architecture is like teenage sex,everybody talks about it,nobody really knows what is it。
事實上,架構在軟體發明時的N多年以前,就已經存在了,這個詞最早是跟隨著建築出現的。所以,我覺得有必要從源頭開始,把架構這個概念先討論清楚,只有這樣,軟體行業架構的討論才有意義。
什麼是架構?
架構的英文是Architecture,在Wikipedia上,架構是這樣定義的:
Architecture (Latin architectura, from the Greek ἀρχιτέκτων arkhitekton"architect", from ἀρχι- “chief” and τέκτων “builder”) is both the process and the product of planning, designing, and constructing buildings and other physical structures。
從這個定義上看,架構好像是一個過程,也不是很清晰。為了講清楚這個問題,我們先來看看為什麼會產生架構。
為什麼會產生架構?
想象一下,在最早期,每個人都完全獨立生活,衣、食、住、行等等全部都自己搞定,整個人類都是獨立的個體,不相往來。為了解決人類的延續的問題,自然而然就有男女群居出現,這個時候就出現了分工了,男性和女性所做的事情就會有一定的分工,可是人每天生活的基本需求沒有發生變化,還是衣食住行等生活必須品。
但是一旦多人分工配合作為生存的整體,力量就顯得強大多了,所以也自然的形成了族群:有些人種田厲害,有些人制作工具厲害,有些地方適合產出糧食,有些地方適合產出棉花等,就自然形成了人的分群,地域的分群。當分工發生後,實際上每個人的生產力都得到了提高,因為做的都是每個人擅長的事情。
整個人群的生產力和抵抗環境的能力都得到了增強。為什麼呢?因為每個人的能力和時間都是有限的,並且因為人的結構的限制,人同時只能專心做好一件事情,這樣不得已就導致了分工的產生。既然分工發生了,原來由一個人幹生存所必需的所有的事情,就變成了很多不同分工的角色合作完成這些事情,這些人必須要通過某些機制合在一起,讓每個人完成生存所必需的事情,這實際上也導致了交易的發生(交易這部分就不在這裡展開了,有機會再討論)。
在每個人都必須自己完成所有生活必須品的生產的時候,是沒有架構的(當然在個人來講,同一時刻只能做有限的事情,在時間上還是可能會產生架構的)。一旦產生的分工,就把所有的事情,切分成由不同角色的人來完成,最後再通過交易,使得每個個體都擁有生活必須品,而不需要每個個體做所有的事情,只需要每個個體做好自己擅長的事情,並具備一定的交易能力即可。
這實際上就形成了社會的架構。那麼怎麼定義架構呢?以上面這個例子為例,把一個整體(完成人類生存的所有工作)切分成不同的部分(分工),由不同角色來完成這些分工,並通過建立不同部分相互溝通的機制,使得這些部分能夠有機的結合為一個整體,並完成這個整體所需要的所有活動,這就是架構。由以上的例子,也可以歸納出架構產生的動力:
必須由人執行的工作(不需要人介入,就意味著不需要改造,也就不需要架構了)
每個人的能力有限(每個人都有自己的強項,個人的產出受限於最短板,並且由於人的結構限制,同時只能專注於做好一件事情,比如雖然有兩隻眼睛,但是隻能同時專注於一件事物,有兩隻手,無法同時做不同的事情。ps. 雖然有少部分人可以左手畫圓右手畫框,但是不是普遍現象)
每個人的時間有限(為了減少時間的投入,必然會導致把工作分解出去,給擅長於這些工作的角色來完成,見2,從而縮短時間)
人對目標系統有更高的要求(如果滿足於現狀,也就不需要進行架構了)
目標系統的複雜性使得單個人完成這個系統,滿足條件2,3(如果個人就可以完成系統的提高,也不需要別的人參與,也就不需要架構的涉及,只是工匠,並且一般這個工作對時間的要求也不迫切。當足夠熟練之後,也會有一定的架構思考,但考慮更多的是如何提高質量,提高個人的時間效率)
有人可能會挑戰說,如果一個人對目標系統進行分解,比如某人建一棟房子,自己採購材料,自己搭建,難道也不算架構嘛?如果對於時間不敏感的話,是會出現這個情況的,但是在這種情況下,並不必然導致架構的發生。如果有足夠的自覺,以及足夠的熟練的話,也會產生架構的思考,因為這樣對於提高生產力是有幫助的,可以縮短建造的時間,並會提高房子的質量。事實上建築的架構就是在長期進行這些活動後,積累下來的實踐。
當這5個條件同時成立,一定會產生架構。從這個層面上來說,架構是人類發展過程中,由懵懵懂懂的,被動的去認識這個世界,變成主動的去認識,並以更高的效率去改造這個世界的方法。以下我們再拿建築來舉例加強一下理解。
最開始人類是住在山洞裡,住在樹上的,主要是為了躲避其他猛獸的攻擊,以及減少自然環境的變化,對人類生存的挑戰。為了完成這些目標,人類開始學會在平地上用樹木和樹葉來建立隔離空間的設施,這就是建築的開始。但是完全隔離也有很多壞處,慢慢就產生了門窗等設施。
建築的本質就是從自然環境中,劃出一塊獨佔的空間,但是仍然能夠通過門窗等和自然環境保持溝通。這個時候架構就已經開始了。對地球上的空間進行切分,並通過門窗,地基等,保持和地球以及空間的有機的溝通。當人類開始學會用火之後,茅棚裡面自然而然慢慢就會被切分為兩部分,一部分用來燒飯,一部分用來生活。當人的排洩慢慢移入到室內後,洗手間也就慢慢的出現了。這就是建築內部的空間切分。
這個時候人們對建築的需求也就慢慢的越來越多,空間的切分也會變成很多種,組合的方式也會有很多種,比如每個人住的房子,群居所產生的宗教性質的房子,集體活動的房子等等。這個時候人們就開始有意識的去設計房子,架構師就慢慢的出現了。一切都是為了滿足人的越來越高的需求,提升質量,減少時間,更有效率的切分空間,並且讓空間之間更加有機的進行溝通。這就是建築的架構以及建築的架構的演變。
總結一下,什麼是架構,就是:
根據要解決的問題,對目標系統的邊界進行界定。
並對目標系統按某個原則的進行切分。切分的原則,要便於不同的角色,對切分出來的部分,並行或序列開展工作,一般並行才能減少時間。
並對這些切分出來的部分,設立溝通機制。
根據3,使得這些部分之間能夠進行有機的聯絡,合併組裝成為一個整體,完成目標系統的所有工作。
同樣這個思考可以展開到其他的行業,比如企業的架構,國家的架構,組織架構,音樂架構,色彩架構,軟體架構等等。套用三國演義的一句話,合久必分,分久必合。架構實際上就是指人們根據自己對世界的認識,為解決某個問題,主動地、有目的地去識別問題,並進行分解、合併,解決這個問題的實踐活動。架構的產出物,自然就是對問題的分析,以及解決問題的方案:包括拆分的原則以及理由,溝通合併的原則以及理由,以及拆分,拆分出來的各個部分和合並所對應的角色和所需要的核心能力等。
架構漫談(二):認識概念是理解架構的基礎
在前一篇文章中,我們討論了什麼是架構。事實上,這些基礎概念對於做架構是非常重要的,大部分人對於每天都習以為常的概念,都自以為明白了,但實際上都是下意識的,並不是主動的認識。比如說“什麼是桌子?”,做培訓的時候,我經常拿這個例子來問大家,回答千奇百怪。這實際上就導致了做架構的時候,不同角色的溝通會出很多問題,那麼結果也就可想而知了。
如前一篇所說,架構實際上解決的是人的問題,而概念是人認識這個世界的基礎,自然概念的認識就非常的重要。這篇文章嘗試討論一下,如何去認識概念。當然這篇不是語言學的文章,我這裡所討論的,和語言學可能不太一樣,如果大家對語言學感興趣,也可以去參考一下。
首先我要先宣告一下,這一系列的文章,都是以人的認識為主體去討論的,解決的都是人的問題,任何沒有具體申明的部分,都隱含這一背景,以免大家誤解。
概念也屬於人認識這個世界並用來溝通的手段,包括“概念”這個概念,也是一樣的。在古代,不叫“概念”,稱之為“名相”。
何為相?
一般我們認為:看到一個東西,比方說杯子,“杯子”就是一個名字,指代的看到的東西就是相,就是事物的相狀。我們一聽到“杯子”這個詞,腦海裡就會浮現出一個杯子的形象。而“杯子”這個詞,是用來指代的是這個相狀的,叫做名。合起來就叫做“名相”。
可是當我們把杯子打碎了的時候,我們還會稱這個碎了的東西叫杯子嗎? 肯定不會,一般會叫“碎瓦片”,如果我們把碎瓦片磨碎了呢,名字又變了,叫做“沙子”。這就奇怪了,同樣一個東西,怎麼會變出這麼多的名字出來?
那究竟什麼才是相?
實際上“相“表達的不是一個具體的東西,如上面所提的一個瓷器杯子,並不是指這個瓷器,而是這個瓷器所起的一個作用:一手可握,敞口(一般不超過底的大小,太大口就叫碗了),並且內部有一個空間可乘東西的這麼一個作用。並不是指這個瓷器本身。這也是為什麼我們從電視上看到一個人拿杯子的時候,我們知道這個是杯子。但是實際上我們看到的都是光影而已。所以說相實際上代表的是這個作用,並不是具體的某個東西,而名是用來標識這個作用的,用來交流的。
為何需要這個作用?
這個作用其實是為了解決“人需要一個可單手持握,但是希望避免直接接觸所盛物體”這個問題。
所以說,每個概念實際上所解決的,還是人遇到的某個特定的問題,我們把解決問題的解決方案,給定了一個名字,這個名字就是對應的某個特定的概念。對於概念這個詞本身,為了統一指代這些名字,我們稱起這類作用的名字稱為“概念”。我們上次討論的“架構”也是是同樣的一個特定概念,這裡不再詳述。同樣,什麼是“建築”? “建築”實際上解決的就是“人需要獨佔的空間,並還能夠比較流暢的和外部世界溝通”的問題。
再拿前面的“桌子”來舉例,什麼叫“桌子”? 很多人回答,四條腿,或者說有腿,有一個平面,等等,櫃子不也是這樣嗎?為什麼我們看到櫃子,不會認為是桌子呢?即使我們放在櫃子上吃飯,我們看到仍然會問,為什麼在櫃子上吃飯? 不會叫桌子。如果明白了上面的道理,就很簡單了,桌子實際上是為了解決人坐在椅子上,手還能夠支撐在一個平面上繼續開展活動的問題,一般會和椅子配對出現。坐在椅子上工作,對著櫃子有一個很嚴重的問題——不知道大家試過沒有——就是腿無法展開的問題。當這麼坐著超過半小時就知道是什麼痛苦了。所以桌子的平面下方一定會有一個足夠容納膝部和小腿的空間,來解決這個問題。解決了這些問題的裝置,才能稱之為桌子。
類似也可以定義出來椅子,由此可見,桌子和椅子的高度也是有限定的,都是是解決人的問題,要符合人的身高:椅子的高度和深度,必須符合小腿和大腿的長度;椅背的高度要配合脊柱的高度;桌子的高度要配合小腿和脊柱的高度之和;成人和小孩的自然也就有區別了。這又變成生理學了,事實上要做好桌子和椅子,必須要理解人的生理結構,才能正確的理解桌子和椅子的概念。
同理,為何我們可以在不同的語言間進行翻譯,是因為雖然語言不同,但是人類所面臨的的問題是一樣的,所使用的名不同而已。對於不同的動物之間的翻譯也是同理。
關於抽象
在討論桌子這個概念的過程中,很多人會提出抽象這個概念,認為定義桌子實際上就是抽象的一個過程。這裡,我覺得有必要要澄清一下抽象這個概念,我認為這個裡面有誤解。我注意到,在做架構師的群體中,不談抽象好像就不是一個合格的架構師。
抽象這個詞代表的含義,實際上是把不同的概念的相似的部分合並在一起,形成一個新的概念。這個裡面問題很多:首先“相似的部分”在不同的人看來,並不一定那麼相似;其次,抽象之後形成的是一個新的概念,和原來那個概念並不一樣,所解決的問題也不一樣。所以我們不能用抽象來定義一個事物,抽象實際上是一個分類的過程,完全是另一碼事。再舉一個例子,杯子和容器,很多人認為容器是杯子的抽象,但是實際上杯子是杯子,容器是容器,它們所解決的問題是不一樣的。當我們需要解決裝東西的問題的時候,會說容器;當我們需要解決單手持握要裝東西的時候,會說要一個杯子。
回過頭來,根據架構的定義,要做好架構所首先必須具備的能力,就是能夠正確的認識概念,能夠發現概念背後所代表的問題,進而才能夠認識目標領域所需要解決的問題,這樣才能夠為做好架構打好基礎。事實上,這一能力,在任何一個領域都是適用的,比如我們如果想要學習一項新的技術,如Hibernate、Spring、PhotoShop、WWW、Internet等等,如果知道這些概念所要解決的問題,學習這些新的技術或者概念就會如虎添翼,快速的入手;學習一個新的領域,也會非常的快速有效;使用這些概念來解釋問題,甚至發明新的概念都是很容易的事。為什麼強調這個呢,因為做架構的時候,很多時候都是在一個新的領域解決問題,必須要快速進入並掌握這個領域,然後才能夠正確的解決問題。
以上通過幾個例子,討論了一下認識概念的誤區,如何有效的去認識概念,明白概念背後的含義,以及如何利用對概念的理解,快速的進行學習。掌握了這些原則,會有利於幫助我們在架構階段,快速的識別和定位問題。
下一篇我們會來討論一下,如何快速的定位和識別問題,這是架構的起始。
架構漫談(三):如何做好架構之識別問題
按照之前架構的定義,做好架構首先需要做的就是識別出需要解決的問題。一般來說,如果把真正的問題找到,那麼問題就已經解決80%了。這個能力基本上就決定了架構師的水平。
那麼面對問題有哪些困難呢?
我們先看一則笑話。女主人公:老公,把袋子裡的土豆切一半下鍋。結果老公是把袋子裡的每個土豆都削了一半,然後下鍋。
當然很多人會說,這個是溝通問題,然後一笑了之。其實,出現這個現象是由於我們大部分時候過於關注解決問題,急於完成自己的工作,而不關心“真正的問題是什麼”而造成的。當我們去解決一個問題的時候,一定要先把問題搞清楚。這也是我為什麼要單獨寫一篇文章講這個的原因。去看看軟體開發工作者的時間分配也可以看出,大家大部分時間花在討論解決方案和實現的細節上,基本都不會花時間去想“問題是什麼”。或者即使想了一點點,也是一閃而過,憑自己的直覺下判斷。只有真正投入思考問題是什麼的工程師,才可能會真正的成長為架構師
以這個笑話為例,看看在我們處理問題的時候,都會犯什麼樣的錯誤:
被告知要處理一個問題,但是交過來的實際上是一個解決方案,不是問題本身。
被告知要處理一個問題,直接通過直覺就有了一個解決方案,馬上考慮解決方案如何落地,或者有幾種解決方案,選哪個合適。
那麼如何識別問題呢?
所有的概念基本都有一個很大的問題,就是缺乏主語。而我們大家都心照不宣的忽略這個主語,溝通的時候也都以為大家都懂得對方說的主語是誰,結果大家都一起犯錯誤。識別問題的一個最大的前提就是要搞清楚:是誰的問題。這個搞清楚了,問題的邊界也就跟著確定了,再去討論問題才有意義。
以上面切土豆的例子來分析:
女主人提出一個問題,要切土豆下鍋煮。
男主人有一個問題,女主人交代了自己必須要完成的一個任務。
每個人都是優先處理自己的問題,自然就選擇了2,完成了這個任務。這也是大部分軟體工程師處理的方式,以自己認為對的方式完成自己的問題,沒什麼不對啊,也難怪能得到我們的共鳴。這個裡面犯的錯誤是什麼呢?
女主人公提出的實際上是解決方案,而不是燒土豆這個問題本身。女主人當時執行這個解決方案可能有困難,就把執行解決方案作為一個任務,委託給了男主人。
男主人得到了一個任務,盡心盡職地把這個任務完成了。
最後的結果是什麼呢,每個人都做了很多工作,每個人都認為自己做的是對的,因此沒有一個人對結果滿意。因為真正的問題沒有被發現,自然也就沒有被解決,那麼後續還得收拾殘局,還要繼續解決問題。事實上自己的工作並沒有完成,反而更多了。把原因歸結為溝通問題也是可以的,但對於解決問題似乎並沒有太多的幫助。因為要改進溝通,這也是一個大問題。搞明白目標問題“是誰的問題,是什麼問題”,當然也是需要溝通的。為了幫助自己更快的搞明白,首先要做的事是問正確的問題。架構師應該問的第一個正確的問題就是:目標問題是誰的問題。
當我們處理問題的時候,如果發現自己正在致力於把自己的工作完成,要馬上警惕起來,因為這樣下去會演變成沒有ownership的工作態度。在面對概念的時候,也會不求甚解,最終會導致沒有真正的理解概念。
作為軟體工程師或者架構師,我們大部分時候是要去解決別人的問題,“別人”是誰,是值得好好思考的。在這個故事裡面,男主人要解決的,實際上是這個家庭晚餐需要吃土豆的問題,目標問題的主體實際上是這個家庭的成員。
明白了問題的主體,這個主體就自然會帶來很多邊界約束,比如土豆是要吃的,要給人吃的,而且還是要給自己的家人吃的。“切土豆下鍋”這個問題,因為識別了問題的主體,自然而然的就附帶了這麼多的資訊。後續如何煮,是否放高壓鍋煮,放多少水,煮多長時間等等,就自然而然能夠問出來其他問題來了,說不定還能夠識別出來,女主人給的這個解決方案可能是有問題的。這個時候才算是真正的明白了問題。可以想象,這樣下去最後的結果一定是大家都滿意的,因為真正的問題解決了。只有真正明白了是誰的問題,才能夠真正地完成自己的任務,真正地把自己的問題解決掉,而不是反過來。
由上面的分析可以看出,找出問題的主體,是做架構的首要問題。這也是我一再強調的,我們要解決的問題,一定都是人的問題。更進一步,架構師要解決的,基本都是別人的問題,不是自己的問題。再進一步,我們一定要明白,任何找上架構師的問題,絕對都不是真正的問題。為什麼呢? 因為如果是真正的問題的話,提問題過來的人肯定都能夠自己解決了,不需要找架構師。架構師都要有這個自覺:發現問題永遠都比解決問題來的更加重要。
當問題的主體離架構師越遠,就會讓找出問題主體的過程越加困難,我們再舉一個軟體行業比較熟悉的例子:使用者給產品經理提出要求,想要一把錘子。這是典型的拿解決方案作為問題的。真正的問題的主體是誰,是使用者還是設計師還是施工隊? 如果產品經理當成是自己的問題,那麼毫無疑問就給了錘子了。
我們需要識別:使用者究竟是二傳手,還是問題的真正主體。如果是設計師,那麼問題的邊界就變成了設計師的問題;如果是施工隊,那麼問題就變成了施工隊的問題;如果是使用者,那麼就要看看使用者到底有什麼困難,絕對不是要一個錘子這麼簡單。這也說明了,問題的主體對問題的邊界確定有多麼的重要。
當明白了問題的主體,我們才可能真正的認識問題是什麼。因為問題的主體是問題的隱含邊界,邊界不確定下來,問題就是不確定的。一旦確定了主體,剩下的就是去搞明白主體有哪些問題。這個就比較直接了,常用的方式就是直接面對主體進行訪談,深入到主體的工作生活當中,體驗並感受這些問題,甚至通過資料的反饋來定位問題。這個大家就比較熟悉了,我就不展開了。
一般來說,從問題暴露的點,一點點去溯源查詢,一定會找出來誰的問題,以及是什麼問題。最壞情況就是當我們時間或者能力有限,實在是無法定位出是誰的問題的時候,比如系統出故障,也就意味著我們無法根本解決問題。這時最好的辦法就是去降低問題發生所帶來的成本,儘量去隔離問題影響的範圍。給我留出時間和空間去識別真正的問題。
總結一下,要正確的認識問題,需要問兩個問題:
這是誰的問題?
有什麼問題?
當得到的回答是支支吾吾的時候,我們就知道正確的方向在哪兒,以及需要做哪些事了。以我的經驗,問題1會花比較多的時間,也是支支吾吾最多的地方,因為架構要解決的問題都是人的問題。但是一旦確定了答案,問題2就會變得非常容易。可以這樣說,架構師的能力大部分會體現在問題1的識別上。
架構漫談(四):如何做好架構之架構切分
前一篇已經講了如何識別問題。在識別出是誰的問題之後,會發現,在大部分情況下,問題都迎刃而解,不需要做額外的動作。很多時候問題的產生都是因為溝通的誤解,或者主觀上有很多不必要的利益訴求導致的。但是總還有一部分確實是有問題的,需要做調整,那麼就必須要有所動作,做相應的調整。這個調整就是架構的切分。
切分就是利益的調整
我們要非常的清楚,所有的切分調整,都是對相關人的利益的調整。為什麼這麼說呢,因為維護自己的利益,是每個人的本性,是在骨子裡面的,我們不能逃避這一點。我們以第一篇文章裡面的例子為例來做解釋。
我們已經知道,隨著社會的發展,分工是必然的,為什麼呢? 這個背後的動力就是每個人自己的利益。每個人都希望能夠把自己的利益最大化,比如:生活的更舒適,更輕鬆,更安全,佔用並享有更多的東西。但是每個人的能力和時間都非常的有限,不可能什麼都懂,所以自然需要舍掉一些自己不擅長的東西,用自己擅長的東西去換取別人擅長的東西。
對比一個人幹所有的事情,結果就是大家都能夠得到更多,當然也產生了一個互相依賴的社會,互相誰都離不開誰。這就是自然而然而產生的架構切分,背後的原動力就是人們對自己利益的渴望。人們對自己利益的渴望也是推動社會物質發展的原動力。
在這個模式下,比較有意思的是,每個人必須要舍掉自己的東西,才能夠得到更多的東西。有些人不願意和別人進行交換,不想去依賴於別人,這些人的生活就很明顯的差很多,也辛苦很多,自然而然的就被社會淘汰了。如果需要在這個社會上立足,判斷標準就變成了:如何給這個社會提供更好更有質量的服務。提供的更好更多的服務,自然就能夠換取更多更好的生活必需品。實際上這就是我們做人的道理。
為什麼需要切分?
當人們認識到要主動的去切分一個系統的時候,毫無疑問,我們不能忘掉利益這個原動力。所有的切分決策都不能夠違背這一點,這是大方向。結合前一篇“識別問題”,一旦確定了問題的主體,那麼系統的利益相關人(用現代管理學語言叫:stakeholder)就確定了下來。所發現的問題,會有幾種情況:
某個或者某些利益相關人負載太重。
時間上的負載太重。
空間上的負載太重,本質上還是時間上的負載太重。
某個或者某些利益相關人的權利和義務不對等。
切分的原則
情況1是切分的原因,情況2是切分不合理而導致的新的問題,最終還是要回到情況1。對於情況1,本質上都是時間上的負載。因為每個人的時間是有限的,怎麼在有限的時間內做出更多的事情?那麼只有把時間上連續的動作,切分成時間上可以並行的動作,在空間上橫向擴充套件。所以切分就要有幾個原則:
必須在連續時間內發生的一個活動,不能切分。比如孕婦懷孕,必須要10月懷胎,不能夠切成10個人一個月完成。
切分出來的部分的負責人,對這個部分的權利和義務必須是對等的。比方說媽媽10月懷胎,媽媽有權利處置小孩的出生和撫養,同樣也對小孩的出生和撫養負責。為什麼必須是這樣呢? 因為如果權利和義務是不對等的話,會傷害每個個體的利益,分出來執行的效率會比沒有分出來還要低,實際上也損害了整體的利益,這違背了提升整體利益的初衷。
切分出來的部分,不應該超出一個自然人的負載。當然對於每個人的能力不同,負載能力也不一樣,需要不斷的根據實際情況調整,這實際上就是運營。
切分是內部活動,內部無任怎麼切,對整個系統的外部應該是透明的。如果因為切分導致整個系統解決的問題發生了變化,那麼這個變化不屬於架構的活動。當然很多時候當我們把問題分析的比較清楚的時候,整個系統的邊界會進一步的完善,這就會形成螺旋式的進化。但這不屬於架構所應該解決的問題。進化的發生,也會導致新的架構的切分。
原則2是確保我們不能違反人性,因為維護自己的利益,是每個人的本性。只有權利和義務對等才能做到這一點。從原則2的也可以推理,所有的架構分拆,都應該是形成樹狀的結果,不應該變成有向圖,更不應該是無向圖。很多人一談架構,必談分層,但是基本上都沒意識到,是因為把一個整體分拆為了一棵樹,因為有了樹,才有層。
從某種意義上來說,談架構就是談分層,似乎也沒有錯,但是還是知道為什麼比較好。從根節點下來,深度相同的是同一層。這個是數學概念,我就不展開了,感興趣可以去複習一下數學。
同樣我們看一個組織架構,也可以做一個粗略的判斷,如果一個企業的組織架構出現了“圖”,比方說多線彙報,一定是對stakeholder的利益分析出現了問題,這就會導致問題2的發生。問題2一旦出現,我們必須馬上要意識到,如果這個問題持續時間長,會極大的降低企業的運作效率,對相關stakeholder的利益都是非常不利的,同樣對於企業的利益也是不利的。必須快速調整相關stakeholder的職責,使得企業的組織架構成為一個完美的樹狀,並且使得樹的層數達到儘可能的低。只有平衡樹可以比較好的達到這個效果。
當然如果某個節點的能力很強,也可以達到減小樹的高度的結果。技術的提升,也是可以提升每個節點的能力,降低樹的層數。很多管理學都在討論如何降低組織架構的層數,使得管理能夠扁平化,原因就在於此,這裡就不展開討論了。從這裡也基本可以得出一個結論,一個好的組織的領導,一定也是一個很好的架構師。
切分與建模
實際上切分的過程就是建模的過程,每次對大問題的切分都會生成很多小問題,每個小問題就形成了不同的概念。這也是系列第二篇文章嘗試表達的。這些不同的概念大部分時候人們自發的已經建好了,架構師更多的是要去理解這些概念,識別概念背後所代表的的人的利益。比如人類社會按照家庭進行延續,形成了家族,由於共享一片土地資源,慢慢形成了村莊,村莊聯合體,不同地域結合,形成了國家。由於利益分配的原因,形成了政權。每次政權的更迭,都是利益重新分配的動力所決定的。
同樣對於一個企業也是一樣的,一開始一個人幹所有的事情。當業務量逐漸變大,就超過了一個人能夠處理的容量,這些內容就會被分解出來,開始招聘人進來,把他們組合在一起,幫助處理企業的事務。整個企業的事務,就按照原則2,分出來了很多新的概念:營銷,售前,售中,售後,財務,HR等等。企業的創始人的工作就變成了如何組合這些不同的概念完成企業的工作。如果業務再繼續增大,這些分出來的部分還要繼續分拆,仍然要按照原則2才能夠讓各方達到利益最大化。如果某個技術的提升,提高了某個角色的生產力,使得某個角色可以同時在承擔更多的工作,就會導致職責的合併,降低樹的層數。
切分的輸出和組織架構
架構切分的輸出實際上就是一個系統的模型,對於一個整體問題,有多少的相關方,每個相關方需要承擔哪些權利和義務,不同的相關方是如何結合起來完成系統的整體任務的。有的時候是從上往下切(企業),有的時候是從下往上合併,有的時候兩者皆有之(人類社會的發展)。而切分的結果最終都會體現在組織架構上,因為我們切分的實際上就是人的利益。
從這方面也可以看出,任何架構調整都會涉及到組織架構,千萬不可輕視。同樣,如果對於stakeholder的利益分析不夠透徹,也會導致架構無法落地,因為沒有人願意去損壞自己的利益。一旦強制去執行,人心就開始潰散。這個也不一定是壞事,只要滿足原則2就能夠很好的建立一個新的次序和新的利益關係,保持組織的良性發展,長久來看是對所有人的利益都有益的,雖然短期內有對某些既得利益者會有損害。
總結一下
架構的切分的導火索是人的負載太重。
架構的切分實際就是對stakeholder的利益進行切分或合併,使得每個stakeholder的權責是對等的,每個stakeholder可以為自己的利益負責。
架構切分的最終結果都會體現在組織架構上,只有這樣才能夠讓架構落地並推進。
架構切分的結果一定是一個樹狀,這也是為什麼會產生分層。層數越多溝通越多,效率越低,分層要越少越好。儘可能變成一顆平衡樹,才能讓整個系統的效率最大化。
架構漫談(五):什麼是軟體
前面通過四篇文章,把什麼是架構,如何做好架構等必要的概念澄清了一下。這些概念對於在各種不同的領域都應該也是有用的,需要讀者自行思考,並應用到自己所在的領域中。在這篇文章開始,我們用同樣的思考,來看看軟體是怎麼回事,以及如何運用架構思維,更好的設計和實現軟體。
馮諾依曼結構,圖靈機,以模擬人為目標
軟體的歷史,實際上可以說是用機器模擬人的歷史。不管大家(包括在這個歷史過程中的參與者)有沒有意識到,我們都有意無意的在計算機上模仿人類的行為。從馮諾依曼結構開始,程式邏輯開始脫離硬體,採用二進位制編碼。加上儲存,配合輸入輸出,一個簡化的大腦就出現了。圖靈機則是模擬大腦的計算,用數學的方式把計算的過程定義了出來,著名的邱奇-圖靈論題:一切直覺上能行可計算的函式都可用圖靈機計算,反之亦然。軟硬體兩者一結合,一個可程式設計的大腦出現了,這也是現在為什麼我們把計算機叫做電腦。在硬體上編寫出的程式,就是軟體,是用來控制硬體的行為的。
成本為王
在初期,軟體使用二進位制編寫的,從硬體到軟體,成本都非常的高。隨著半導體技術的進步,硬體的成本越來越低,效能越來越高,甚至出現了摩爾定律:當價格不變時,積體電路上可容納的元器件數目,約每隔18-24個月增加一倍,效能提升一倍。軟體方面,為了簡化難度,開始採用彙編,進一步出現了類似於人類的語言的高階語言,比如C/C++/Java等,這使得人類可以用類似於人的語言來和計算機溝通。軟體工程師慢慢越來越多,開發軟體的成本也越來越低。計算機就好像是一個只需要電,不需要休息的人,可以無休無止的工作。
人們越來越願意把原來只有人才能做的事情,交給計算機來做。結果就導致軟體越來越豐富,能夠做的事情也越來越多,成本也越來越低。可以這麼說,成本是我們為什麼採用軟體的主要動力,可以節省大量的人員培訓,減少僱員的數目。隨著網際網路的發展,人類社會也開始軟體化了。原來必須實體店來進行售賣的,搬到網際網路上,開店成本更低,並且能夠接觸到更多的人。想象一下,一個門店每天的人流達到百萬級別是很恐怖的,由實體空間大小來決定。但是在網際網路上,訪問量千萬級別都不算什麼。最終的結果就變成,每個人能夠負擔的工作越來越多,成本越來越低。這也是為什麼軟體這麼熱的原因。
軟體扮演的角色
隨著軟體的規模的變大,做好一個軟體也變得越來越難了。早期的程式設計師寫程式,主要是為了幫助自己研究課題。這些程式設計師熟練了之後,提高了自己的生產力,並發現還可以幫助別人寫程式,慢慢軟體就變成了一個獨立的行業。程式從早期由一個人完成,也逐漸變成了由很多不同角色的人共同合作來完成。以下討論的前提,都是基於幫助別人寫程式,多人合作的基礎上的。結論對於單人為自己寫程式也適用。
在沒有軟體之前,每個人幹自己的工作,自行儲存自己的工作結果。人們面對面或者通過電話等溝通,如下圖所示。
有了軟體之後,實際上,我們是把我們日常生活中所做的事情,包括我們自己本人都一起虛擬化到了計算機中。而人則演化成了,通過計算機的輸入輸出裝置,控制計算機中的自己,來完成日常的工作,以及與其他人的溝通。也就是說,軟體一直以來的動力,始終都是來模擬人和這個社會的。比如模擬大氣運動(天氣預報),模擬人類社會(網際網路社交),模擬交易,包括現在正在流行的VR,人工智慧等等。模擬的物件越來越高階,難度越來越大。
不管如何發展,模擬人的所有行為都是一個大的趨勢。也就是說,軟體的主要目的,還是把人類的生活模擬化,提供更低成本,高效率的新的生活。從這個角度來看,軟體主要依賴的還是人類的生活知識。軟體更多的是扮演一個cost center,這也是為什麼會出現很多的軟體代工。
軟體開發的架構演變
軟體工程師是實現這個模擬過程的關鍵人物,他必須先理解人是怎麼在日常生活中完成工作的,才能夠很好的把這些工作在計算機中模擬出來。可是軟體工程師需要學習大量的計算機語言和計算機知識,還需要學習各行各業的專業知識。軟體工程師本身的培養就比較難,同時行業知識也要靠時間的積累,這樣就遠遠超出了軟體工程師的能力了。所以軟體開發就開始有分工了,行業知識和業務的識別,會交給BA,系統的設計會交給架構師,設計的實現交給架構師,實現的檢驗交給測試,還有很多其他角色的配合。為了組織這些角色的工作,還有專案經理。這就把原來一個人的連續工作,拆分成了不同角色的人的連續配合,演化成了不同的軟體開發的模式。然後慢慢演變出專門為別人開發軟體的軟體公司。
軟體架構的出現
如同前面描述的架構的定義,軟體架構的出現也是同樣的。一開始是懵懵懂懂的去寫軟體,後來慢慢的就有意識的去切分,演變成了不同的架構。這個背後的動力也是一樣的,就是提升參與的人的利益,降低成本。導火索也是軟體工程師的任務太重,我們需要把很多工作拆分出來。拆分的原則也是一樣的,如何讓權責一致。同樣,這個拆分也是需要組織架構的調整,來保證架構的落地。具體如何分拆,如何調整,我們將在另外一篇中著重討論。
以上通過簡單的描述計算機和軟體的發展歷史,闡明軟體的本質,其實就是通過把人類的日常工作生活虛擬化,減少成本,提升單個人員的生產力,提升人類自己的利益。軟體工程師的職責在這個浪潮中,不堪重負,自然而然就分拆為不同的角色,形成了一個獨特的架構體系。這一切的背後,仍然是為了提升人類自己的利益,解決人類自己的問題。
架構漫談(六):軟體架構到底是要解決什麼問題?
前一篇文章簡述了什麼是軟體。那麼什麼是軟體架構呢?按照慣例,我們來看看是什麼問題,是誰的問題。
要解決誰的問題?
如前所述,軟體實際上就是把現實生活模擬到計算機中,並且軟體是需要在計算機的硬體中執行起來的。要做到這一點需要解決兩個問題:
一、業務問題
具體的現實生活狀態下,沒有軟體的時候,所解決的問題的主體是誰,解決的是什麼問題,是如何解決,如何運作的?
二、計算機問題
如何把現實生活用軟體來模擬?
模擬出來的軟體,需要哪些硬體設施才能夠滿足要求? 並且當訪問量越來越大的時候,軟體能否支援硬體慢慢長大,效能線性擴充套件?
因為硬體是可能會失效的,軟體如何在硬體失效的情況下,仍然能夠保證可用性,讓使用者能夠不中斷的訪問軟體提供的服務?
怎麼收集軟體產生的資料,為下一階段的工作提供依據?
分別是誰的問題呢?
業務的owner需要提升業務的效率,降低業務的成本,這是動機。這個實際上就是業務的問題,所以一般軟體開發的出發點就在這裡。
是軟體工程師的問題,要解決業務owner把業務虛擬化的問題,並且要解決軟體開發和運營的生命週期的問題。
分別有什麼問題?
業務問題的本質,是業務所服務的物件的利益問題,明白了這個,就很容易搞清業務的概念和組織方式。再次強調一下,有了軟體,可以降低業務的成本,沒有軟體的情況下,業務是一樣跑的。如果只是為了跟風要用軟體,說不定反而提高了成本,這個是採用軟體之前首先要先搞清楚的。我們經常說軟體和技術是業務的enabler,實際就是把原來成本很高的降到到了很低的程度而已,並不是有了什麼新的業務。另外,軟體也不是降低業務成本的唯一方式。
為了能夠讓軟體很好的跑起來,軟體工程師必須理解業務所服務的物件,他們的利益所在,即業務問題。業務面對這些問題是如何分拆解決的? 涉及到了哪些概念? 這些概念分別解決了哪些哪些問題? 我們不能自己按照自己的理解,用自己的一套概念體系來表述。如果這麼做的話,會導致兩個問題:
1)業務無法和我們交流,因為他們無法明白我們所自己建立的概念,所以他們無法確認我們的理解是否正確。
2)我們所表述的東西,並沒有在實際生活中實踐過,我們也不知道這些概念是否能夠解決業務的問題。
軟體工程師還必須要考慮,用什麼樣的硬體把軟體跑起來,怎樣跑得好,跑得快,並且可以隨著業務的流量逐漸的長大?
分析問題
對於2,在有限的時間下,軟體工程師毫無疑問無法一個人去完成這麼多事情,那麼我們需要把所做的事情列出來,進行分析。
一、虛擬化業務需要完成這些事情:
學習業務知識,認識業務所涉及的stakeholders的核心利益述求,以及業務是如何分拆滿足這些利益訴求,並通過怎樣的組織架構完成整個組織的核心利益的,以及業務運作的流程,涉及到哪些概念,有哪些權利和責任等。
通過對業務知識的學習,針對這些概念所對應的權利和責任以及組織架構,對業務進行建模,並把建模的結果用程式語言實現。這是業務的模型,通常是現實生活中利益鬥爭的結果,是非常穩定的。
學習業務所參與的stakeholder是如何和業務打交道,並完成每個人的權利和義務的,並通過程式語言,結合業務模型實現這些打交道的溝通通道。這部分是變化最頻繁的,屬於組合關係。明白了這一點,對後續的實現非常有幫助。
如何把業務執行的結果持久化,並通過合適的手段把持久化後的資料,在合適的時間合適的地點加載出來。這部分和基礎設施有關,變化可能也會比較頻繁。
二、程式碼如何運營,需要完成這些事情:
需要多少硬體裝置來滿足訪問的需求?
程式碼要分成多少個元件部署到哪些硬體裝置上?
這些程式碼如何通過硬體裝置互相連線在一起?
當業務流量增大到超過一臺機器的容量時,軟體能否支援通過部署到新增機器上的方式,擴大對業務的支撐?
當某臺或某些硬體裝置失效時,軟體是否仍然能夠不影響使用者的訪問。
軟體執行產生的資料,能否支援提取出來並加以分析,為下一輪的業務決策提供依據。
三、如果分成不同的角色來完成這些事情,就需要一個組織架構來組織程式碼的編寫和運營,需要做哪些事情:
完成一和二所列的這些事情,需要哪些角色參與?
這些事情基本都需要順序的發生,如何保證資訊在不同角色的傳遞過程中不會有損失? 或者說即使有損失,也能快速糾正?
這些角色之間是如何協調,才能共同完成虛擬化業務的需求?
會生成哪些架構
如果業務足夠簡單,使用者流量夠小,時間要求也不急迫,那麼一個人,一臺機器就夠了,這個時候一般不會去討論架構的問題。當訪問的流量越來越大,機器就會越來越多,程式碼的部署單元就會拆分的越來越多。
同樣就會需要越來越多的人來完成拆分出來的越來越多的部署單元,甚至同一個部署單元也需要分拆為多人合作完成。但是我們需要注意到一點,整個的概念體系,或者說業務的建模不會有任何的變化,還是完成同樣的這些事情。唯一的區別就是量越來越大,超過了單個人和單個機器的容量,不斷地增長。這樣就會導致以下的架構:
當流量越來越大,我們就會發現,軟體所部屬的機器就會開始按照樹狀的結構開始分拆,就會形成硬體的部屬架構。這就是為什麼會形成部署的分層。
為了把業務在軟體中實現並落地,需要前端人員、業務程式碼人員、儲存層等不同技巧的人同時工作,需要切分成程式碼的架構。這就是為什麼會形成程式碼的分層,形成程式碼的架構。當然,當這些角色由一個人來完成的時候,不一定會有程式碼架構,往往會比較亂。
當參與的人員越來越多,就會形成開發體系的組織架構。因為程式碼開發的過程是一個連續的過程,會用流程來把不同的角色串聯起來,這就是軟體工程。
為了完成業務的工作,需要識別出來業務架構和支撐業務的組織架構,以及業務運作的流程。這是被虛擬化的業務架構和組織架構,也需要體現在程式碼中,保持和現實生活中一致。
什麼是軟體架構
這就是軟體比較複雜的地方,涉及到軟體本身的業務體系,和所虛擬的業務體系。根據以上的分析,所生成的架構,究竟那些算是軟體架構呢?
軟體因為流量增大而分拆成不同的執行單元,在不同的機器上部署所形成的架構,屬於軟體架構。
每個執行單元為了讓不同角色的人,比如前端,業務,資料儲存等能夠並行工作,所分成的程式碼架構,也屬於軟體架構。
所以當我們說軟體架構的時候,我們一定要講清楚,究竟說的是部署的架構,還是程式碼的架構。軟體架構的落地,需要軟體的組織架構和流程來保障,離開了這個,軟體架構是一句空話。
另外很多人講,架構是進化出來的。架構實際上是在量不斷的增大,超過了單臺伺服器的容量,逐漸的分拆,同時導致超過單個人員的能力,工作人員不斷的增多,工作內容不斷的分拆形成的。這本身就是架構的意義所在。不管怎麼分拆,所達到的目標沒有任何變化,就是完成業務在計算機中的虛擬化。
架構漫談(七):不要空設架構師這個職位,給他實權
什麼是架構師
在之前的幾篇文章中,經常會提到架構師這個詞。我們已經定義了什麼叫架構,那怎麼定義架構師呢,是不是做架構的就叫架構師了? 沒有這麼簡單,本篇嘗試討論一下這個問題。
架構師的前提條件
如果一個人在工作中,只是致力於完成自己的工作,以做好自己的工作為主要目標,那麼最多隻能成為一個工匠,無法成為一個架構師。因為這個過程解決的還是自己的問題,並沒有時間的壓力,可以隨意什麼時候做完都可以。
當我們所做的工作是處於社會的分工的一環,需要幫助別人解決問題,並且按時解決別人的問題成為我們自己的問題的時候,我們就有了時間壓力,潛意識裡會自然而然的有一種對時間的恐懼。這個恐懼在潛意識裡面會想方設法推動我們採用各種手段,以便及時的完成工作,換取報酬。甚至會加班加點,不擇手段。
如果我們還生活在這個恐懼下面,是不可能成為架構師的。要成為架構師,必須要超越這個恐懼才能夠看清楚,我們要解決的是別人的問題,不是自己完成工作的問題。因為僅僅是完成了自己的工作,也並不一定就解決了別人的問題。如果別人的問題沒有解決——即使我們認為自己的工作完成了——我們的工作實際也沒完成,因為我們工作是否完成,是別人說了算的,不是我們自己。
為什麼會有這個對時間的恐懼和壓力呢?這是因為我們把完成自己的工作當成了我們的最大利益。如果別人的問題沒有真正的解決,必然會覺得付出的報酬不值得,我們的利益實際上是受損失了。這和我們所以為的恰恰相反,因為我們所能得到的工作只會越來越少,別人會越來越不願意依賴於我們。
另一方面也說明,我們對自己所從事的工作,還沒有足夠的自信,我們解決自己的問題還有困難,才會這麼在意,並恐懼。如果我們把完成別人工作當成自己的最大利益,這個對時間的恐懼自然就會消失,這個時候就自然而然的開竅了,就知道怎麼去發現問題了。只有做到這一點,才能在自己所服務的領域建立起自信,成為一個合格的架構師。
其實剛開始一般是硬著頭皮去克服對時間的恐懼和壓力的,一點自信都沒有。但只要做成功了一次(只要真的捨得這麼去做了,想不成功也很難!),自信就開始慢慢建立起來了,這個時候就是我們開始慢慢變成架構師的時候。大家就當著上當一回,試試看。
如何發現“是誰的問題”
當我們真正專注於別人的問題的時候,我們自己的理想,抱負,對技術的追求都不算什麼了。這些理想,抱負,對技術的最求,不就是要達到自己的利益嗎? 只有幫助別人解決了問題,這些理想,抱負,對技術的追求才可能實現,否則這些理想,抱負,對技術的追求有什麼意義,能得到什麼利益?
這個時候就會真正的開始思考,別人究竟有什麼問題。其實也很簡單,和我們自己面臨的問題一樣,別人的問題也都是如何獲取更好更多的利益。我們自己想明白了這一點,自然也就能想明白別人的問題。這個時候就能夠問出正確的問題:如果問題不解決,究竟誰會有利益的損失? 如果問題解決了,究竟誰會有收益,誰的收益最大? 回答了這兩個問題就找到了問題的主體。只回答一個是沒有用的,因為很多時候這個世界的事情,權責是不對等的。明白了這兩個問題,我們只要讓事情權責對等起來,讓每個人為自己的權利產生的結果負有義務,大部分時候我們自己根本就不需要做什麼,問題就都解決了。這就是最高明的架構師。
架構師的權利和義務
架構師是要去平衡別人的利益,甚至會調整別人的利益的。一旦架構師是全心全意的為別人的利益服務,自然而然的架構師就擁有了強有力的影響力,肯定會是一個leader。但是隻是民意上的leader是沒有用的,不能完全發揮架構師的能量。
架構師必須是一個組織的領導人,有權利調動這個組織的架構,才能夠更好的發揮架構師的作用,更好的把利益的調整落到實處。所以很多公司設了很多架構師的職位,但是並不具備調動組織架構的權利,那麼這個架構師的職位一定是形同虛設。架構師只能夠通過建立某些流程來行使架構師的權利,比如強制架構review,反而會造成很多內部不必要的衝突,最終都會導致這些流程流於形式,得不償失。相信很多人都已經經歷過這些,但似乎很少有人回去探討這是為什麼。
反過來,具備架構師能力的組織領導人,一定是一個很好的領導,這個組織一定是很健康向上的,因為每個人的權利和義務就是比較均等的。並且這類領導對於組織成員權利和義務的對等狀況會非常的敏感,會及時的調整組織架構,在問題發生之前就解決了。這樣這個組織就會具備更好的抗壓能力,能夠更好的為這個組織的客戶服務,這個組織的成員內心一定都是比較平衡的,每個人的能力都能夠得到比較好的發展。當然讀者可能又會說,這不是管理學的東西嗎? 是的,但也是架構的問題。所有架構的核心就是組織架構。或者也可以這樣說,一個合格的組織領導人,一定必須是一個合格的架構師。
架構師的義務似乎不用說了,大家提的要求可能比我提的都高 —— 當然是發現問題並且解決問題。架構師必須能夠超越對時間的恐懼 —— 也就是說必須具備了一定程度的自信,哪怕是裝的,去真正的發現問題的主體,識別真正的問題,並把這個行為變成為自己面對問題的第一反應。架構師還必須要明白,所給出的解決方案 —— 架構的分拆、合併方案,只有讓問題的主體的權責對等,才能夠真正的解決別人的問題。一般明白了問題的主體,以及主體的利益所在,做到這一點也沒有問題。
架構師和技術
很多人會問,特別是做軟體行業的,架構師是不是需要學習技術,甚至是學習語言? 如果一個架構師還有這個困擾——就如問這個問題的人,說明目前還不具備做架構師的能力,或者說還不具備對自己領域——哪怕是技術領域——的自信,更別談業務領域了。
因為技術和語言,都是用來識別和解決所服務的主體的權責,保護並提升所服務的主體的權利的。特別對於軟體領域來說,必須明白軟體本身是怎麼回事,解決什麼問題,還要解決軟體所服務的物件的領域本身是怎麼回事,解決什麼問題,這就要求更高了。語言和技術應該是隨手拈來才對,對於架構師這些都是工具。學習技術和語言,如果明白了這些技術和語言要解決的是誰的問題,什麼問題,學起來是非常快,非常容易的。
同樣,採用哪個技術或者語言,只要某個技術或語言所解決的問題的主體,以及所解決的問題,和自己所面對的問題的主體和這個主體要解決的問題,這兩者是匹配的,那麼這個方案的成本是最低的,所採用的技術或者語言就是靠譜的。沒有趁手的工具或語言的情況下,自己設計一個也不難,因為很清楚自己要什麼。要不要自己做,無非是一個成本問題,也就是利益問題。並且從這個思路下去,選擇的工具和語言肯定都是最簡單的,成本是最低的。因為架構畢竟解決的還是人的利益問題,成本越低越好,這個成本當然是長期總體成本,不是眼前的短期成本。
架構漫談(八):從架構的角度看如何寫好程式碼
在第六篇文章中,我們得出一個結論,軟體架構實際上包括了:程式碼架構,以及承載程式碼執行的硬體部署架構。實際上,硬體部署架構最終還是由程式碼的架構來決定。因為程式碼架構不合理,是無法把一個執行單元分拆出多個來的,那麼硬體架構能分拆的就非常的有限,整個系統最終很難長的更大。
所以我們經常會聽說,重寫程式碼,推翻原有架構,重新設計等等說法,來說明架構的進化。這實際上就是當初為了完成任務,沒有充分思考所帶來的後果。這也並不是架構進化的事情,而是個人對問題領域的逐漸深入理解的過程。所以有必要再討論一下,程式碼的架構應該是怎樣的。
本文會在之前幾篇文章的基礎上,進一步探討如何把架構的思考進行落地,細化到我們程式碼的實踐當中,儘量不要讓程式碼成為系統長大的瓶頸,降低架構分拆的成本。
在前面我們提到,軟體實際上是對現實生活的模擬,虛擬化。這是一個非常重要的前提,直接決定了我們的程式碼應該分為幾部分。結合每個部署單元所承擔的責任,可以明確的拆分為兩個不同的責任:
表達業務邏輯的程式碼。很多人把這部分叫做Domain Logic,或者叫Domain Model。這部分實際是來源於生活的,必須保持和現實生活中的切分一致,並非人為的抽象而成。
對使用者提供訪問並儲存業務邏輯執行結果的程式碼。計算機的狀態儲存有一個缺陷,本機保留業務執行結果有很大的問題,一般都在外儲存裝置上儲存,也便於擴充套件。
所以單個部署單元的程式碼可以分為兩個部分,如下圖所示:
從這個圖中可以看出,軟體程式碼的相關利益人為執行時的訪問人員和儲存裝置。而service的程式碼是最複雜的,需要服務於三方,程式碼人員的負擔是最重的。為了把這三方的變化對service的影響降到最低,對於service還必須進一步的分拆為三個部分,讓每一個部分都能夠獨立的變化,這樣這三方的變化就不會產生連鎖響應,降低成本。如下圖所示:
這樣,就劃分成了幾個責任:
Service就專注於user的需求,並組合Glue Code提供的服務完成需求。
Glue Code專注於組合business的呼叫,管理Business裡面物件的生命週期,並且通過Repository儲存或載入Business的狀態
Business專注於實現業務的核心模型。
Repository專注於資料的儲存,並和儲存裝置一一對應。
大家注意看,還是樹形架構。並且左側的主要需要計算機的相關理論知識,並且要直接面對使用者的需求。右側的更多的需要面對業務的核心。只要這幾塊的開發人員互相商量好了介面定義,這幾個部分的開發就可以並行的進行,極大的提升開發的效率,縮短開發的時間。要做好這幾部分,還需要注意,邏輯只允許存在於Business中,Service、Glue Code、Repository都不允許存在業務邏輯。為什麼呢?首先我們來看看什麼叫業務邏輯。
什麼叫業務邏輯?
首先這個定義的前提是指軟體程式碼中的邏輯,不是現實生活中的邏輯。在軟體程式碼中,不需縮排和計算的順序呼叫,包括縮排的程式碼目的是catch exception的,都不算邏輯,除此以外都是邏輯。以下用嚴格的順序呼叫來指代這種程式碼。因為順序呼叫是計算機的特性,由編譯器來決定的,當然最本質的是因為我們計算的基礎都是圖靈機。在現實生活中,順序呼叫也是邏輯,大家不要和我們這裡說的業務邏輯相混淆。
為什麼說除了Business程式碼中有邏輯以外,其他地方不能有邏輯呢? 我們每個部分分別分析:
如果service裡面不是嚴格的順序呼叫,有很多分支,那麼說明這個service做了兩件或者兩件以上的事情。必須把這個service分拆,確保每個service只做一件事情。因為如果不這麼分拆的話,一旦這個service中的某各部分發生變動,其他的部分的執行必定會受影響。而確定到底有哪些影響的溝通成本非常高,其他相關利益方沒有動力去配合,我們往往不會投入精力仔細評估。最後上線會出很多不可預料的問題,最終會導致損失使用者的利益,並且肯定會導致返工,損壞自己的利益。如果是有計算的邏輯的話,比如受益計算,訂單金額計算等,那麼這部分應該是Business程式碼需要完成的,不能交給service程式碼來實現。
Glue Code裡面如果不是嚴格的順序呼叫,同理會和service一樣遇到同樣的問題。
Repository裡面如果不是嚴格的順序呼叫,包括儲存訪問的程式碼裡面(比如SQL),會導致邏輯進入到儲存裝置中。儲存裝置的主要目的是拿來儲存的,一旦變成了邏輯計算的主體,就會導致儲存裝置無法通過增加機器的方式橫向擴充套件長大。這個時候就沒有架構了,只能換效能更好的機器,這個叫scale up。只有scale out才能算架構。
以上都會導致架構無法快速的橫向擴充套件和分拆,並且增加了修改的成本,這些是不符合開發人員以及業務的利益的。
這麼做的好處有哪些呢?
Service、Glue Cod