看過武俠小説或電影的,或許都在其中悟出過一個道理,從高手成為絕頂高手,或許只在一線之間。而正是這小小的一步,卻是差之毫釐,失之千里。在編程世界裏,同樣是這個道理。看到很多編程的小夥伴都曾困惑,感覺自己已經學習了很多框架,也相對掌握了幾門計算機編程語言,卻感覺自己的編程思維與能力,達到了瓶頸,不知該如何進行自我突破。那麼我的建議是,我們應該從關注軟件框架的高度,上升到關注軟件設計模式的高度。
軟件框架VS軟件架構設計模式:
還是借用武俠小説中的例子,普通高手練的是劍招,絕頂高手練的是劍氣,而武功的最高境界便是無招勝有招,無形勝有形。在編程中的道理也是如此,軟件框架就是具體的招式,軟件設計模式就是一種理論指導,是指導實踐的方法論,是無形的東西。而這才是真正解決實際問題時,以不變應萬變的精髓所在。
下面,我們共同來了解下常見的軟件架構模式:
一、分層架構模式
分層架構模式是比較常見的軟件架構,這種架構將軟件分成若干個水平層,每一層分層體系結構模式的每一層在應用程序中都有一個特定的角色和職責。分層架構模式的強大特性之一是組件之間的關注點分離。 特定層中的組件只處理屬於該層的邏輯,層與層之間通過定義接口進行通信。
表現層(presentation):用户界面,負責視覺和用户互動
業務層(business):實現業務邏輯
服務層(Services): 提供共享服務
持久層(persistence):提供數據,SQL 語句就放在這一層
數據庫(database) :保存數據
模式分析
整體敏捷度低
易於部署:低
可測試性:高
性能等級:低
雖然有些分層架構確實可以執行得很好,但是由於必須通過多層架構來滿足業務請求的低效率,這種模式並不適合高性能應用程序。
可擴展性等級:低
由於此模式的緊密耦合和單塊實現的趨勢,使用此體系結構模式構建的應用程序通常難以伸縮。
易於開發性:高
優點
1. 結構簡單,容易理解和開發
2. 不同技能的程序員可以分工,負責不同的層,天然適合大多數軟件公司的組織架構
3. 每一層都可以獨立測試,其他層的接口通過模擬解決
缺點
1. 一旦環境變化,需要代碼調整或增加功能時,通常比較麻煩和費時
2. 部署比較麻煩,即使只修改一個小地方,往往需要整個軟件重新部署,不容易做持續發佈
3. 軟件升級時,可能需要整個服務暫停
4. 擴展性差。用户請求大量增加時,必須依次擴展每一層,由於每一層內部是耦合的,擴展會很困難
二、事件驅動模式
事件驅動架構模式是一種流行的分佈式異步架構模式,用於生成高度可伸縮的應用程序。 它也具有高度的適應性,可以用於小型應用程序,也可以用於大型、複雜的應用程序。 事件驅動的體系結構由高度解耦的、單一用途的事件處理組件組成,這些組件異步接收和處理事件。
該模式的構成:
· 事件隊列(event queue):接收事件的入口
· 分發器(event mediator):將不同的事件分發到不同的業務邏輯單元
· 事件通道(event channel):分發器與處理器之間的聯繫渠道
· 事件處理器(event processor):實現業務邏輯,處理完成後會發出事件,觸發下一步操作
模式分析
總體敏捷度:高
易於部署性:高
可測試性評價:低
此模式的異步特性使測試變得複雜。
性能等級:高
可伸縮性等級:高
通過高度獨立和解耦的事件處理器,這種模式自然實現了可伸縮性。 每個事件處理器都可以單獨伸縮,從而支持細粒度的可伸縮性。
易於開發性:低
由於模式的異步特性以及契約的創建,以及對於無響應的事件處理器和失敗的代理在代碼中需要更高級的錯誤處理條件,開發可能會有些複雜。
優點
1. 分佈式的異步架構,事件處理器之間高度解耦,軟件的擴展性好
2. 適用性廣,各種類型的項目都可以用
3. 性能較好,因為事件的異步本質,軟件不易產生堵塞
4. 事件處理器可以獨立地加載和卸載,容易部署
缺點
· 涉及異步編程(要考慮遠程通信、失去響應等情況),開發相對複雜
· 難以支持原子性操作,因為事件通過會涉及多個處理器,很難回滾
· 分佈式和異步特性導致這個架構較難測試
三、微內核模式
微內核體系結構模式(也被稱為插件體系結構模式)是實現第三方產品打包並以版本提供下載的自然模式。 微內核架構模式由兩種類型的架構組件組成:核心系統和插件模塊。 應用程序邏輯被劃分為獨立插件模塊和基本核心系統,提供可擴展性、靈活性以及應用程序特性和自定義處理邏輯的隔離。
模式分析
總體敏捷度:高
易於部署性:高
根據模式的實現方式,插件模塊可以在運行時動態地添加到核心系統(如熱部署),從而最大限度地減少部署期間的停機時間。
可測試性等級:高
插件模塊可以單獨測試,可以很容易地被核心系統模擬,以演示或原型一個特定的功能,幾乎或沒有改變核心系統。
性能等級:高
可擴展性等級:低
大多數微內核架構實現都是基於產品的,而且通常規模較小,它們是作為單個單元實現的,因此伸縮性不高。
易於開發性:低
微內核架構需要深思熟慮的設計和契約治理,這使得它的實現相當複雜。
優點
1. 良好的功能延伸性(extensibility),需要什麼功能,開發一個插件即可
2. 功能之間是隔離的,插件可以獨立的加載和卸載,使得它比較容易部署,
3. 可定製性高,適應不同的開發需要
4. 可以漸進式地開發,逐步增加功能
缺點
· 擴展性(scalability)差,內核通常是一個獨立單元,不容易做成分佈式
· 開發難度相對較高,因為涉及到插件與內核的通信,以及內部的插件登記機制
四、微服務模式
微服務架構(microservices architecture)是服務導向架構(service-oriented architecture,縮寫 SOA)的升級。微服務體系結構模式作為獨立應用程序和麪向服務的體系結構的可行選擇。
每一個服務就是一個獨立的部署單元(separately deployed unit)。這些單元都是分佈式的,互相解耦,通過遠程通信協議(比如REST、SOAP)聯繫。
微服務架構分成三種實現模式:
· RESTful API 模式:服務通過 API 提供,雲服務就屬於這一類
· RESTful 應用模式:服務通過傳統的網絡協議或者應用協議提供,背後通常是一個多功能的應用程序,常見於企業內部
· 集中消息模式:採用消息代理(message broker),可以實現消息隊列、負載均衡、統一日誌和異常處理,缺點是會出現單點失敗,消息代理可能要做成集羣
模式分析
總體敏捷度:高
由於採用了單獨部署單元的概念,因此更改通常與單個服務組件隔離,從而允許快速而簡單地部署。
易於部署:高
由於遠程服務的細粒度和獨立性,微服務模式的部署特徵率非常高。 服務通常作為獨立的軟件單元部署,因此可以在白天或晚上的任何時間進行"熱部署"。
可測試性等級:高
由於將業務功能分離和隔離到獨立的應用程序中,可以確定測試的範圍,允許進行更有針對性的測試工作。
性能等級:低
由於微服務體系結構模式的分佈式特性,該模式本身並不適合高性能應用程序。
可伸縮性等級:高
由於應用程序被分解為單獨部署的單元,每個服務組件可以單獨伸縮,從而允許對應用程序進行微調伸縮。
易於開發:高
由於功能被隔離到獨立的服務組件中,因此由於較小的隔離範圍,開發變得更容易。 開發人員在一個服務組件中做出影響其他服務組件的更改的可能性很小,因此減少了開發人員或開發團隊之間所需的協調。
優點
1. 擴展性好,各個服務之間低耦合
2. 容易部署,軟件從單一可部署單元,被拆成了多個服務,每個服務都是可部署單元
3. 容易開發,每個組件都可以進行持續集成式的開發,可以做到實時部署,不間斷地升級
4. 易於測試,可以單獨測試每一個服務
缺點
· 由於強調互相獨立和低耦合,服務可能會拆分得很細。這導致系統依賴大量的微服務,變得很凌亂和笨重,性能也會不佳。
· 一旦服務之間需要通信(即一個服務要用到另一個服務),整個架構就會變得複雜。典型的例子就是一些通用的 Utility 類,一種解決方案是把它們拷貝到每一個服務中去,用冗餘換取架構的簡單性。
· 分佈式的本質使得這種架構很難實現原子性操作,交易回滾會比較困難。
五、雲架構模式
雲結構(cloud architecture)主要解決擴展性和併發的問題,是最容易擴展的架構。
它的高擴展性,主要原因是沒使用中央數據庫,而是把數據都複製到內存中,變成可複製的內存數據單元。然後,業務處理能力封裝成一個個處理單元(prcessing unit)。訪問量增加,就新建處理單元;訪問量減少,就關閉處理單元。由於沒有中央數據庫,所以擴展性的最大瓶頸消失了。由於每個處理單元的數據都在內存裏,最好要進行數據持久化。
這個模式主要分成兩部分:
· 處理單元:實現業務邏輯
· 虛擬中間件:負責通信、保持sessions、數據複製、分佈式處理、處理單元的部署。
虛擬中間件又包含四個組件:
· 消息中間件(Messaging Grid):管理用户請求和session,當一個請求進來以後,決定分配給哪一個處理單元。
· 數據中間件(Data Grid):將數據複製到每一個處理單元,即數據同步。保證某個處理單元都得到同樣的數據。
· 處理中間件(Processing Grid):可選,如果一個請求涉及不同類型的處理單元,該中間件負責協調處理單元
· 部署中間件(Deployment Manager):負責處理單元的啓動和關閉,監控負載和響應時間,當負載增加,就新啓動處理單元,負載減少,就關閉處理單元。
模式分析
總體敏捷度:高
易於部署:高
雲架構通常不是解耦和分佈式的,但它們是動態的,而且複雜的基於雲的工具允許應用程序很容易"推出"到服務器,從而簡化部署。
可測試性評價:低
在測試環境中實現非常高的用户負載既昂貴又耗時,使得測試應用程序的可伸縮性方面變得困難。
性能等級:高
通過構建到該模式中的內存數據訪問和緩存機制實現了高性能。
可伸縮性等級:高
高可伸縮性來自於很少或不依賴於集中式數據庫的事實,因此從本質上消除了可伸縮性等式中的這個限制瓶頸。
易於開發:低
成熟的緩存和內存中的數據網格產品使得該模式的開發相對複雜。
優點
1. 高負載,高擴展性
2. 動態部署
缺點
· 實現複雜,成本較高
· 主要適合網站類應用,不合適大量數據吞吐的大型數據庫應用
· 較難測試
常見的軟件框架實例及應用
· Java 的 SpringMVC、Dubbo
· Python 的 Diango、Tornodo
· Php 的 Laravel 、ThinkPHP
· Javascript 的 Vue、Angular、React
寫在最後
大多數框架的設計模式都基本可以從上邊的設計模式中找到原型,複雜的框架也只是多種設計模式的組合運用。當我們瞭解了設計模式後,再去分析框架的時候,就會有煥然一新、豁然開朗的心境。當我們在理解設計模式的基礎上,去學習新的框架或語言,也會在理解上以及應用效率上得到顯著提升。