引自:《Software Architecture Patterns》程序員
附腦圖web
分層架構(layered architecture)是最多見的軟件架構,也是事實上的標準架構。數據庫
一般結構可分爲4個標準層級,各層級的定義以下:編程
So why not allow the presentation layer direct access to either the persistence layer or database layer? After all, direct database access from the presentation layer is much faster than going through a bunch of unnecessary layers just to retrieve or save database information. The answer to this question lies in a key concept known as layers of isolation.架構
The layers of isolation concept means that changes made in one layer of the architecture generally don’t impact or affect components in other layers: the change is isolated to the components within that layer, and possibly another associated layer (such as a persistence layer containing SQL).app
The layers of isolation concept also means that each layer is independent of the other layers, thereby having little or no knowledge of the inner workings of other layers in the architecture.框架
層級隔離的設計理念,使得層與層之間實現了高內聚、低耦合。異步
Creating a services layer is usually a good idea in this case because architecturally it restricts access to the shared services to the business layer (and not the presentation layer). Without a separate layer, there is nothing architecturally that restricts the presentation layer from accessing these common services, making it difficult to govern this access restriction.socket
層級架構也使得增長新的業務層更加容易——由於層級(模塊)間的耦合度很低,新的層級只須要處理層與層之間的接口就OK了。async
調整業務結構,咱們增長一個新的層級——服務層。
The services layer in this case is marked as open, meaning requests are allowed to bypass this open layer and go directly to the layer below it.
In the following example, since the services layer is open, the business layer is now allowed to bypass it and go directly to the persistence layer, which makes perfect sense.
因爲新的層級是開放的而非閉合的,它容許上游層越過自身,實現直接對下游層數據的訪問。
分層架構能夠直觀的實現不一樣層級邏輯代碼的解耦合,除此以外:
缺點:
模式分析:
事件驅動架構(Event-Driven Architecture)是一個流行的分佈式異步架構模式。基於這種架構模式應用可大可小。它由高度解耦、單一目的的事件處理組件組成,能夠異步地接口和處理事件。
事件:系統或組件的狀態發生變化時,系統層發出的通知。
解耦方式:每一個對象都經過與中間件(Mediator or Broker)實現與外界的溝通,而不是相互依賴(迪米特法則)。
通信方式:以消息爲載體、經過中間件傳遞通信。
The event-driven architecture pattern consists of two main topologies, the mediator and the broker. The mediator topology is commonly used when you need to orchestrate multiple steps within an event through a central mediator, whereas the broker topology is used when you want to chain events together without the use of a central mediator. Because the architecture characteristics and implementation strategies differ between these two topologies, it is impor‐tant to understand each one to know which is best suited for your particular situation.
相比於後面講到的Mediator,Broker是一種更本質也更簡潔的EDA(不知道做者爲什麼選擇先講解複雜的Mediator,我的認爲應該將這個順序調整過來)。
該結構包含了三個組件:
如上圖:當系統中的某個對象觸發了某個事件,事件被提交到Custormer Process,而後派送到Broker。Broker將解析事件並轉發到相關的Processor中執行處理(注意,兩個Processor是各自獨立進行的,不存在任何耦合)。而在Processor中又觸發了新的事件(「責任鏈」模式),並經過各自的Channel轉發到另外的Processor中完成處理。
在Mediator中,咱們將看到Mediator模式對該問題的另一種處理方式。
Mediator能夠說是Broker的一種拓展,更適用於粗粒度事件的處理——因爲業務邏輯更復雜,細粒度的拓撲結構將形成消息臃腫而混亂,固然,粗粒度也增長了EDA架構的複雜度。
採用Mediator模式的架構中,事件通常是複雜的(包含多個執行單元的合集),而Mediator的責任就是將該複合事件拆解爲獨立的子事件,而後發送到不一樣類型的子事件處理系統中,由子系統完成獨立子事件的分發和處理。
在結構上,Mediator的EDA架構包括4個組件:
在邏輯上,Mediator的處理過程以下:
The event flow starts with a client sending an event to an event queue, which is used to transport the event to the event mediator. The event mediator receives the initial event and orchestrates that event by sending additional asynchronous events to event channels to execute each step of the process. Event processors, which listen on the event channels, receive the event from theevent mediator and execute specific business logic to process the event.
It is common to have anywhere from a dozen to several hundred event queues in an event-driven architecture. The pattern does not specify the implementation of the event queue component; it can be a message queue, a web service endpoint, or any combination thereof.
EDA對 Event Queues 並無特定的實現要求,不管是數量仍是類型,均可以根據實際須要肯定。
There are two types of events within this pattern: an initial event and a processing event. The initial event is the original event received by the mediator, whereas the processing events are ones that are generated by the mediator and received by the event-processing components.
對應於 Event Queues 和 Event Channel,也一樣存在着兩種事件類型:原始事件(或者稱爲:複合事件)和處理事件。
呃,這句話倒過來講更合適:由於有不一樣的事件類型,因此須要對應存在不一樣的隊列。
Event channels are used by the event mediator to asynchronously pass specific processing events related to each step in the initial event to the event processors. The event channels can be either message queues or message topics, although message topics are most widely used with the mediator topology so that processing events can be processed by multiple event processors (each performing a different task based on the processing event received).
The event processor components contain the application business logic necessary to process the processing event. Event processors are self-contained, independent, highly decoupled architecture components that perform a specific task in the application or system. While the granularity of the event-processor component can vary from fine-grained (e.g., calculate sales tax on an order) to coarsegrained (e.g., process an insurance claim), it is important to keep in mind that in general, each event-processor component should perform a single business task and not rely on other event processors to complete its specific task.
事件處理器包含實際的業務邏輯。每一個消息處理器都是自包含的,獨立的,高度解耦的,執行單一的任務(高內聚低耦合的要求使然)。這部分是咱們開發和拓展業務的主要戰場。
有一些開源的框架實現了這種架構,如Spring Integration, Apache Camel, 或者 Mule ESB。
固然,這種架構包含了多種形式的變種,你應當可以根據須要,靈活的替換相應的子模塊以適配需求。
仍是剛纔的Move的例子,在Broker的架構中,事件以遞歸方式,實現自包含,經過Processor與Channel的互相調用完成消息的傳遞。這是所謂「責任鏈」模式的體現。
而Mediator則是經過統一的封裝性,將自己的Move事件封裝成若干子事件,每一個子事件由不一樣的Event Channel在子系統內實現派發。這樣的模式效率無疑是更高的,但它要求固定的問題域——這就致使其可拓展性較差,一旦體系須要拓展,或原Event結構出現變化,子系統也必須全盤修改。
架構考量:
事件驅動架構模式實現起來相對複雜,主要是因爲它的異步和分佈式特性。這可能會帶來一些分佈式的問題,好比遠程處理的可用性,缺少響應,broker重連等問題。
優勢:
缺點:
模式分析
微核架構(microkernel architecture)又稱爲"插件架構"(plug-in architecture),指的是軟件的內核相對較小,主要功能和業務邏輯都經過插件實現。
內核(core)一般只包含系統運行的最小功能。插件則是互相獨立的,插件之間的通訊,應該減小到最低,避免出現互相依賴的問題。
解耦方式:業務相關項以插件的形式發佈,能夠選擇動態加載。業務插件只與內核交互,實現業務間的低耦合。
通信方式:插件與內核,經過內核發佈的特定接口進行通信(通信樣式無限制)
The microkernel architecture pattern consists of two types of architecture components: a core system and plug-in modules. Application logic is divided between independent plug-in modules and the basic core system, providing extensibility, flexibility, and isolation of application features and custom processing logic.
因爲許多的系統都是採用的相似架構設計,該架構模式所以得名。
The microkernel architecture pattern consists of two types of architecture components: a core system and plug-in modules. Application logic is divided between independent plug-in modules and the basic core system, providing extensibility, flexibility, and isolation of application features and custom processing logic.
內核系統是一種最小化開發的、可以保證程序基本運行的應用。通常不包含業務層,基本的業務邏輯也是抽象化的通用性規則。而具體規則和業務邏輯,則經過不一樣的插件拓展實現。
The plug-in modules are stand-alone, independent components that contain specialized processing, additional features, and custom code that is meant to enhance or extend the core system to produce additional business capabilities. Generally, plug-in modules should be independent of other plug-in modules, but you can certainly design plug-ins that require other plug-ins to be present. Either way, it is important to keep the communication between plug-ins to a minimum to avoid dependency issues.
想要插件之間徹底沒有耦合是不合理的,但儘量的減小插件之間的耦合,關係到整個體系的運轉與維護。
The core system needs to know about which plug-in modules are available and how to get to them. One common way of implementing this is through some sort of plug-in registry. This registry contains information about each plug-in module, including things like its name, data contract, and remote access protocol details (depending on how the plug-in is connected to the core system). For example, a plug-in for tax software that flags high-risk tax audit items might have a registry entry that contains the name of the service (AuditChecker), the data contract (input data and output data), and the contract format (XML). It might also contain a WSDL (Web Services Definition Language) if the plug-in is accessed through SOAP.
通常的,插件經過註冊機制掛載到內核上。內核將維持一個插件列表,以瞭解當前系統中的每個組件。插件的掛載方式能夠有多種,例如經過 dlopen( ) 將lib庫載入內核進程內存;或是經過 SOA 模式加載服務項,並執行服務調用;或是經過點對點 socket 創建 romote object proxy 的隊列,並執行RPC調用,等等。更多的方式見下一段:
Plug-in modules can be connected to the core system through a variety of ways, including OSGi (open service gateway initiative), messaging, web services, or even direct point-to-point binding (i.e., object instantiation). The type of connection you use depends on the type of application you are building (small product or large business application) and your specific needs (e.g., single deploy or distributed deployment). The architecture pattern itself does not specify any of these implementation details, only that the plug-in modules must remain independent from one another.
插件架構模式自己並無限定core與module的鏈接方式——鏈接方式通常須要根據具體的應用場景選擇不一樣的方案。
The contracts between the plug-in modules and the core system can range anywhere from standard contracts to custom ones. Custom contracts are typically found in situations where plug-in components are developed by a third party where you have no control over the contract used by the plug-in. In such cases, it is common to create an adapter between the plug-in contact and your standard contract so that the core system doesn’t need specialized code for each plug-in. When creating standard contracts (usually implemented through XML or a Java Map), it is important to remember to create a versioning strategy right from the start.
插件之間的通訊方式也能夠有多種實現,通常的建議使用通用協議,如HTTP或標準socket消息結構。
架構考量:
微內核的架構模式能夠嵌入到其它的架構模式之中。微內核架構經過插件還能夠提供逐步演化的功能和增量開發。因此若是你要開發基於產品的應用,微內核是不二選擇。
模式分析:
優勢:
缺點: