zoukankan      html  css  js  c++  java
  • CQRS架构介绍

    CQRS on itself is a very simple pattern. It only describes that the component of an application that processes commands should be separated from the component that processes queries. Although this separation is very simple on itself, it provides a number of very powerful features when combined with other patterns.

    The diagrams below show an example of an extended layout of a CQRS-based event driven architecture. The UI component, displayed on the left, interacts with the rest of the application in two ways: it sends commands to the application (shown in the top section), and it queries the application for information (shown in the bottom section).

    Command handling

    The user interface sends commands to make changes to the system. Commands are simple object that contain all the data needed to perform the underlying action. An example of the command could be MoveUserToNewAddress. The command should hold the new address for the user and the user id that indicates which user has moved.

    Commands also tent to express intent by there name. For example, although the command MoveUserToNewAddress andCorrectAddressForUser both contain the same data – the address and the user id – the intent is definitely different.

    All commands are send to a Command Service. This service receives the commands and routes them to the corresponding command handlers. Command handlers should not contain any business logic. The only thing they do is making changes to aggregate roots from the domain and makes changes to them.

    The domain

    The command handler retrieves domain objects (Aggregates) from a repository and executes methods on them to change their state. All business logic is captured within these objects and is not used for querying. This allows us to optimize this model for behavior.

    Aggregate roots contain the actual business logic and are  responsible for guarding their own invariants. State changes on aggregate roots cause domain events to occur. This sequence of domain events represents all the changes that has been made. This pattern is called event sourcing. Both the Domain Events and the Aggregates form the domain model.
     

    The domain events

    All state changes in the domain are represented by domain events. They are simple object that contain all data related to the change. We gave two examples of command names. The events that are related to the state change of these commands will be UserMovedToNewAddress and AddressCorrectedForUser. Notice that the names are in the past tense.

    The Repository

    The repository act as a in-memory aggregate collection. The repository allow us to get a single aggregate by the aggregate id or save a single aggregate root into it. Getting an aggregate root is done by getting all its related events and replaying them to build up the aggregate root into the latest state. Saving an aggregate root will result in persisting all its uncommitted events that occurred while making change to it. The events are stored in the event store and when an aggregate root is saved, all the events will also be published to the event listeners.

    The event store

    All events that have occurred end up in the event store. It contains all the event that represents the state changes in the system. These can be used to build up the current state by replaying them all. This store can also be used to fill up new or repair existing read model.

    The event bus

    When an aggregate root is saved via the repository all the uncommitted events that represent the state changes that has been made are persisted into the event store. Beside that, the repository also publish these events via the event bus. This bus publishes it to event listener that has registered itself as one being interested in the events. An important choice to make is whether the bus publishes the events to the subscribers in a synchronous or asynchronous way.

    Synchronous means that the event handling that is done by the subscribers blocks the current execution and that this waits for all subscribers to complete before returning to the user. This model is simple and is a sensible default.

    Asynchronous would not wait for all subscribers to complete before returning to the user. It will drop the event on the bus and return to the user. This will keep the execution of command fast, but introduces eventual consistency. The read models will be consistent at some point of time.

    The event handlers

    There are different event handlers subscribed to the events bus. The most common one are denormalizers. These event handlers take events and makes changes to the read model based on them. For example, a denormalizer could update the users address in the user table based on the data in the UserMovedToNewAddress event. But it could also update the total number of users in city X based on that the same event.

    Event handlers are not only interesting to keep the read model up to date. But they could also be written to make changes to an external system or send warning email to the business when certain event occur. It could also be that an event handler issues a new command . Event handlers are great components to extent the system with new functionality without making changes in it.

    Read models

    An important part of every application is data. Most of the screen in an user interface request it. But every screen just tents to have a different view on the data. For example, one wants all the products with there name, price and category, while another wants the products with there name and top 3 latest product review score and name of the reviewer.

    Read models are models that can be optimized for data querying. And what is a optimal query? That is a query that just queries the data from one source. In other words: select * from x where y. No joining, just give me the data. We can accomplish this by creating one table per view. So that every view can just request data by a simple query.

    Your read model doesn’t even have to be a relational database, it could be a document based database that contains a collection for every view.
  • 相关阅读:
    用VC编译lua源码,生成lua语言的解释器和编译器
    vs如何在C++中调用Lua
    打印页面 订单号生成 条形码
    关于 打印页面 图片被截断
    easyui numberbox输入框 编辑不可编辑的切换
    点击空白处--某个div 消失
    easyui扩展行默认展开 以及 去除滚动条
    eayui grid 每一页的行号都是从1开始
    js中的this--执行上下文
    easyui grid 本地做分页
  • 原文地址:https://www.cnblogs.com/netfocus/p/2347910.html
Copyright © 2011-2022 走看看