1、什麼是架構 編程
關於什麼是架構,業界歷來沒有一個統一的定義。Martin Fowler在《企業應用架構模式》中也沒有對其給出定義,只是提到可以統一的內容有兩點:設計模式
最高層次的系統分解;緩存
系統中不易改變的決定。安全
《軟件架構設計》一書則將架構定義總結爲組成派和決策派:服務器
組成派:架構=組件+交互:軟件系統的架構將系統描述爲計算組件及組件之間的交互。網絡
決策派:架構=重要決策集:軟件架構是在一些重要方面所做出的決策的集合。數據結構
而架構的概念最初來源於建築,所以,我想從建築的角度去思考這個問題。Wikipedia中,對架構,即Architecture的定義以下:架構
Architecture is both the process and the product of planning, designing, and constructing buildings and other physical structures.併發
簡單翻譯就是:架構是規劃、設計和構建建築物或其餘物理構築物的過程和結果。框架
從上面的定義中可知,首先,架構的最終目標是爲了產出建築物或其餘物理構築物,構築物能夠只是一套房子,也能夠是一棟樓盤,抑或是一個小區、商業區,甚至是一個城市。構築物越大,其架構必然也越複雜。
其次,產出建築物以前須要通過三個階段:規劃(planning)、設計(designing)和構建(constructing)。這三個階段其實也是架構的核心了。好比,開發商要建一個住宅小區,首先確定要對該小區有一個總體的規劃吧:小區的建設選址、建設的規模、建設的內容、投資估算、建設週期等等。接着,就要對小區的各方面進行設計了,最高層次的應該是小區的整體佈局設計,拆分開的話就是各樓盤的設計、綠化的設計、各類配套設施的設計等等,再細化下去就是各類戶型的設計、樓盤內和小區內各類走道的設計等等。最後,構建階段也就是施工階段了,是將以前全部的想法轉爲實際的建築物的階段。即架構包含了以上的過程和結果。
那麼,若是將建築物換成了軟件,那就變成對軟件架構的定義了:軟件架構是規劃、設計和構建軟件的過程和結果。
相應地,軟件架構的最終目標就是爲了產出軟件,能夠是一個App,也能夠是一個平臺,如SaaS、PaaS、BaaS等等,甚至還能夠是智慧城市這樣龐大的生態系統,地球人都知道,越龐大複雜的系統,架構越難。規劃階段更多考慮的是軟件的需求,包括業務上功能性需求和技術上的非功能性需求,如可靠性、可擴展性、可維護性等;此階段的架構通常爲系統架構。設計階段的工做更多的就是拆分細化,以知足各類需求;此階段的架構通常爲邏輯架構。構建階段主要就是對軟件的實現和部署了;此階段的架構通常爲物理架構。
2、架構規劃
架構規劃作什麼呢?我以爲主要是規劃好下個階段架構設計的邊界。而影響架構邊界的,其實就是需求。需求造成了對架構的約束條件,從而也對架構設計造成了邊界。能夠分爲三大類:商業需求、功能需求和質量需求。
(一)商業需求
商業需求是最高層次的需求,對其含義,我比較贊同溫昱在《軟件架構設計》中提到的解釋:它關注從客戶羣、企業現狀、將來發展、預算、立項、開發、運營、維護在內的整個軟件生命週期涉及的商業因素,包括了商業層面的目標、指望和限制等。商業需求通常對架構的影響比較大,對架構產生限制的商業因素也比較多,在此列舉一些比較常見的:
上市時間:上市時間限定了系統從設計、開發、測試到上市的時間邊界。以前我跟進過一個垂直於大學生市場的應用,上市時間就要求在新生入學前,否則就會錯過推廣的最佳時期,預留給開發的時間只有兩個月。所以,咱們只好大部分重用前個項目的元素,包括重用服務端的一些模塊,還包括客戶端的架構和界面。固然,通常狀況下,預留給開發的時間不會這麼短,但也不會特別長。架構師須要根據時間長短,平衡各方面需求,作好架構選型。
成本預算:成本預算就限定了能使用的資源邊界。不一樣架構的開發成本確定不一樣,要知足更多功能需求和更多質量需求的架構成本也更高,在預算有限的狀況下,只能權衡各類需求,優先知足重要程度高的需求。
人力現狀:100人的開發團隊和10人的開發團隊,軟件的架構會有很大不一樣。另外,開發團隊人員所掌握的技術也會對架構選型有影響。例如,團隊裏尚未人會用React Native,那現階段就不適合選擇React Native做爲App架構的技術基礎。
與外圍系統的集成:當須要與外圍系統集成時,須要認真考慮集成方法,尤爲是外圍系統比較老的時候,集成難度可能更高。另外,外圍系統的不可控因素通常也比較多,所以,對架構處理這些不可控風險的要求相對也高。
開放性:封閉的私有系統和開放式系統對架構的要求也不一樣,一個系統若是選擇了開放,那對架構的質量要求更高,對安全性、擴展性、性能等質量屬性都應該比封閉時高。
目標市場:目標用戶10萬、100萬、1000萬,不一樣級別的目標市場,架構也是大有不一樣。另外,大衆市場和垂直的專門市場,架構也一樣有區別,較大的專門市場通常都採用產品線的規劃方案。
多端支持:如今移動端廣泛支持Android、iOS、Wechat,管理端一般則支持PC Web,若是管理端也要支持Android、iOS、Wechat,或者移動端和管理端還要再支持WindowsPhone、黑莓,甚至再支持VR,則須要投入更多時間和人力,架構上相應也須要作出調整。
指望的系統生存期:從主觀上說,誰都但願本身的系統能夠生存好久,但生存期越長,意味着系統的可修改性、可擴展性、可移植性等須要更高。可是,受上市時間、成本預算等因素的制約,再加上軟件自己的變化快,因此,客觀上,通常也不會指望其生存期太長。當系統不能知足漸增的需求時,基本經過重構來解決。
階段性計劃:每個大平臺系統廣泛都是分階段完成的,所以,前期階段的架構設計時就須要考慮好重用性、擴展性、伸縮性、移植性等特性。但由於每一個階段通過市場驗證後,需求有可能會變化,因此又不能過分設計,不然就會形成設計浪費,還可能加大了後續階段架構調整的難度。
國際化:若是走國際化路線,那架構上就要考慮好對多國語言的支持。
競爭對手:產品要比競爭對手優秀,那就要在一些關鍵的功能或質量上超越對方,也意味着在這些方面的架構須要投入更多。
法律法規:好比,對某些關鍵字要進行過濾屏蔽,這是天朝獨有的,你們懂的。
商業需求多種多樣,有些需求還可能會相互矛盾,好比,上市時間和成本預算就會和指望的系統生存期可能產生矛盾,指望的生存期越長其成本就會越高,須要投入的時間就會越多,那麼,就有可能拖延上市時間。所以,作架構規劃時,必須梳理清楚哪些需求是可以被知足的,能被知足的程度如何,須要在各個需求間權衡利弊。另外,商業需求由於是最高層次的需求,所以,相對於功能需求和質量需求,其優先級通常也比較高。
(二)功能需求
功能需求描述了系統應該提供的服務,包括爲用戶提供的服務,也包括爲其餘系統提供的服務。而架構主要就是爲功能服務的,而功能需求基本與具體的業務相關。所以,要作好功能需求這塊的架構,就必須對該業務領域足夠了解,這樣才能更好地抽象建模。對功能需求的架構規劃,主要就是創建業務領域模型。領域模型定下來後,下個階段的設計必須與領域模型保持一致。
而對功能需求進行領域建模以前,還需先梳理下需求的優先級。由於受商業需求的影響,功能需求也須要權衡。好比,上市時間緊、成本預算低、人力資源也不是很充足的狀況下,功能需求只能少不能多。而須要與外圍系統集成的時候,也意味着這部分功能不須要本身實現了;可是,若是外圍系統沒法徹底知足需求時,則還須要本身再實現缺失的需求。所以,現階段須要知足哪些功能需求?須要知足到什麼程度?這兩個問題肯定了以後才能更有效地進行領域建模。
領域建模主要就是要分析清楚每一個領域模型和模型之間的關係。仍是直接用一個例子來講明吧。假設如今要作一個支持O2O(Online To Offline)的電商平臺,如下是通過梳理後的幾個關鍵的功能需求:
商家能夠在平臺發佈商品,能夠是實體類商品,也能夠是服務類商品。
實體類商品支持快遞,服務類商品只能到商家門店兌換消費。
用戶購買實體類商品時需提供收貨信息。
用戶購買每一個商品時對應生成一個訂單。
用戶購買的是實體類商品時,能夠查看商品的物流信息。
用戶購買的是服務類商品時,能夠用訂單的兌換碼到商家門店兌換消費。
根據以上需求,能夠初步獲得相關的領域概念有:商家、商品、實體類商品、服務類商品、物流信息、門店、用戶、收貨信息、訂單、兌換信息。理清這些領域概念之間的關係以後,能夠獲得相似於下面的領域模型視圖:
固然,這只是一個很小的例子,實際上的領域模型會比這個例子複雜得多。領域模型肯定以後,系統中有多少業務領域、各領域概念之間的關係如何就一清二楚了。
(三)質量需求
質量需求是三類需求中,需求層次最低的,但倒是大部分架構師最關注的。縱覽那麼多架構技術,就會發現,大部分都是爲了解決某個或某些質量屬性優化的問題。
質量屬性常見的有如下這些:
性能(Performance):性能無疑是一個很是重要的特性,尤爲在計算資源有限的狀況下。但也無需過度追求高性能,從而犧牲其餘更重要的特性。
安全性(Security):安全性通常會和性能相互制約,最明顯的例子就是HTTPS,使用HTTPS提升了安全性,但性能就會有所犧牲。很難作到既知足高安全又高性能,所以須要根據具體需求平衡兩方面的特性。
可用性(Availability):也有人稱爲有效性,通常定義爲:可用性 = 系統正常工做時間 / (系統正常工做時間 + 故障維修時間)。此定義就說明了可用性與系統故障有關,故障率高,可用性就低,故障率低,可用性才高。另外,高可用性還說明了系統對故障維修的時間也很短。
易用性(Usability):易用性很容易和可用性混淆,可用性關注的是系統長時間無端障運行的能力,而易用性關注的則是系統易於使用的能力。
魯棒性(Robustness):也稱爲健壯性、容錯性,是指系統在出現了用戶非法操做、或軟硬件的缺陷致使的異常狀況下,系統依然可以正常運行的能力。好比說,系統在輸入錯誤、磁盤故障、網絡過載或有意攻擊狀況下,可否不死機、不崩潰,就是該軟件的魯棒性。
可伸縮性(Scalability):可伸縮性是指當用戶量和數據量增長時,系統維持高服務質量的能力。好比,當併發量爲1W時,系統響應時間爲1秒,那若是併發量增長到100W時,只要經過增長服務器數量,而無需對代碼進行修改便可達到系統響應時間依然爲1秒,就說明該系統的可伸縮性高。
互操做性(Interoperability):互操做性反映了本系統與其餘系統交換數據和服務的難易程度。
可擴展性(Extensibility):也稱爲靈活性,反映了系統應對變化的能力。在軟件開發過程當中,需求變動是常有的事,尤爲在移動互聯網時代,變化是很是頻繁的,也所以,可擴展性是移動互聯網產品重點考慮的質量需求。
可理解性(Understandability):可理解性是指開發人員經過源代碼和相關文檔,瞭解程序功能、結構和運行方式的難易程度。聽從好的開發規範通常均可以提升可理解性。另外,單一職責原則運用得好,也能大大提升可理解性,所謂「簡單就是美」,簡單才容易理解。
可測試性(Testability):簡單點說,可測試性就是測試和診斷軟件錯誤的難易程度。好比進行單元測試的難易程度。若是程序包含了複雜的處理邏輯、數據結構、模塊關係,可測試性的設計更顯得尤其重要。
可複用性(Reusability):可重用性代表了一個軟件組件能夠在其餘程序中使用的難易程度。通常須要將一個組件抽離成通用性的組件時,對可複用性的要求就會比較高。
可移植性(Portability):可移植性代表了將軟件系統從一個運行環境轉移到另外一個不一樣的運行環境的難易程度。
可維護性(Maintainability):可維護性是指理解、改正、改動、改進軟件的難易程度。我以爲,可維護性是保證一個軟件系統可以長期生存的最重要的特性,沒有之一。對一個可維護性差的系統,長此以往,不斷變得牽一髮而動全身,變得不可維護,慢慢只能宣佈滅亡。
理想狀況下,誰都但願全部屬性都是高質量的,但誰都清楚這是不可能的事。要提升更多質量屬性,實現的難度更大,須要付出的成本更高。並且,不一樣質量屬性之間還存在制約關係,好比,提升安全性,通常就會減低性能;提升了性能,還可能減低了可維護性。所以,在實際作架構規劃時,必須根據具體需求在各質量屬性間權衡優先級。
3、架構思惟
這裏說的架構思惟是指進行架構設計時最高層級的思考方式,好比:面向過程、面向對象、面向切面、面向服務等。
一、面向過程(Procedure Oriented)
面向過程的設計思路就是將問題分解成一個個步驟,按照步驟一步步執行以後,問題就解決了。每個步驟就是一個子過程,也能夠稱爲一個模塊,子過程還能夠繼續拆分紅更多更細的子過程。所以,面向過程的設計核心就是過程分析、功能分解,通常採用自頂向下、逐步求精的分解方式。一個大的程序能夠分解成多個子程序,子程序再分解成多個大模塊,大模塊再分解成多個小模塊,最終分解成一個個函數。
在此我想借用一個象棋對戰的例子,例子來源於一篇很老的文章:架構師之路(4)---詳解面向對象。如下是採用面向過程的設計思路分解的對戰流程圖:
將以上每一個流程分別用函數實現,問題就解決了。
面向過程的優勢主要有兩個:一是流程清晰簡單;二是性能比較高。尤爲是性能,這也是爲何至今不少單片機開發、驅動程序開發、或其餘與硬件相關的系統開發等對性能要求很高的軟硬件程序依然在用面向過程的方式進行設計和開發。
面向過程的缺點也很明顯:一是主程序過重,主程序與模塊承擔的任務不均衡;二是函數不易擴展,致使其可擴展性、可複用性、可維護性相對都比較差;三是上下層級模塊之間的聯繫太緊密,耦合高,因此模塊也難以複用。
二、面向對象(Object Oriented)
面向過程的思路是「怎麼作」,關注於實現細節;而面向對象的思路是「誰來作」,關注於抽象的對象。對象的封裝、繼承和多態等特性,讓咱們以更接近現實世界的方式來思考程序設計。面向對象相比面向過程容易實現更好的分離,相應地可擴展性、可複用性、可維護性也會比較高,但同時會犧牲掉一些性能。不過,也由於硬件發展迅猛,因此犧牲的那點性能也不算什麼了。
面向對象設計的難點在於抽象,從問題域中抽象出一個個對象,並找出它們之間的關係。好在有SOLID原則和一大堆設計模式指導咱們如何更好地設計。也有領域驅動設計的方法論指導咱們怎麼進行領域建模。
仍是象棋對戰的例子,用面向對象的設計思路,能夠抽象出如下三種對象:
棋手:負責行棋,紅黑兩方行爲一致。
棋盤:負責繪製棋盤畫面。
裁判:負責斷定吃子、犯規和輸贏等。
三者關係以下圖:
棋手對象行棋後,棋盤對象根據棋子佈局的變化刷新棋盤畫面,裁判對象則對棋局進行斷定。
三、面向切面(Aspect Oriented)
面向切面,也就是AOP,是對面向對象的一種擴展,爲了彌補面向對象的侷限性。面向對象設計主要是對業務領域進行抽象封裝,但對於業務領域以外的內容,好比日誌記錄、權限檢查、事務支持等,在沒有AOP以前,只能將實現這些功能的代碼散佈在全部對象層次中,但這些代碼與所散佈的對象的核心業務功能是沒任何關係的。這種作法也致使了大量重複的代碼,並且難以複用。AOP就是爲了解決這種問題而產生的,將這些與業務領域無關的部分分離出來,以橫切面的方式注入系統,從而減小重複代碼、減低耦合度、加強擴展性和維護性。
將日誌記錄、權限檢查、事務支持等等使用橫切技術分別獨立成一個個服務模塊,這些模塊也稱爲「橫切面」,這樣就能夠將這些與業務無關的服務從業務核心中解耦出來,就能夠將系統劃分爲兩部分:業務核心和通用服務。業務核心依然採用面向對象的思路去設計,而通用服務則能夠採用面向切面的思想來實現。
Spring就大量使用了AOP技術,OkHttp的Interceptor也是AOP設計的一種實現。不少場景均可以使用AOP的思想去設計,好比添加統一的Http Request Header,添加統一的登陸驗證,添加統一的緩存,添加統一的錯誤處理,等等,只要是通用的功能點基本均可以使用AOP的思想去設計和實現。
四、面向服務(Service Oriented)
無論是SOA仍是如今流行的微服務架構,都是採用面向服務的思惟方式。說到面向服務,須要先了解一個概念:Monolith,也稱爲單體架構。在沒有SOA思想以前,軟件系統將全部功能整合成一個獨立的軟件包,而後部署在單一的平臺上。好比,在J2EE平臺,一個軟件系統最終會打成一個包含全部功能的WAR包,而後部署到Web容器中。若要擴展的話,則經過複製這個WAR包部署到多個Web容器來實現。這種方式,若是程序須要改動,無論多麼微小的改動,都須要從新打包個新的WAR包,並替換掉全部Web容器的舊WAR包。
面向服務的架構思想則是,將系統的不一樣功能分離成一個個單獨的應用程序或組件,統稱爲服務,不一樣服務部署在不一樣容器中,不一樣服務之間經過一些輕量級的交互機制來通訊,如HTTP,RPC等。這樣,相比單體架構,功能服務之間明顯是鬆耦合的,擴展也會靈活不少。並且,不一樣服務還能夠用不一樣編程語言實現,部署到不一樣平臺。
無論是面向過程,面向對象,面向切面,仍是面向服務,最本質的區別仍是在於看問題的角度不一樣。而在實際應用中,也不會只使用一種架構思惟,而是綜合考慮的,系統的不一樣方面或不一樣層級可能會用不一樣的架構思惟去思考。好比,一個龐大的複雜系統,總體上可能用面向服務的架構思惟去拆解各類服務,業務核心方面的服務可能再用面向對象的架構思惟進行建模,通用功能服務仍是用面向切面的架構思惟來設計,事務流程固然是採用面向過程的架構思惟最直觀。
4、架構原則
架構思惟從面向過程,到如今的面向服務,之後也不知道還會出現什麼新的思惟方式。但不管是何種思惟方式,都存在一些共通性的架構原則,能夠指導咱們如何設計出一個合適的架構。從另外一方面來講,架構設計,無論是面向過程、面向對象、面向切面,仍是面向服務,無一例外,主要都是在對複雜的系統進行分解。那麼,相應地,就須要思考三個問題:分解爲哪些?如何分解?分解到什麼程度?相對應地,有三個重要原則能夠分別爲解答這三個問題提供指引。
一、關注點分離原則
關注點分離原則主要就是爲了解決將複雜系統分解爲哪些部分的問題,分解出來的部分就是關注點。過程、對象、切面、服務,只是分解的角度(也是關注點)不一樣而已。將複雜的問題根據不一樣的關注點分解爲多個相對簡單的問題,再對每一個簡單的問題進行分別處理,這就是關注點分離。分離以後,各個關注點相對獨立,每一個關注點的變化基本不會影響到其餘的關注點,即便須要改變,改變的部分也很小。須要擴展時,影響也將會最小化。
關注點分離,最難的在於如何識別出有哪些關注點。要識別出有哪些關注點,須要將複雜系統不一樣的方方面面抽象成一個個具備清晰明確的邊界的概念模型,或爲「對象」,或爲「組件」,或「切面」,或「服務」,以將複雜問題分解爲一個個相對簡單的問題。
從不一樣維度,能夠有不一樣的分離方案。除了上面提到的面向過程、面向對象、面向切面、面向服務等思惟角度以外,還有以下圖所示的其餘幾種不一樣維度,該圖引自《軟件架構設計》一書中的【2.1.1 關注點分離之道】一節:
上圖分別從功能職責、通用性、大小粒度的不一樣維度進行分離。從職責維度進行分離,就能夠分爲三層架構:展示層、業務層、數據層,相應的關注點就是:數據展現、數據加工、數據管理。另外,數據層還能夠再分離爲網絡層和緩存層。從通用性維度來看,就能夠分離出技術通用部分、領域通用部分、特定應用部分。通常,使用框架技術就能夠用於分離各類不一樣的通用部分。從大小粒度的維度考慮,無非就是將複雜系統分離爲各個子系統,再分離爲不一樣模塊,再細分到不一樣類。
在實際應用中,並不會只採用一種維度,而是多種維度綜合考慮,不一樣部分採用不一樣維度的分離方案。好比,也許,總體上按職責分離爲多層架構,而後,在某些層級根據大小粒度再進行分離,例如將業務層按照不一樣業務模塊進行分離。另外,也會將不一樣的通用部分進行分離,例如可將技術通用部分的日誌記錄、領域通用部分的權限檢查分別分離出來。
二、高內聚低耦合原則
系統應該如何分解?或者說關注點應該如何分離?高內聚低耦合原則就能夠爲該問題提供設計指引。
內聚是指模塊內部的功能和元素之間的緊密程度,而耦合則是指模塊與模塊之間的關聯程度。
內聚可分爲好多種:功能內聚、順序內聚、通訊內聚、過程內聚、時間內聚、邏輯內聚、偶然內聚。功能內聚是最強最好的內聚,模塊內各元素共同協做完成一個單一的功能,這些元素緊密聯繫、缺一不可。順序內聚則是指,模塊中各個處理元素和同一個功能密切相關,並且這些處理必須順序執行,一般前一個處理元素的輸出時後一個處理元素的輸入。順序內聚的內聚度也比較高,但相比功能內聚,缺點就是可維護性相對差些。偶然內聚則是最弱的內聚,模塊內的各元素之間沒有任何聯繫,只是偶然地被湊到一塊兒。
耦合也分爲好多種:非直接耦合、數據耦合、標記耦合、控制耦合、外部耦合、公共耦合、內容耦合。非直接耦合表示兩個模塊直接沒有直接關係,它們之間的聯繫徹底是經過主模塊的控制和調用來實現的,其耦合度是最弱的,模塊獨立性最強。數據耦合表示調用模塊和被調用模塊之間只傳遞簡單的數據項參數,至關於高級語言中的值傳遞。標記耦合也稱爲特徵耦合,表示調用模塊和被調用模塊之間傳遞的不是簡單數據,而是數據結構,像高級語言中的數據名、記錄名和文件名等數據結果,這些名字即爲標記,其實傳遞的是地址。控制耦合則表示模塊之間傳遞的不是數據信息,而是控制信息例如標誌、開關等,一個模塊控制了另外一個模塊的功能。外部耦合則是指一組模塊都訪問同一全局簡單變量,並且不經過參數表傳遞該全局變量的信息。內容耦合則是一個模塊直接訪問另外一模塊的內容,這是最強的耦合。
高內聚的設計原則是說:一個模塊只完成一個單一的功能,儘量使模塊達到功能內聚。
低耦合的設計原則是說:若模塊間必須存在耦合,應儘可能使用數據耦合,少用控制耦合,慎用或有控制地使用公共耦合,並限制公共耦合的範圍,儘可能避免內容耦合。
三、適度設計
適度設計原則關注的就是系統分解到什麼程度的問題。適度設計就是指設計不要過分,也不要不足。那麼,怎樣纔算設計過分?怎樣纔算設計不足?一句話,設計過分就是想太多,設計不足就是想太少。感受好虛,是吧?我也這麼以爲。由於,如何判斷一個設計是否過分或不足,並無標準的可量化指標。所以,設計是否適度,更多在於主觀的判斷。而如何避免設計過分或不足,更多的也在於我的經驗積累所造成的直覺。
設計不足相對還比較容易判斷,致使設計不足的緣由主要有兩個:一是由於新手的設計經驗不足而致使;二是由於一味追求快速實現產品功能而跳過或大幅度減小了設計而致使。
也有些設計過分比較明顯的例子,好比Uncle Bob提出的Clean架構,每一個關注點都有着清晰明確的邊界,架構真的很清晰,可維護性、可測試性都很是不錯,高內聚低耦合。可是,若是將其應用到一個只有兩三個開發人員的小團隊的小項目中,就會明顯發現代碼量大並且複雜,每須要添加一個小功能,卻須要編寫大量代碼。這對一個小團隊小項目來講,明顯不適合。Clean架構比較適用於人員較多的團隊,和中大型項目。
所以,判斷設計是否適度,不能脫離團隊和項目的現狀。另外,還有其餘現狀因素,包括各類商業需求、功能需求和質量需求。大部分狀況下,造成過分設計的緣由在於:一是過多地考慮了將來可能發生的變化;二是爲了追求設計而設計。適度設計,首先應該着眼於當下,當下的需求、當下的開發成本、當下的人員和項目現狀;其次纔是適當考慮如何應對將來的變化。對於將來的變化,也不是任何可能都要考慮,只需考慮在可預見的將來裏有很是大的概率會發生的變化便可,這個很是大的概率能夠達到90%以上。好比,已經肯定要實現的需求,只是由於優先級問題而稍微延後;好比,已經肯定的人員擴充計劃;好比,雙11要搞活動,交易量將會激增;等等。
也就是說,適度設計的原則,能夠總結爲:設計應該優先知足當前肯定的需求,再知足可預見將來裏幾乎能夠肯定會發生的需求。只知足當前需求而不考慮將來,就容易致使設計不足;而過多地考慮將來可能發生的需求,就容易致使設計過分。所以,適度設計須要在當前需求和將來需求之間作好平衡,而我以爲只考慮當前需求和將來幾乎肯定會發生的需求是最好的平衡點。
參考:https://blog.csdn.net/bestlove12345/article/details/51803053