cqrs documents by greg young - minato.tv · 2014-04-07 · cqrs and event sourcing ... it is...

55
CQRS Documents by Greg Young http://cqrsinfo.com 1 Content A Stereotypical Architecture | ステレオタイプなアーキテクチャ.................................. 3 Application Server | アプリケーションサーバ............................................................ 3 Client Interaction | クライアントの対話 ............................................................... 4 Analysis of the Stereotypical Architecture | ステレオタイプなアーキテクチャの分析 ....................... 6 Simplicity | 簡易性 ................................................................................ 6 Tooling | ツールの使用.............................................................................. 6 Domain Driven Design | ドメイン駆動設計 ............................................................. 6 Scaling | 拡張性 ................................................................................... 8 Summary | 概要....................................................................................... 8 Works Cited | 参考文献 ............................................................................... 8 Task Based User Interface | タスクベース・ユーザインタフェース ................................. 9 Commands | コマンド ................................................................................. 11 User Interface | ユーザインタフェース................................................................. 13 Works Cited | 参考文献 .............................................................................. 16 Command and Query Responsibility Segregation | コマンドクエリ債務分離 ........................ 17 Origins | 起源...................................................................................... 17 Consistency | 一貫性 .............................................................................. 19 Data Storage | データストレージ .................................................................... 19 Scalability | スケーラビリティ ..................................................................... 19 The Query Side | クエリ側 ........................................................................... 19 The Command Side | コマンド側 ....................................................................... 22 Events as a Storage Mechanism | ストレージメカニズムにおけるイベント .......................... 25 What is a Domain Event? | ドメインイベントとは........................................................ 25 Other Definitions and Discussion | 他の定義や議論 .................................................... 26 Events as a Mechanism for Storage | ストレージ向けメカニズムとしてのイベント............................ 28 There is no Delete | 削除するものは無い .............................................................. 31 Performance and Scalability | パフォーマンスとスケーラビリティ......................................... 32 Partitioning | パーティション分割................................................................... 32 Saving Objects | オブジェクトの格納................................................................. 33 Loading Objects | オブジェクトのロード.............................................................. 33 Rolling Snapshots | スナップショットの巻き出し ........................................................ 34 Impedance Mismatch | インピーダンス・ミスマッチ ....................................................... 36 Business Value of the Event Log | イベントログのビジネス価値 .......................................... 38 Works Cited | 参考文献 .............................................................................. 40 Building an Event Storage | イベントストレージの構築 ......................................... 41 Structure | 構造.................................................................................... 41 Operations | 操作................................................................................... 42 Rolling Snapshots | スナップショットの巻き出し ........................................................ 44 Event Storage as a Queue | キューとしてのイベントストレージ............................................ 46 CQRS and Event Sourcing | CQRS とイベント供給 ............................................... 49 Cost Analysis | コスト分析 .......................................................................... 50 Integration | 統合.................................................................................. 51 Differences in Work Habits | 作業習慣における相違点................................................... 52 Parallelization | 並列化 .......................................................................... 53 All Developers are not Created Equally | 開発者は同じものを作らない ................................. 53 Outsourcing | アウトソーシング ..................................................................... 54

Upload: others

Post on 05-Jul-2020

4 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 1

Content

A Stereotypical Architecture | ステレオタイプなアーキテクチャ .................................. 3

Application Server | アプリケーションサーバ ............................................................ 3

Client Interaction | クライアントの対話 ............................................................... 4

Analysis of the Stereotypical Architecture | ステレオタイプなアーキテクチャの分析 ....................... 6

Simplicity | 簡易性 ................................................................................ 6

Tooling | ツールの使用 .............................................................................. 6

Domain Driven Design | ドメイン駆動設計 ............................................................. 6

Scaling | 拡張性 ................................................................................... 8

Summary | 概要 ....................................................................................... 8

Works Cited | 参考文献 ............................................................................... 8

Task Based User Interface | タスクベース・ユーザインタフェース ................................. 9

Commands | コマンド ................................................................................. 11

User Interface | ユーザインタフェース................................................................. 13

Works Cited | 参考文献 .............................................................................. 16

Command and Query Responsibility Segregation | コマンドクエリ債務分離 ........................ 17

Origins | 起源 ...................................................................................... 17

Consistency | 一貫性 .............................................................................. 19

Data Storage | データストレージ .................................................................... 19

Scalability | スケーラビリティ ..................................................................... 19

The Query Side | クエリ側 ........................................................................... 19

The Command Side | コマンド側 ....................................................................... 22

Events as a Storage Mechanism | ストレージメカニズムにおけるイベント .......................... 25

What is a Domain Event? | ドメインイベントとは ........................................................ 25

Other Definitions and Discussion | 他の定義や議論 .................................................... 26

Events as a Mechanism for Storage | ストレージ向けメカニズムとしてのイベント ............................ 28

There is no Delete | 削除するものは無い .............................................................. 31

Performance and Scalability | パフォーマンスとスケーラビリティ ......................................... 32

Partitioning | パーティション分割 ................................................................... 32

Saving Objects | オブジェクトの格納 ................................................................. 33

Loading Objects | オブジェクトのロード .............................................................. 33

Rolling Snapshots | スナップショットの巻き出し ........................................................ 34

Impedance Mismatch | インピーダンス・ミスマッチ ....................................................... 36

Business Value of the Event Log | イベントログのビジネス価値 .......................................... 38

Works Cited | 参考文献 .............................................................................. 40

Building an Event Storage | イベントストレージの構築 ......................................... 41

Structure | 構造 .................................................................................... 41

Operations | 操作 ................................................................................... 42

Rolling Snapshots | スナップショットの巻き出し ........................................................ 44

Event Storage as a Queue | キューとしてのイベントストレージ ............................................ 46

CQRS and Event Sourcing | CQRSとイベント供給 ............................................... 49

Cost Analysis | コスト分析 .......................................................................... 50

Integration | 統合 .................................................................................. 51

Differences in Work Habits | 作業習慣における相違点 ................................................... 52

Parallelization | 並列化 .......................................................................... 53

All Developers are not Created Equally | 開発者は同じものを作らない ................................. 53

Outsourcing | アウトソーシング ..................................................................... 54

Page 2: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 2

Specialization | 特殊化/専門化 ..................................................................... 54

Only Sometimes | 時には ........................................................................... 55

Page 3: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 3

A Stereotypical Architecture | ステレオタイプなアーキテクチャ

Before moving into architectures for Domain Driven Design based projects it is important to start off by

analyzing what is generally considered to be the standard architecture that many try to apply to projects.

We can from that point attempt to improve upon the stereotypical architecture in small rational steps while

trying to minimize the cost in terms of productivity for each step towards a better architecture.

ドメイン駆動設計ベースのプロジェクト向けアーキテクチャに移行する前に、多くのプロジェクトが適用しようとしているアーキ

テクチャについて、何を標準的なアーキテクチャとみなすのかを、まず分析することが重要です。そこから、私たちは、より優れ

たアーキテクチャに対してステップごとに生産性の観点でコストを抑制する施策を通して、ステップを小さく合理的に分割してス

テレオタイプなアーキテクチャの改善に取り組むことができます。

Below is shown a diagram of a stereotypical architecture.

下図は、ステレオタイプなアーキテクチャの図です。

Figure 1 A Stereotypical Architecture | 図1 ステレオタイプなアーキテクチャ

Application Server | アプリケーションサーバ

The above architecture is centered upon a backing data storage system. This system although typically a RDBMS

does not have to be, it could just as easily be a key/value store, and object database, or even plain XML

files. The important aspect of the backing store is that it is representing the current state of objects in

the domain.

上図のアーキテクチャは、補助データストレージに集中しています。このシステムは典型的な RDBMS である必要はなく、簡単に

Key-Valueストア、オブジェクトデータベースまたは、プレインなXMLファイルの場合もあります。補助記憶装置の重要な面は、

ドメインのオブジェクトの現在のステートを表現しているということです。

Above the backing data storage lies an Application Server. An area of logic, labeled as the domain in Figure

1 contains the business logic of the system. In this area validation and orchestration logic exists for the

processing of requests given to the Application Server.

上図の補助データストレージは、アプリケーションサーバ上にあります。図 1の Domain部分のロジック領域は、システムのビジ

ネスロジックを含みます。この領域には、アプリケーションサーバが受け付けたリクエストを処理する、バリデーションや集約ロ

ジックがあります。

It is important to note that although Figure 1 is drawn without a data tier one could place a data tier in

between the Application Server and the Data Storage. It is also important to note that a “domain” is not necessary

to achieve this architecture, one could also use other patterns such as Table Module or Transaction Script.

Page 4: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 4

With these only existing as Application Services.

重要な注意事項として、図1にはありませんが、アプリケーションサーバとデータストレージの間にデータ層を置くこともできま

す。また、ドメイン層は、必ずしもこのアーキテクチャを達成するのに必要ではない点、ドメイン層はTable ModuleやTransaction

Scriptのような他のパターンも使用可能な点に注意することも重要です。

Abstracting the “domain” one will find a facade known as Application Services. Application Services provide

a simple interface to the domain and underlying data, they also limit coupling between the consumers of the

domain and the domain itself.

ドメイン層から分離するものとして、アプリケーションサービスとも言われるファサードがあります。アプリケーションサービス

は、ドメインとその下層のデータ層をつなぐ簡易なインタフェースを提供し、ドメインの消費者やドメイン自身との間における結

合を制限します。

On the outside of the Application Server sits some type of Remote Facade. This could be many things such as

SOAP, custom TCP/IP, XML over HTTP, TomCat, or even a person manually typing messages that arrive tied to

the legs of pigeons. The Remote Facade may or may not be abstracted away from its underlying technology mechanism

depending on the situation and tools that are involved.

アプリケーションサーバの外側には、数種類のリモートファサードがあります。これにはSOAP、カスタムTCP/IP、XML over HTTP、

Tomcat や、伝言鳩で送るメッセージを手書きする人さえも含まれます。リモートファサードは、リモートファサードの下にある

テクノロジーメカニズム(関連するシチュエーションやツールなど)を含む場合もあればそうでない場合もあります。

The overall usage of an Application Server to abstract away the data storage of a system and to provide a

centralized location of business logic has become very popular over the years and at the time of this writing

is in many circumstances considered to be the default architecture applied to many systems.

データストレージから分離してビジネスロジックを集中化する領域を提供するアプリケーションサーバの全体的手法は、この数年

間で非常に人気が上昇し、多くのシステムで適用されているデフォルトのアーキテクチャとなっている状況にあります。

Client Interaction | クライアントの対話

Interacting with the Application Server there is a / are many client(s). The general interaction of the clients

can be seen in Figure 2.

アプリケーションサーバとの対話では、単数/多数のクライアントがあります。クライアントの一般的な対話を、図2に示します。

Figure 2 Typical Client Interaction | 図2 典型的なクライアントの対話

The basic interaction of the client can be described as a DTO (Data Transfer Object) up/down interaction.

Going through the lifecycle of an operation is the easiest way to show the functioning of the API. A user

goes to a screen, perhaps to edit a customer. The client sends a request to the remote facade for a DTO representing

Customer #id. The Remote facade loads up the domain objects required, and maps the domain objects to a DTO

that is then returned to the client. An example of DTO in XML format can be seen in Figure 3 but the basic

Page 5: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 5

explanation is that the DTO in this stereotypical architecture contains the current state of the object in

questions.

クライアントの基本的な対話は、DTO(Data Transfer Object)のアップ/ダウンインタラクションと呼べます。オペレーショ

ンのライフサイクルを完遂することは、APIの機能を示す最も簡単な方法です。ユーザが画面上でたとえば情報を編集します。ク

ライアントはリクエストとして、カスタマ ID(お客様ID)を含む DTOをリモートファサードに送信します。リモートファサード

は要求されたドメインオブジェクトをロードし、ドメインオブジェクトをDTOにマッピングしてクライアントに返します。図3は、

XMLで記述したDTOの例ですが、基本的にステレオタイプなアーキテクチャではDTOはオブジェクトの現在のステートを含んでい

ます。

The client will then display the information received from the Remote Facade on the screen allowing the user

to interact with it. This is very often done utilizing a view model and/or data binding with the view.

そして、クライアントではリモートファサードから返ってきた情報を画面上に表示し、対話ができるようにします。ここではビュ

ーモデルと/またはデータバインディングをよく利用します。

At some point the user will be complete with the editing of the data on the screen and will through some action

cause the UI to “Save” the data. Generally this is implemented through a “Save Button” although some User

Interfaces will instead just have you leave the current data which forces a save.

そこで、ユーザは画面上でデータを編集し、UIを通してデータを「保存」するアクションを起こすでしょう。一般的に[保存]ボタ

ンを使用しますが、一部のユーザインタフェースでは代わりに、強制的に保存する現在のデータを残すでしょう。

<Contact id=”1234”>

<Name>Greg Young</Name>

<Address>

<Street>111 Some St.</Street>

<City>Vernon</City>

<State>CT</State>

<Zip>06066</Zip>

<Country>USA</Country>

</Address>

</Contact>

Figure 3 Example in XML of a DTO | 図3 XMLで記述したDTOの例

The processing of a Save on the client will take the data that has been edited by the user on the screen,

pack it back into a DTO (usually identical to the DTO it requested from the Remote Façade for displaying to

the user). It will then send this DTO back up to the Application Server.

クライアント上での保存の実行により、ユーザが編集したデータを画面から取り出し、DTO(通常はリモートファサードから返さ

れたDTOと同一内容)に詰め込むでしょう。そしてこのDTOをアプリケーションサーバに返すでしょう。

The Application Server receiving the DTO will then start a transaction/session, map the DTO back to the

domain objects, allow the domain objects to verify any changes, then save the changes within the

domain objects back to the data storage likely through the use of something like an Object Relational

Mapper that has the ability to distinguish what has changed in the domain objects and update the data

storage accordingly. The Application Server will return to the client either an Acknowledgement (Ack)

that the change has been persisted or it will return a series of errors as to why it was unable to persist

the changes.

DTOを受け取ったアプリケーションサーバは、そこでトランザクション/セッションを開始し、DTOをドメインオブジェクトにマ

ッピングし、ドメインオブジェクトの変更内容を検証し、Object Relational Mapper(ドメインオブジェクト内の変更内容を識

別して、その内容に応じてデータストレージを更新する機能がある)などを使用してデータストレージに格納するでしょう。アプ

リケーションサーバは、変更内容を永続化したことを示す通知(Ack)か、変更内容を永続化できなかった理由を示すエラーを、

クライアントに返すでしょう。

Page 6: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 6

Analysis of the Stereotypical Architecture | ステレオタイプなアーキテクチャの分析

The architecture provided above as with any architecture has many properties. Some of these properties are

good under certain scenarios and other properties can be extremely bad in others. As architects we should

really be trying to align many of these properties to best fit our needs.

他のアーキテクチャと同様、先述のアーキテクチャには、多くの特性があります。特定のシナリオの下では一部の特性は優れてい

ても、他のシナリオでは非常に悪いです。設計者としては、本当に、ニーズに最も適合するよう多くの資産を整理するよう努める

べきです。

Simplicity | 簡易性

When looking at properties it is important to note what the most likely property is for a given architecture

becoming popular. In the architecture above the most likely property defining its popularity is that it is

simple. One could teach a Junior developer how to interact with a system built using this architecture in

a very short period of time. Going along with the simplicity, the architecture is completely generic. One

could use this architecture on every project. Along with being able to use it on every project, because many

people are doing it, its likely that if a team brings on a new member the new member will be intimately familiar

with the general architecture of their system again lowering on ramp up costs.

特性を考えるとき、アーキテクチャにとって最も重要な特性が何なのかに注意することが大切です。先述のアーキテクチャにおけ

る最も重要な特性は、シンプルなことです。特性がシンプルなら、このアーキテクチャを使用するシステムがどのように機能する

かを、若い開発者に短期間で教えることができます。簡易性をサポートすれば、アーキテクチャは完全に汎用的になります。あら

ゆるプロジェクトでこのアーキテクチャを使用できます。加えて、あらゆるプロジェクトでこのアーキテクチャを使用できれば、

多くのメンバーが扱います。すると、チームが多くの新しいメンバーを抱えていても、そのシステムの一般的なアーキテクチャを

親密に扱うことができるため、コストが減少します。

The combination of these two items allows teams to become extremely adept at applying this architecture and

more important it allows them to use it as a default architecture. The thought process of needing to align

non-functional requirements really goes away as they know that this architecture will be “good enough” for

80% of the projects that they run into.

この2つの組み合わせにより、チームはこのアーキテクチャを非常にスムーズに適用できるようになり、より重要な点として、そ

れをデフォルトのアーキテクチャとして使用できるようになります。非機能要件を整理する必要がある思考プロセスが本当になく

なり、チームのメンバーが知っているように、彼らが陥るプロジェクトの 80%では、このアーキテクチャは「十分良い」ものにな

るでしょう。

Tooling | ツールの使用

Many frameworks exist for the optimization of time required to create systems utilizing the architecture

provided above. ORM’s are the largest single example as they provide valuable services such as change tracking

and transaction management with complex object graphs. Other examples would include the automapping frameworks

that map from the domain objects to DTOs on both sides resulting in largely removing the amount of “plumbing

code” required to map the DTOs back and forth in the Application Server.

先述のアーキテクチャを利用するシステムを作成する作業を最適化するためのフレームワークが、多く存在します。変化追跡と業

務管理のような、複雑なオブジェクトグラフが伴うサービスでは、ORMは価値あるサービスを実現するためにORMがもっともよく

使われます。他にも、ドメインオブジェクトとDTOの間を自動的に双方向マッピングするフレームワークを使えば、アプリケーシ

ョンサーバの至る所にあるDTOのマッピングを行う大量のコード(plumbing code)を削除できます。

Of course there are however also many not-so-good things associated with the architecture provided above.

It being that this document is associated with Domain Driven Design the single most important of the not-so-good

properties would be that it is impossible to apply Domain Driven Design with the architecture provided.

しかしながら、先述のアーキテクチャには、当然、あまり好ましくない特性も存在します。本書ではドメイン駆動設計について触

れますが、最も重要なのは、ドメイン駆動設計を先述のアーキテクチャに適用するのは不可能だということです。

Domain Driven Design | ドメイン駆動設計

The application of Domain Driven Design is not possible in the above architecture though many who are “practicing”

Domain Driven Design use this architecture. The reasoning for why it is impossible can easily be seen when

one looks at how the Ubiquitous Language is represented by the object model.

Page 7: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 7

ドメイン駆動設計を実践している多くの人は、先述のアーキテクチャを使用しますが、このアーキテクチャではドメイン駆動設計

のアプリケーションは不可能です。なぜ不可能なのかという推論は、ユビキタス言語がどのようにオブジェクトモデルを表現する

のかを見れば、簡単に導くことができます。

In the architecture above there are only four verbs (and of course synonyms for those four such as edit instead

of update). The four verbs are Create, Read, Update, and Delete or CRUD as they are commonly known in the

industry. Because the Remote Façade has a data oriented interface the Application Services must necessarily

have the same interface.

先述のアーキテクチャには、唯一の4つの動詞があります。この4つの動詞とは、業界でよく知られているように、Create(作成)、

Read(読み込み)、Update(更新)およびDelete(削除)を指します(略称:CRUD)。もちろん、たとえば「更新」の代わりに「編

集」といった類義語を使っても、この4つに含みます。リモートファサードはデータ指向インタフェースなので、アプリケーショ

ンサービスは、必然的に同じインタフェースになります。

This means that there are no other verbs within the domain. When however one talks with domain experts in

an effort to refine an Ubiquitous Language, it is extremely rare that one ends up with a language that is

focused on these four verbs.

つまり、ドメイン内には他の動詞がないということを意味します。しかしながらドメインの専門家とユビキタス言語を改良しよう

と議論しても、この4つの動詞に焦点を当てたユビキタス言語で終わるのは非常に稀です。

There is a related well-known anti-pattern of domain modeling known as an “Anemic Model”.

ドメインモデリングに関しては「Anemic Model」という有名なアンチパターンがあります。

“The basic symptom of an Anemic Domain Model is that at first blush it looks like the real thing. There are

objects, many named after the nouns in the domain space, and these objects are connected with the rich

relationships and structure that true domain models have. The catch comes when you look at the behavior, and

you realize that there is hardly any behavior on these objects, making them little more than bags of getters

and setters. Indeed these models often come with design rules that say that you are not to put any domain

logic into the domain objects. Instead there are a set of service objects which capture all of the domain

logic. These services live on top of the domain model and use the domain model for data” (Fowler, 2003)

「Anemic Domain Model の基本的な症状は、まずそれが一見、本物のように見えることです。オブジェクトがあり、ドメイン領

域ではその多くが名詞で名付けられています。また、これらのオブジェクトは、本当のドメインモデルが持っているリッチな関係

と構造と結びつけられています。ふるまいを見れば、明らかです。これらのオブジェクトには、大量の getterと setterがあっ

ても、ふるまいがほとんどありません。実際に、これらのモデルは、ドメインロジックをドメインオブジェクトに入れないという

設計規則によく登場します。その代わり、すべてのドメインロジックは、一組のサービスオブジェクトに入れます。これらのサー

ビスはドメインモデルの上位に位置し、データを扱うためにドメインモデルを使用します。」(Fowler, 2003)(訳注:

http://martinfowler.com/bliki/AnemicDomainModel.htmlを参照)

The model that is being built in this architecture sounds at first to be an anemic domain model. Because the

Application Services map data back and forth to DTO’s the domain objects have little behavior and are littered

with getters and setters to be used in the mapping process. There is a structure to the domain showing how

objects relate with one another but …

このアーキテクチャで構築したモデルは、当初はAnemic Domain Modelのように見えます。アプリケーションサービスはDTOと

相互マッピングを行うので、ドメインオブジェクトが持つふるまいはごくわずかであるにも関わらず、マッピング処理で使うため

のgetterとsetterでごった返しになります。ドメインには、オブジェクトの相互関係を示す構造があるのですが…

One cannot even create and Anemic Domain Model with this architecture as then all of the business logic would

be in services, here the services themselves are really just mapping DTO’s to domain objects, there is no

actual business logic in them. In this case a large amount of business logic is not existing in the domain

at all, nor in the Application Server, it may exist on the client but more likely it exists on either pieces

of paper in a manual or in the heads of the people using the system.

…それを作ることができなくても、このアーキテクチャではAnemic Domain Modelは時として、すべてのビジネスロジックがサ

ービスに含まれていることがあり、ここではサービス自身は、DTOをドメインオブジェクトにマッピングするだけで、ビジネスロ

ジックがない場合があります。このケースでは、大量のビジネスロジックがドメインにまったく存在していないか、アプリケーシ

ョンサーバに存在していません。逆に、クライアントにビジネスロジックが存在するかもしれません。または、マニュアルの一部

Page 8: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 8

か、システム利用者の脳内に存在するかもしれません。

Architectures like the one being viewed tend to come with instructions of how to complete complex tasks by

editing data in many parts of the system. A stereotypical example of this would be when changing the sex of

an employee you must after go edit their health insurance information. This is far worse than the creation

of an anemic model, this is the creation of a glorified excel spreadsheet.

このようなアーキテクチャには、システムのあちこちでデータを編集することにより、複雑なタスクを完了するための命令が存在

する傾向があります。たとえば、従業員の性別を変更した後に、続いて従業員の健康保険情報の編集を行うといったものが、この

ステレオタイプな例でしょう。これは、Anemic Domain Modelを作るよりもはるかに悪く、Excelのスプレッドシートを作成す

るようなものです。

Scaling | 拡張性

When one looks at the architecture provided above in the context of scaling one will quickly notice that there

is a large bottle neck. The bottleneck in terms of scaling is the data storage. When using a RDBMS as 90%+

currently use this becomes even more of a problem most RDBMS are at this point not horizontally scalable and

vertically scaling becomes prohibitively expensive very quickly. It is however also extremely important to

remember that most systems do not need to scale and as such scalability is really not a grave issue in all

cases.

先述のアーキテクチャには、スケーリング(拡張)するときに大きなボトルネックを抱えることにすぐ気づきます。拡張性のボト

ルネックとなるのは、データストレージです。RDBMS使用時に使用率が90%以上になると、問題が顕著になります。ほとんどのRDBMS

はこの点において、横水平のスケーラビリティは無く、縦垂直のスケーリングにもひどい出費がかさみます。しかし、大部分のシ

ステムはスケーリングの必要がない点を考慮することもきわめて重要です。また、すべてのケースで、スケーラビリティ自体が重

大な問題になるわけではありません。

Summary | 概要

The DTO up/down architecture employed on many projects is capable of being used for many applications and

can offer many benefits in terms of simplicity for teams to work with. It cannot however be used with a Domain

Driven Design based project, to attempt so will bring failure to your efforts at applying Domain Driven Design.

多くのプロジェクトで採用しているDTOアップ/ダウン・アーキテクチャは、多くのアプリケーションで使用されていて、簡潔性

である点でチームに多くの利点をもたらします。しかし、ドメイン駆動設計ベースのオブジェクトでは、このアーキテクチャを使

うことができません。ドメイン駆動設計を適用しようと努力しても、失敗が目に見えるでしょう。

This architecture does however make a good baseline and the rest of this document will be focused on improving

this architecture in incremental steps while attempting to limit or remove cost while adding business value

at each additional step.

しかし、このアーキテクチャは良い議論材料です。以降、本書では、度重なるエンハンスにおいて、ビジネス価値の向上を図りつ

つコスト節約・削減を推進するために、このアーキテクチャに必要な改良点に焦点を当てて考えていきます。

Works Cited | 参考文献

Fowler, M. (2003, 11 25). MF Bliki: AnemicDomainModel. Retrieved from Bliki:

http://martinfowler.com/bliki/anemicdomainmodel

Page 9: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 9

Task Based User Interface | タスクベース・ユーザインタフェース

This chapter introduces the concept of a Task Based User Interface and compares it with a CRUD style user

interface. It also shows the changes that occur within the Application Server when a more task oriented style

is applied to it’s API.

本節では、タスクベースのユーザインタフェースの構想を紹介し、CRUDスタイルのユーザインタフェースと比較します。また、タ

スク指向スタイルをアプリケーションサーバのAPIに適用したときに、アプリケーションサーバで起こる変化について提示します。

One of the largest problems seen in “A Stereotypical Architecture” was that the intent of the user was lost.

Because the client interacted by posting data-centric DTOs back and forth with the Application Server, the

domain was unable to have any verbs in it. The domain had become a glorified abstraction of the data model.

There were no behaviors, the behaviors that existed, existed in the client, on pieces of paper, or in the

heads of the users of the software.

ステレオタイプなアーキテクチャに見られるもっとも深刻な問題の一つとして、ユーザの目的が失われる点が挙げられます。クラ

イアントとアプリケーションサーバは、DTOの送受信によるデータ中心の対話になるため、ドメイン内にはどんな動詞も持てませ

ん。ドメインはデータモデルの抽象概念として絶賛されましたが、アプリケーションサーバにはふるまいが存在せず、クライアン

ト、紙の断片または、ソフトウェアユーザの脳内にふるまいが存在しています。

Many examples of such applications can be cited. Users have “work flow” information documented for them. Go

to screen xyz edit foo to bar, then go to this other screen and edit xyz to abc. For many types of systems

this type of workflow is fine. These systems are also generally low value in terms of the business. In an

area that is sufficiently complex and high enough ROI in order to use Domain Driven Design these types of

workflows become unwieldy.

このようなアプリケーション例は、多くあります。これらの例では、ユーザは「ワークフロー」情報を持っています。「xyz」画面

に遷移し、編集して「foo」を「bar」に変更します。他の画面に遷移し、編集して「xyz」を「abc」に変更します。多くのシス

テムにあるこの種のワークフローは単純明快ですが、ビジネスに関しては一般的に価値が低いのです。ドメイン駆動設計を使うほ

どに非常に複雑かつ高いROI比率が求められる分野では、この種のワークフローは扱いづらいものです。

One reason that is commonly cited for wanting to build a system such as described is that “the business logic

and work flows can be changed at any time to anything without need of a change to the software”. While this

may be true it must be asked at what cost. What happens when someone misses a step in the process they have

in their head or you have multiple users who do it differently as is commonly the case? How do you get any

reasonable information out of a system in terms of reporting?

先述のようなシステムの構築が望まれる一般的な理由の一つは、「ビジネスロジックとワークフローは、ソフトウェアの変更なしに、

いつでも何にでも変えることができる」ということです。これが本当なら、何にコストがかかっているのかを見極める必要があり

ます。ソフトウェアユーザが脳内に持っているプロセスのステップを見落としたとき、または、一般的なケースとして、異なるこ

とを実行する様々なソフトウェアユーザを抱えているとき、何が起きるのでしょうか?レポートを報告する必要があるとき、正当

な情報をシステムから取り出せるでしょうか?

One way of dealing with this issue is to move away from the DTO up/down architecture that was illustrated

in a “Stereotypical Architecture”. Figure 4 shows the client interaction side of a DTO up/down architecture.

この問題を扱う方法の一つが、「ステレオタイプなアーキテクチャ」の節で例示した DTO アップ/ダウン・アーキテクチャから離

別することです。DTOアップ/ダウン・アーキテクチャにおけるクライアント対話を、図4に示します。

Page 10: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 10

Figure 4 Interaction in a DTO Up/Down Architecture | 図4 DTOアップ/ダウンによる対話 (図1と同じ)

The basic explanation of the operation is that the UI will request a DTO, say for Customer 1234 from the

Application Server. This DTO will be returned to the client and then shown on the screen. The user will interact

with the DTO in some way (likely either directly or through a View Model). Eventually the client will click

Save or some other trigger will occur and the client will take the DTO and send it back up to the Application

Server. The Application Server will then internally map the data back to the domain model and save the changes

returning a success or failure.

基本的な操作の説明をします。UIは顧客1234に関する情報を得るために、アプリケーションサーバにDTOを要求します。すると

このDTOがアプリケーションサーバから返ってきて、画面に表示されます。ユーザは直接またはビューモデルを介するなどの方法

で、DTOと対話するでしょう。次に、クライアントは[保存]ボタンをクリックするか、他の方法をトリガーにして、DTOを取り出

してアプリケーションサーバに返すでしょう。アプリケーションサーバは、そこで、データをドメインモデルにマッピングし、更

新した情報を格納し、成功または失敗をクライアントに返すでしょう。

As discussed the intention of the user is being lost because a DTO is being sent up that just represents the

current state of the object after the client’s actions are completed. It is possible to bring forward the

intention of the user; this will allow the Application Server to process behaviors as opposed to saving data.

Figure shows an interaction capturing intent.

先に議論したように、クライアントの操作完了後に、オブジェクトの現在のステートを表現するDTOを送る時点で、ユーザの意図

が失われているのです。ユーザの意図を伝えるためには、アプリケーションサーバにはデータを格納する機能とは対比的なものと

して、ふるまいを処理する機能を与えることです。ユーザの意図を汲んだ対話を、図示します。

Page 11: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 11

Figure 5 Behavioral Interface | 図5 ふるまいのインタフェース

Capturing intent the client interaction is very similar to the DTO up/down methodology in terms of interactions.

The client first quests a DTO from the Application Server for instance Customer 1234. The Application Server

returns a DTO representing the customer that is then shown on the screen for the user to interact with usually

either directly or through a View Model. The similarities however stop at this point.

クライアント対話の意図を汲むといっても、DTOアップ/ダウン方法論における対話と酷似しています。クライアントはまず、アプ

リケーションサーバに顧客1234の情報をDTOで問い合わせます。アプリケーションサーバからその顧客を表現するDTOが返され

ると、その情報が画面上に表示され、直接またはビューモデルを介してユーザと対話します。しかし、類似点はこれだけです。

Instead of simply sending the same DTO back up when the user is completed with their action the client needs

to send a message to the Application Server telling it to do something. It could be to “Complete a Sale”,

“Approve a Purchase Order”, “Submit a Loan Application”. Said simply the client needs to send a message to

the Application Server to have it complete the task that the user would like to complete. By telling the

Application Server what the user would like to do, it is possible to know the intention of the user.

同じDTOを単純に送り返すのではなく、クライアントはユーザ操作が完了後にアプリケーションサーバに何かを処理するのかをメ

ッセージとして送るのです。メッセージとしては「販売完了」、「購入命令の承認」や「ローン申請の提出」などがあります。簡単

に言うと、クライアントからアプリケーションサーバにメッセージを送って、ユーザが完了したいタスクを伝える必要があるとい

うことです。ユーザが何をしたいのかをアプリケーションサーバに話すことにより、ユーザの意図がわかるわけです。

Commands | コマンド

The method through which the Application Server will be told what to do is through the use of a Command. A

command is a simple object with a name of an operation and the data required to perform that operation. Many

think of Commands as being Serializable Method Calls. Listing 1 includes the code of a basic command.

アプリケーションサーバが何をするかを伝える方法として、コマンドを使います。コマンドは、処理に必要なデータと、処理の名

前を持つ簡易なオブジェクトです。多くのチームメンバーは、コマンドを「シリアライズ化を行うメソッドの呼び出し

(Serializable Method Call)」とみなしています。リスト1は基本的なコマンドのコードの一部です。

public class DeactivateInventoryItemCommand {

public readonly Guid InventoryItemId;

public readononly string Comment;

public DeactivateInventoryItemCommand(Guid id, string comment) {

InventoryItemId = id;

Comment = comment;

}

Listing 1 A Simple Command | リスト1 簡易なコマンド

As a side note the example in Listing 1 includes the pattern name after the name of the Command. This is a

decision that has many positives and negatives both linguistically and operationally. The choice over whether

to use a pattern name in a class name is one that should not be taken lightly by a development team.

補足としてリスト1のサンプルは、コマンド名の後にパターン名があります。この命名方法には、言語学と操作上、多くの賛否両

論があります。クラス名にパターン名を使用するかどうかの選択は、開発チームにとっては軽視すべきではありません。

One important aspect of Commands is that they are always in the imperative tense; that is they are telling

the Application Server to do something. The linguistics with Commands are important. A situation could for

with a disconnected client where something has already happened such as a sale and could want to send up a

“SaleOccurred” Command object. When analyzing this, is the domain allowed to say no that this thing did not

happen? Placing Commands in the imperative tense linguistically shows that the Application Server is allowed

to reject the Command, if it were not allowed to, it would be an Event for more information on this see “Events”.

コマンドの重要な面の一つとして、常に命令口調であるということです。つまり、アプリケーションサーバに命令するということ

です。コマンドの言語学は重要です。たとえば切断しているクライアントで、すでに販売に関して何らかの処理が発生していて、

SaleOccurredコマンドオブジェクトを送信したかった状態としよう。これを考えると、ドメインはこの命令が起こらなかったこ

Page 12: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 12

とにしていいわけではありません。コマンドを言語学的に命令口調にするということは、アプリケーションサーバはコマンドを拒

否できるということです。もし、拒否できなかったとしたら、それはイベントでしょう。イベントの詳細は「イベント」を参照し

てください。

Occasionally there exist funny examples of language in English. A perfect example of this would be “Purchase”

which can be used either as a verb in the imperative or as a noun describing the result of its usage in the

imperative. When dealing with these situations, ensure that the concept being pushed forward represents the

imperative of the verb and not the noun. As an example a purchase should be including what to purchase and

expecting the domain to possibly fill in some information like when the item was purchased as opposed to sending

up a purchase DTO that fully describes the purchase.

時折、英語に妙な例があります。代表例として、「Purchase(購入)」は命令形の動詞として使う場合もあれば、命令した結果とし

ての名詞として使う場合もあります。このような状況に対処するときは、先述したようにコマンドの概念は動詞の命令であって、

名詞ではないことを思い出してください。たとえば、「Purchase」には「何を購入するか」が含まれているべきです。また、

購入に関する DTO を送信することの対比として、「商品が購入された」という情報が送信されることをドメインに期待するべきで

す。

The simple Command in Listing 1 includes two data properties. It includes an Id which represents the

InventoryItem it will apply to and it includes a comment as to why the item is being deactivated. The comment

is quite typical of an attribute associated with a Command, it is a piece of data that is required in order

to process the behavior. There should only exist on a Command data points that are required to process the

given behavior. This contrasts greatly with the typical architecture where the entire data of the object is

passed back to the Application Server.

リスト 1の簡易なコマンドには 2つの特性があり、それぞれインベントリアイテムの ID情報と、インベントリアイテムを非アク

ティブ化する理由を示すコメント情報を保持します。コメント情報は、コマンドの属性としてよく使われるものでありがあり、ふ

るまいを処理するために必要なデータです。コマンドには、ふるまいの処理に必要な情報だけを持つべきです。典型的なアーキテ

クチャではオブジェクト全体のデータをアプリケーションサーバに渡しますが、これとは対比的なものです。

Most importantly of the data is the Id of the associated inventory item. At least one Id must exist for all

commands that are updating state in some way, as all commands are intended to be routed to an object. When

issuing a Create Command it is not necessary though valuable to include an Id. Having the client originate

Ids normally in the form of UUIDs is extremely valuable in distributed systems.

インベントリアイテムに紐付けられたIDが最も重要です。少なくともすべてのコマンドにこのようなIDが存在し、ステートを更

新するために必要です。すべてのコマンドは、オブジェクトに送信する意図があるのです。コマンドを生成するときは、必ずしも

IDに値が格納されている必要がありません。通常、クライアントが UUID形式の IDを生成することは、分散システムでは非常に

重要です。

It is quite common for developers to learn about Commands and to very quickly start creating Commands using

vocabulary familiar to them such as “ChangeAddress”, “CreateUser”, or “DeleteClass”. This should be avoided

as a default. Instead a team should be focused on what the use case really is.

開発者がコマンドを学ぶことは本当に一般的であり、「ChangeAddress」「CreateUser」または「DeleteClass」のようななじみ

が深い名前のコマンドをすぐ作成しがちです。しかし、これは避けるべきです。チームは本当の使用場面が何であるか、に焦点を

当てるべきです。

Is it “ChangeAddress”? Is there a difference between “Correcting an Address” and “Relocating the Customer”?

It likely will be if the domain in question is for a telephone company that sends the yellow pages to a customer

when they move to a new location.

使用場面が「ChangeAdress」なのか?「Correcting an Address(住所の修正)」と「Relocating the Customer(顧客の再

配置)」に違いがないか?顧客が新しい住所に引っ越すときにイエローページを送付する電話会社などのドメインで問題が起きそう

です。

Is it “CreateUser” or is it “RegisterUser”? “DeleteClass” or “DeregisterStudent”. This process in naming can

lead to great amounts of domain insight. To begin defining Commands, the best place to begin is in defining

use cases, as generally a Command and a use case align.

「CreateUser(ユーザの作成)」と「RegisterUser(ユーザの登録)」のどちらか?コマンドに名前を付けるというプロセスは、

Page 13: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 13

非常に多くのドメインにおいて、深い洞察につながります。一般的には、コマンドとユースケースを整理してから、ユースケース

を定義すると同時にコマンドを定義するのが最適です。

It is also important to note that sometimes the only use case that exists for a portion of data is to “create”,

“edit”, “update”, “change”, or “delete” it. All applications carry information that is simply supporting

information. It is important though to not fall into the trap of mistaking places where there are use cases

associated with intent for these CRUD only places.

一部のデータについては、「create(作成)」「edit(編集)」「update(更新)」「change(変更)」または「delete(削除)」が、

唯一のユースケースになる場合があることに注意してください。すべてのアプリケーションでは、情報を単純に補足するだけの情

報を持ち運びます。しかし、CRUDしかないにもかかわらず、そのユースケースに意図があると勘違いするという罠に陥らないよう

にすることが重要です。

Commands as a concept are not difficult but are different for many developers. Many developers see the creation

of the Commands as a lot of work. If the creation of Commands is a bottleneck in the workflow, many of the

ideas being discussed are likely being applied in an incorrect location.

概念としてのコマンドは難しくありませんが、多くの開発者の間で概念が異なります。多くの開発者は、コマンドを作成するのは

コストが高い作業と考えています。もし、コマンドを作成することがワークフローにおけるボトルネックであるなら、おそらく、

検討中のアイデアが不適切でしょう。

User Interface | ユーザインタフェース

In order to build up Commands the User Interface will generally work a bit differently than in a DTO up/down

system. Because the UI must build Command objects it needs to be designed in such a way that the user intent

can be derived from the actions of the user.

コマンドを構築するにあたって、ユーザインタフェースは、一般的に、DTOアップ/ダウンシステムとは少し異なるものになりま

す。UIはコマンドオブジェクトを構築する必要があるため、ユーザの意図がユーザのアクションに由来したものとなるようUIを

設計する必要があります

The way to solve this is to lean more towards a “Task Based User Interface” also known as an “Inductive User

Interface” in the Microsoft world. This style of UI is not by any means new and offers a quite different

perspective on the design of user interfaces. Microsoft identified three major problems with Deductive UIs

when researching Inductive UIs.

これを解決するためには、「タスクベース・ユーザーインタフェース」(別名:Microsoft 界の「帰納的ユーザインタフェース」)

に傾斜することです。この UI スタイルは決して目新しいものではありませんが、まったく異なる考え方のユーザインタフェース

を提供します。Microsoft社は、帰納的UIの研究にあたり、演繹的なUIの3つの主な問題点を見極めました。

Users don't seem to construct an adequate mental model of the product. The interface design for most current

software products assumes that users will understand a conceptual model that the designers carefully crafted.

Unfortunately, most users don't seem to ever acquire a mental model that is thorough and accurate enough to

guide their navigation. These users aren't dumb — they are just very busy and overloaded with information.

They do not have the time, energy, or desire to wonder about a conceptual model for their software.

ユーザは製品の十分なメンタルモデルを作らないようだ:現在のほとんどのソフトウェア製品のインタフェース設計は、デザイナ

が慎重に巧みに作れば、ユーザは概念モデルを理解すると決めてかかっています。残念なことに、ほとんどのユーザは、インタフ

ェースによるナビゲーションを導くのに十分な完全かつ正確なメンタルモデルを取得していないようです。これらのユーザは、非

常に多忙で、情報に惑わされているのであって、まぬけというわけではありません。ソフトウェアの概念モデルについて探求する

時間、エネルギーや欲求がないのです。

Even many long-time users never master common procedures. Designers know that new users may have trouble at

first, but expect these problems to vanish as users learn common tasks. Usability data indicates this often

doesn't happen. In one study, researchers set up automated equipment to videotape users at home. The tapes

showed that users focusing on the task at hand do not necessarily notice the procedure they are following

and do not learn from the experience. The next time users perform the same operation, they may stumble through

it in exactly the same way.

多くのユーザは経験が長くても、決して一般的な手順をマスターしない:新しいユーザは最初にトラブルを抱えますが、学ぶにつ

Page 14: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 14

れてトラブルが消えていくことを、デザイナは知っています。データがユーザビリティであれば、トラブルが起きにくいことを示

しています。ある研究では、研究者がビデオを設置して、ユーザを自動撮影しました。手元の仕事に集中しているユーザは、経験

がない手順に必ずしも気付くとは限らないことが明らかになりました。次回にユーザが同じ操作を行う時も、まったく同じ方法で

つまずくのです。

Users must work hard to figure out each feature or screen. Most software products are designed for (the few)

users who understand its conceptual model and have mastered common procedures. For the majority of customers,

each feature or procedure is a frustrating, unwanted puzzle. Users might assume these puzzles are an unavoidable

cost of using computers, but they would certainly be happier without this burden. (Microsoft Corporation,

2001)

ユーザは機能や画面を理解するのが困難である:多くのソフトウェア製品は、その概念モデルを理解していて、一般的な手順をマ

スターしている(少数の)ユーザ向けに設計されています。大多数の顧客にとって、各々の特徴や手順は、苛立たしい不必要なパ

ズルそのものです。ユーザは、コンピュータを使うからには、このパズルは不可避なコストだと思い込んでいるでしょう。しかし、

この重荷がなければ、確かに幸せでしょう。 (マイクロソフト社, 2001)

The basic idea behind a Task Based or Inductive UI is that it's important to figure out how the users want

to use the software and to make it guide them through those processes.

タスクベース UI(または帰納的 UI)の基本的な考え方としては、ユーザがどのようにソフトウェアを使いたいのかを把握するこ

と、プロセスを通して使用方法を導くことの2つが重要です。

Many commercial software applications include user interfaces in which a screen presents a set of controls,

but leaves it to the user to deduce the page's purpose and how to use the controls to accomplish that purpose.

(Microsoft Corporation, 2001)

多くの商用ソフトウェアアプリケーションは、コントロールを配置した画面でユーザインタフェースを提供しています。しかし、

ページの目的と、その目的を果たすためのコントロールの使い方を、ユーザに演繹させています。 (Microsoft Corporation,

2001)

The goal is to guide the user through the process. An example of the differences can be seen in the

DeactivateInventoryItem example previously shown. A typical deductive UI might have an editable data grid

containing all of the inventory items. It would have editable fields for various data and perhaps a drop down

for the status of the inventory item, deactivated being one of them. In order to deactivate an inventory item

the user would have to go to the item in the grid, type in a comment as to why they were deactivating it and

then change the drop down to the status of deactivated. A similar example could be where you click to a screen

to edit an inventory item but go through the same process as seen in Figure 6.

プロセスを通してユーザを導くのが、タスクベース UI の目標です。演繹的 UI とタスクベース UI の相違点の例として、先述の

DeactivateInventoryItemサンプルを使って説明します。典型的な演繹的 UIでは、すべてのインベントリアイテムを含む、編

集可能なデータグリッド(コントロールの一種)を使うでしょう。また、様々なデータを編集するためのフィールドや、インベン

トリアイテムのアクティブ状態を変更するためのコンボボックスがあるでしょう。インベントリアイテムを非アクティブ化したい

場合、ユーザはグリッドでインベントリアイテムを選択し、非アクティブ化する理由を入力して、コンボボックスで「非アクティ

ブ化」を選択するでしょう。他にも、画面上をクリックすると、図6の画面を表示し、インベントリアイテムを編集させる類似例

もあるでしょう。

Figure 6 A CRUD screen for an Inventory Item | 図6 インベントリアイテムを編集するCRUD画面

Page 15: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 15

If the user attempts to submit an item that is “deactivated” and has not entered a comment they will receive

an error saying that they must enter a comment as it is a mandatory field for a deactivated item. Some UIs

might be a bit more user friendly, they may not show the comment field until the user selects deactivated

from the drop down at which point it would appear on the screen. This is far more intuitive to the user as

it is a cue that they should be putting data in that field but one can do even better.

もし、コメントを入力せずに、非アクティブ化するインベントアイテムをサブミット(提出)しようとしたら、コメントの入力が

必須であることを指摘するエラーを受け取るでしょう。もう少しユーザフレンドリーな(ユーザ親和性が高い)UIでは、非アクテ

ィブ化することを選択しない限り、コメント入力欄を表示しないでしょう。データを入力すべきであるという合図があると、より

直感的になりますが、もっとうまくできるはずです。

Figure 7 Listing Screen with Link | 図7 リンク付きのリスト画面

A Task Based UI would take a different approach, likely it would show a list of inventory items, next to an

inventory item there might be a link to “deactivate” the item as seen in Figure 7. This link would take them

to a screen that would then ask them for a comment as to why they are deactivating the items which is shown

in Figure 8. he intent of the user is clear in this case and the software is guiding them through the process

of deactivating an inventory item. It is also very easy to build Commands representing the user’s intentions

with this style of interface.

タスクベース UI は、異なるアプローチを採るでしょう。たとえば、インベントリアイテムのリストがあり、非アクティブ化する

ためのリンクがあります(図7)。このリンクをクリックすると、インベントリアイテムを非アクティブ化する理由を入力する画面

が表示されます(図8)。このケースだとユーザの意図が明確であり、ソフトウェアがインベントリアイテムの非アクティブ化する

プロセスを導いてくれます。また、このインタフェーススタイルだと、ユーザの意図に沿ったコマンドを構築するのが簡単です。

Figure 8 Deactivating an Inventory Item | インベントリアイテムの非アクティブ化

Web, Mobile, and especially Mac UIs have been trending towards the direction of being task based. The UI guides

you through a process and offers you contextually sensitive guidance pushing you in the right direction. This

is largely due to the style offering the capability of a much better user experience. There is a solid focus

on how and why the user is using the software; the user’s experience becomes an integral part of the process.

Beyond this there is also value on focusing more in general on how the user wants to use the software; this

is a great first step in defining some of the verbs of the domain.

Web、モバイルおよび特にMacでは、タスクベースUIを採用する傾向があります。そのUIはプロセスを導き、コンテキストに敏

感に沿う形で適切な方向に導く手引きを提供します。これは、主に、非常に優れたユーザ経験能力を提供するスタイルのおかげで

す。ユーザがソフトウェアをなぜ、どのように使用しているのかにしっかりと焦点を当てています。ユーザ経験は、プロセスには

必須な部分です。さらに、一般にユーザがソフトウェアをどのように使いたいのかに、より焦点を当てることにも価値があります。

これはドメインのいくつかの動詞を定義するための大きな最初の一歩です。

Page 16: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 16

Works Cited | 参考文献

Microsoft Corporation. (2001, Feb 9). Microsoft Inductive User Interface Guidelines. Retrieved from

MSDN: http://msdn.microsoft.com/en-us/library/ms997506

Page 17: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 17

Command and Query Responsibility Segregation | コマンドクエリ債務分離

This chapter will introduce the concept of Command and Query Responsibility Segregation. It will look at how

the separation of roles in the system can lead towards a much more effective architecture. It will also analyze

some of the different architectural properties that exist in systems where CQRS has been applied.

本節では、コマンドクエリ債務分離の概念を紹介します。非常に有効なアーキテクチャに導くために、システムにおいてどのよう

にロールを分離すればよいかを考察します。また、CQRSを適用したシステムについて、いくつかのアーキテクチャ上の特性を分析

します。

Origins | 起源

Command and Query Responsibility Segregation (CQRS) originated with Bertrand Meyer’s Command and Query

Separation Principle. Wikipedia defines the principle as:

コマンドクエリ債務分離(CQRS)は、Betrand Meyer氏のコマンドクエリ分離(CQS)主義に基づいています。CQS主義について

は、Wikipediaでは次のように記述しています。

It states that every method should either be a command that performs an action, or a query that returns data

to the caller, but not both. In other words, asking a question should not change the answer. More formally,

methods should return a value only if they are referentially transparent and hence possess no side effects.

(Wikipedia)

各メソッドは、アクションを処理するコマンドまたは、データを呼び出し側に返すクエリーのどちらかであるべきと述べています。

メソッドが両方を担うべきではありません。言い換えると、質問を投げるたびに、答えを変えるべきではありません。透明かつ副

作用をもたらさないように、メソッドは値を返すだけに留めるべきです。(Wikipedia)

Basically it boils down to. If you have a return value you cannot mutate state. If you mutate state your return

type must be void. There can be some issues with this. Martin Fowler shows one example on the bliki with:

要約します。復帰値を使ってステートを変更することはできません。また、ステートを変更する場合は、復帰値は無効でなければ

なりません。これについて、いくつかの問題があります。Martin Fowler氏はblikiでサンプルを示しています。

Meyer likes to use command-query separation absolutely, but there are exceptions. Popping a stack is a good

example of a modifier that modifies state. Meyer correctly says that you can avoid having this method, but

it is a useful idiom. So I prefer to follow this principle when I can, but I'm prepared to break it to get

my pop. (Fowler)

Meyer氏は、CQSを使うのを絶対的に好んでいますが、例外があります。スタックからの取り出しは、ステートを変更する良い例

です。Meyer氏は、この方法は回避可能だと言っていますが、有用なイディオムに過ぎません。よって、私は可能な限りこの主義

に従うのを好みますが、スタックからの取り出しにおいてはこの主義を破る用意があります。(Fowler氏)

Command and Query Responsibility Segregation was originally considered just to be an extension of this concept.

For a long time it was discussed simply as CQS at a higher level. Eventually after much confusion between

the two concepts it was correctly deemed to be a different pattern.

コマンドクエリ債務分離は、当初、この概念の拡張であると考えられ、長い間、CQS の上位レベルとして議論されました。この 2

つの概念で様々な混乱がありましたが、正確には異なるパターンであると結論づけられました。

Command and Query Responsibility Segregation uses the same definition of Commands and Queries that Meyer used

and maintains the viewpoint that they should be pure. The fundamental difference is that in CQRS objects are

split into two objects, one containing the Commands one containing the Queries.

CQRSはMeyer氏のコマンドとクエリと同じ定義を使いますが、この2つは純粋であるべきという視点を貫いています。CQRSでは、

CQSと異なり、オブジェクトを2種類に分けます。(複数の)コマンドを持つオブジェクトと、(複数の)クエリを持つオブジェクト

です。

The pattern although not very interesting in and of itself becomes extremely interesting when viewed from

an architectural point of view.

そのパターンはそれ自体にはあまり興味を引くものではありませんが、アーキテクチャ上の観点から見ると、極めて興味深いもの

です。

Page 18: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 18

Figure 9 Stereotypical Architecture | 図9 ステレオタイプ・アーキテクチャ (図1と同じ)

Figure 9 contains the stereotypical architecture discussed in the first chapter. One key aspect of the

architecture is that the service handles both commands and queries. More often than not the domain is also

being used for both commands and queries. The application of CQRS to this architecture although quite simple

in definition will drastically change architectural opportunities. A simple service to transform is in Listing

2.

図9はステレオタイプなアーキテクチャを示しています(図1と同じ)。サービスがコマンドとクエリーの両方を担っているのが、

このアーキテクチャの特徴の 1 つです。ドメインもコマンドとクエリーの両方で使われています。CQRS アプリケーションとステ

レオタイプなアーキテクチャとでは、定義の違いは単純明快ですが、CQRSへのアーキテクチャ上の変更は徹底しています(複雑で

す)。簡単なサンプルをリスト2に示します。

CustomerService

void MakeCustomerPreferred(CustomerId)

Customer GetCustomer(CustomerId)

CustomerSet GetCustomersWithName(Name)

CustomerSet GetPreferredCustomers()

void ChangeCustomerLocale(CustomerId, NewLocale)

void CreateCustomer(Customer)

void EditCustomerDetails(CustomerDetails)

Listing 2 Original Customer Service | リスト2 オリジナルのカスタマサービス

Applying CQRS on the CustomerService would result in two services as shown in Listing 2.

リスト2のCustomerServiceにCQRSを適用すると、リスト3のように2つのサービスに分離します。

CustomerWriteService

void MakeCustomerPreferred(CustomerId)

void ChangeCustomerLocale(CustomerId, NewLocale)

void CreateCustomer(Customer)

void EditCustomerDetails(CustomerDetails)

CustomerReadService

Customer GetCustomer(CustomerId)

CustomerSet GetCustomersWithName(Name)

CustomerSet GetPreferredCustomers()

Page 19: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 19

Listing 3 Customer Service after CQRS | リスト3 CQRS適用後のカスタマサービス

While a relatively simple process, this will solve many of the problems that existed in the stereotypical

architecture. The service has been split into two separate services, a read side and a write side or the Command

side and the Query side.

比較的単純なプロセスですが、ステレオタイプなアーキテクチャに存在する多くの問題を解決します。サービスを2つの異なるサ

ービスに分離しました。この2つとは、書き出し側と読み込み側、または、コマンド側とクエリ側です。

This separation enforces the notion that the Command side and the Query side have very different needs. The

architectural properties associated with use cases on each side are tend to be quite different. Just to name

a few:

コマンド側とクエリ側には、非常に異なるニーズがあるので、分離するわけです。コマンド側とクエリ側それぞれのユースケース

には、アーキテクチャ特性がまったく異なる傾向があります。少し例を挙げます。

Consistency | 一貫性

Command: It is far easier to process transactions with consistent data than to handle all of the edge cases

that eventual consistency can bring into play.

Query: Most systems can be eventually consistent on the Query side.

コマンド:結果整合性が使う極限値(edge case)すべてを処理するよりも、整合性が取れているデータのトランザクション処理

の方が、はるかに簡単です。

クエリ:ほとんどのシステムは、最終的には首尾一貫した処理が可能です。

Data Storage | データストレージ

Command: The Command side being a transaction processor in a relational structure would want to store data

in a normalized way, probably near 3rd Normal Form (3NF)

Query: The Query side would want data in a denormalized way to minimize the number of joins needed to get

a given set of data. In a relational structure likely in 1st Normal Form (1NF)

コマンド:コマンド側では、リレーショナルデータ構造のトランザクション処理を行い、3rd Normal Form(3NF)などで正規化

したデータを格納することが好まれます。

クエリ:クエリ側では、非正規化したデータ一式を取得するのが好まれます。非正規化とは、データの結合数を最小限にする方法

です。1st Normal Form(1NF)などのリレーショナルデータ構造を使います。

(訳注:1NFや3NFはデータベースを構築する方法論。「Normalization of Database」などを参照のこと)

Scalability | スケーラビリティ

Command: In most systems, especially web systems, the Command side generally processes a very small number

of transactions as a percentage of the whole. Scalability therefore is not always important.

Query: In most systems, especially web systems, the Query side generally processes a very large number of

transactions as a percentage of the whole (often times 2 or more orders of magnitude). Scalabilityis most

often needed for the query side.

コマンド:ほとんどのシステム(特にWebシステム)では、コマンド側は一般的に、全体の比率としてはごく少数のトランザクシ

ョン処理しか行いません。したがって、スケーラビリティは必ずしも重要ではありません。

クエリ:ほとんどのシステム(特にWebシステム)では、クエリ側は一般的に、全体のかなりの比率(2桁以上)を占めるトラン

ザクション処理を行います。したがって、クエリ側ではスケーラビリティが重要です。

It is not possible to create an optimal solution for searching, reporting, and processing transactions utilizing

a single model.

検索、レポートやトランザクション処理を単一モデルで担うようなソリューションを、適切に構築するのは不可能です。

The Query Side | クエリ側

As stated, the Query side will only contain the methods for getting data. From the original architecture these

would be all of the methods that return DTOs that the client consumes to show on the screen.

先述の通り、クエリ側はデータを取得するメソッドを持つだけです。これらのメソッドは、クライアントが画面に表示するのに必

要なDTOsを返します。

Page 20: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 20

In the original architecture the building of DTOs was handled by projecting off of domain objects. This process

can lead to a lot of pain. A large source of the pain is that the DTOs are a different model than the domain

and as such require a mapping.

最初のアーキテクチャでは、DTOsはドメインオブジェクトへの投影のために使われました。この処理は大きな代償をもたします。

代償の主要な原因は、DTOsはマッピングのために生成されるものであって、ドメインとは異なるモデルだからです。

DTOs are optimally built to match the screens of the client to prevent multiple round trips with the server.

In cases with many clients it may be better to build a canonical model that all of the clients use. In either

case the DTO model is very different than the domain model that was built in order to represent and process

transactions.

サーバ側で往復の送受信を行わないようにするために、クライアントの画面にマッチする DTOs を生成します。多数のクライアン

トすべてに対応するように、共通のモデルを好んで構築しがちです。どちらしても、DTOモデルはトランザクションの表現や処理

を行うために構築されたものであり、ドメインモデルとは非常に異なります。

Common smells of the problems can be found in many domains.

多くのドメインには、共通の問題の前触れを検出できます。

Large numbers of read methods on repositories often also including paging or sorting information.

Getters exposing the internal state of domain objects in order to build DTOs.

Use of prefetch paths on the read use cases as they require more data to be loaded by the ORM.

Loading of multiple aggregate roots to build a DTO causes non-optimal querying to the data model.

Alternatively aggregate boundaries can be confused because of the DTO building operations

リポジトリ上の読み込み用メソッドの多くは、ページ番号やソート情報も扱います。

getterはDTOsを生成するために、ドメインオブジェクトの内部ステートを露出します。

読み込み処理のユースケースでは、ORMで多くのデータをロードする際に、プレフェッチ経路を使います。

DTO を生成する際に複数のアグリゲートルート(aggregate roots)をロードするため、データモデルに対して不適切なク

エリを実行します。または、DTO生成処理のために、アグリゲートの境界が複雑化します。(訳注:aggregateについては、

ドメイン駆動設計などを参照)

The largest smell though is that the optimization of queries is extremely difficult. Because queries are

operating on an object model then being translated to a data model, likely by an ORM it can become difficult

to optimize these queries. A developer needs to have intimate knowledge of the ORM and the database. The developer

is dealing with a problem of Impedance Mismatch (for more discussion see “Events as a Storage Mechanism”).

しかし、最も大きな前触れは、クエリの最適化が非常に困難であるということです。オブジェクトモデルでクエリを処理し、デー

タモデルに変換するため、ORMのようにクエリの最適化が困難になります。開発者はORMやデータベースに関する深い知識が必要

であり、Impedance Mismatchの問題に悩まされることになります。詳細は「ストレージメカニズムにおけるイベント」で扱いま

す。

After CQRS has been applied there is a natural boundary. Separate paths have been made explicit. It makes

a lot of sense now to not use the domain to project DTOs. Instead it is possible to introduce a new way of

projecting DTOs.

CQRSを適用すれば、自然に境界線ができます。分離した経路が明確になります。DTOsを投影するためのドメインが不要になると

いう大きな価値をもたらします。代わりに、DTOsを投影する新しい方法の導入を可能にします。

Page 21: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 21

Figure 10 The Query Side | 図10クエリ側

The domain has been bypassed. There is now a new concept called a “Thin Read Layer”. This layer reads directly

from the database and projects DTOs. There are many ways that this can be done with handwritten ADO.NET and

mapping code and a full blown ORM on the high end. Which choice is right for a team depends largely on the

team itself and what they are most comfortable with. Likely the best solution is something in the middle as

much of what an ORM provides is not needed and large amounts of time will be lost manually creating mapping

code. A possible solution would be to use a small convention based mapping utility.

図10の通り、クエリ側ではドメインを使わずに迂回します。新しい概念の「Thin Read Layer(薄い読み取り層)」では、データ

ベースから直接読み込み、DTOsに投影します。ADO.NETでは様々なDTOsへの投影方法をプログラミング可能であり、ハイエンド

上でコードとfull-blown ORMの間でマッピング可能です。どちらを選択するがチームによって良いのか、また、何がチームにと

ってもっとも良いのか?ORMが提供しているものは不要ですし、マッピング処理のプログラミングに膨大な時間を浪費してしまい

ます。ベストの解決策はおそらく、ミドル層でORMと同じような機能を提供する何かのものです。解決策としてあり得るのは、小

さな規約をベースとしたマッピングユーティリティを使うことです。

The Thin Read Layer need not be isolated from the database, it is not necessarily a bad thing to be tied to

a database vendor from the read layer. It is also not necessarily bad to use stored procedures for reading,

it again depends on the team and the non-functional requirements of the system.

Thin Read Layerは、データベースから分離する必要はありません。Thin Read Layerからデータベースのベンダーと結びつく

のは、必ずしも悪いわけではありません。データを読み込むためにストアドプロシージャを使うことも必ずしも悪いわけではあり

ません。システムの非機能要件やチームによって違います。

The Thin Read Layer is not a complex piece of code although it can be tedious to maintain. One benefit of

the separate read layer is that it will not suffer from an impedance mismatch. It is connected directly to

the data model, this can make queries much easier to optimize. Developers working on the Query side of the

system also do not need to understand the domain model nor whatever ORM tool is being used. At the simplest

level they would need to understand only the data model.

Thin Read Layerは複雑ではありませんが、保守が面倒(長ったらしい)です。分離した Thin Read Layerの利点の 1つは、

Impedance Mismatch で苦しむことがないということです。データモデルに直接接続し、クエリを非常に簡単に最適化できます。

システムのクエリ側を担当する開発者は、ドメインモデルも、使用されているどんなORMツールも理解する必要はなく、データモ

デルだけを理解すればよいのです。

The separation of the Thin Read Layer and the bypassing of the domain for reads allows also for the specialization

of the domain.

Page 22: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 22

データの読み込みのために、Thin Read Layer を分離することと、ドメインを迂回することは、ドメインの専門化につながりま

す(訳注:専門化=ドメインはクエリ側を意識しないで設計可能になるという意味だと思われる)。

The Command Side | コマンド側

Overall the Command side remains very similar to the “Stereotypical Architecture”. The illustration in Figure

3 should look nearly identical to the previously discussed architecture. The main differences are that it

now has a behavioral as opposed to a data centric contract which was needed in order actually use Domain Driven

Design and it has had the reads separated out of it.

コマンド側全体は、ステレオタイプなアーキテクチャに似た形に留めています。図 11 は、先に図示したアーキテクチャに似てい

ますが、少し異なります。実際にドメイン駆動デザインで必要としていた「データ中心の設計」ではデータの読み込みも行ってい

ましたが、今回のコマンド側ではデータの読み込みを分離しています。

Figure 11 The Command Side | 図11 コマンド側

In the “Stereotypical Architecture” the domain was handling both Commands and Queries, this caused many issues

within the domain itself. Some of those issues were:

ステレオタイプなアーキテクチャでは、ドメインはコマンドもクエリも処理していて、多くの問題の温床となっていました。いく

つかの問題を、次に列挙します。

Large numbers of read methods on repositories often also including paging or sorting information.

Getters exposing the internal state of domain objects in order to build DTOs.

Use of prefetch paths on the read use cases as they require more data to be loaded by the ORM.

Loading of multiple aggregates to build a DTO causes non-optimal querying to the data model. Alternatively

aggregate boundaries can be confused because of the DTO building operations

リポジトリ上の読み込み用メソッドの多くは、ページ番号やソート情報もよく扱います。

getterメソッドは、DTOsを生成するために、ドメインの内部ステートを晒します。

ORMで多くのデータをロードするため、読み込み処理のユースケースでプレフェッチ経路を使います。

DTOsを生成する際に複数のアグリゲートをロードするので、データモデルに対するクエリが最適化されません。または、DTO

生成処理のせいで、アグリゲートの境界が混乱しやすくなります。

Once the read layer has been separated the domain will only focus on the processing of Commands. These issues

also suddenly go away. Domain objects suddenly no longer have a need to expose internal state, repositories

Page 23: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 23

have very few if any query methods aside from GetById, and a more behavioral focus can be had on Aggregate

boundaries.

一度、読み込みレイヤをドメインから分離すれば、コマンドの処理だけに焦点が当たります。すると、上記の問題を解消します。

ドメインオブジェクトは内部ステートを晒す必要がなく、リポジトリでは GetByIdを除くとクエリ用メソッドはわずかだけです。

また、アグリゲートの境界は、今まで以上にふるまいに焦点が絞れます。

This change has been done at a lower or no cost in comparison to the original architecture. In many cases

the separation will actually lower costs as the optimization of queries is simpler in the thin read layer

than it would be if implemented in the domain model. The architecture also carries lower conceptual overhead

when working with the domain model as the querying is separated; this can also lead towards a lower cost.

In the worst case, the cost should work out to be equal; all that has really been done is the moving of a

responsibility, it is feasible to even have the read side still use the domain.

元のアーキテクチャに対する変更は、わずかなコストで済みます。ドメインモデルで実装するよりも Thin Read Layerにてクエ

リを最適化するほうが簡易になるのと同様、この分離により多くの場面で実際にコストが減ります。このアーキテクチャは、クエ

リを分離したドメインモデルで作業すれば、概念的なオーバヘッドが減り、コスト軽減につながります。最悪でもコストが等しく

なるようにうまくやるべきです。本当に実施するべき作業は、「債務の移動」です。ただし、クエリ側にドメインを使わせるのは、

依然として可能です。

By applying CQRS the concepts of Reads and Writes have been separated. It really begs the question of whether

the two should exist reading the same data model or perhaps they can be treated as if they were two integrated

systems, Figure 5 illustrates this concept. There are many well known integration patterns between multiple

data sources in order to maintain synchronisity either in a consistent or eventually consistent fashion. The

two distinct data sources allow the data models to be optimized to the task at hand. As an example the Read

side can be modeled in 1NF and the transactional model could be modeled in 3nf.

CQRS を適用することによって、読み込みと書き出しの概念を分離します。すると、同一データモデルからの読み込みにこの 2 つ

を混在させるべきかどうか、または、2つの統合化システムとして扱うかという議論を喚起します。概要を図12に示します。一貫

した方法で複数のデータソース間を同期化するための有名な「統合パターン」が多くあります。2 つの異なるデータソースは、シ

ステム処理向けにデータモデルをすぐ最適化できます。たとえば、読み込み側は1NFで構築可能であり、トランザクションモデル

も3NFで構築可能です。

The choice of integration model though is very important as translation and synchronization between models

can be become a very expensive undertaking. The model that is best suited is the introduction of events, events

are a well known integration pattern and offer the best mechanism for model synchronization.

モデル間の変換・同期が高負荷な処理であっても、統合モデルの選択は非常に重要です。イベントの導入が最良です。イベントは

有名な統合パターンであり、モデルを同期する最良のメカニズムを提供します。

Page 24: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 24

Figure 12 Separated Data Models with CQRS | 図12 CQRSでのデータモデル分離

Page 25: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 25

Events as a Storage Mechanism | ストレージメカニズムにおけるイベント

Most systems in production today rely on the storing of current state in order to process transactions. In

fact it is rare to meet a developer who has worked on a system that maintains current state in any other way.

It has not always been like this.

今日の製品のほとんどのシステムは、トランザクション処理を行うために、現在のステートを保持します。実際、それ以外の方法

で現在のステートを維持するシステム作成に携わった開発者は珍しく、必ずしもこうとは限りません。

Before the general acceptance of the RDBMS as the center of the architecture many systems did not store current

state. This was especially true in high performance, mission critical, and/or highly secure systems. In fact

if we look at the inner workings of a RDBMS we will find that most RDBMSs themselves not actually work by

managing current state!

アーキテクチャの中心部としてのRDBMSが世間広く知られる前は、多くのシステムでは現在のステートを保存していませんでした。

特に高性能、ミッションクリティカル、かつ/または、セキュアなシステムに当てはまります。実際、RDBMS の内部処理を見れば

わかるように、ほとんどのRDBMSでは、自ら現在のステートを管理しているわけではないのです!

The goal of this section is to introduce the concept of event sourcing, to show the benefits, to show how

a simple event storage system can be created utilizing a Relational Database for underlying data management.

本章では、イベント発行の概念とその利点を紹介します。また、データ管理の基盤であるリレーショナルデータベースを利用した、

単純なイベントストレージシステムを構築する方法を説明します。

What is a Domain Event? | ドメインイベントとは

An event is something that has happened in the past.

イベントとは、過去に発生した事柄です。

All events should be represented as verbs in the past tense such as CustomerRelocated, CargoShipped, or

InventoryLossageRecorded. For those who speak French, it should be in Passé Composé, they are things that

have completed in the past. There are interesting examples in the English language where it is tempting to

use nouns as opposed to verbs in the past tense, an example of this would be “Earthquake” or “Capsize”, as

a congressman recently worried about Guam, but avoid the temptation to use names like this and stick with

the usage of verbs in the past tense when creating Domain Events.

すべてのイベントは、たとえば、CustomerRelocated、CargoShippedまたはInventoryLossageRecordedというふうに過去形

の動詞で表現しなければなりません。フランス語であれば、過去に完了したものを意味する Passé Composéで表現しなければな

りません。英語での興味深い例として、過去形の動詞に相反して名詞を使いたい衝動に駆られることがあります。たとえば、グア

ムに関して議員が最近困った事例として、「Earthquake(地震)」や「Capsize(転覆する)」があります(訳注:2010/4/1 辺り

に起きた事件のようだ)。しかし、ドメインイベントを作る際は、このような名前を使用したい誘惑を避けて、過去形の動詞の使用

を徹底します。

It is absolutely imperative that events always be verbs in the past tense as they are part of the Ubiquitous

Language. Consider the differences in the Ubiquitous Language when we discuss the side effects from relocating

a customer, the event makes the concept explicit whereas previously the changes that would occur within an

aggregate or between multiple aggregates were left as an implicit concept that needed to be explored and defined.

As an example, in most systems the fact that a side effect occurred is simply found by a tool such as Hibernate

or Entity Framework, if there is a change to the side effects of a use case, it is an implicit concept. The

introduction of the event makes the concept explicit and part of the Ubiquitous Language; relocating a customer

does not just change some stuff, relocating a customer produces a CustomerRelocatedEvent which is explicitly

defined within the language.

ユビキタス言語の一部においては、イベントは過去形の動詞であることが必須です。「Relocating a customer(お客様の再配置)」

による副作用について、ユビキタス言語における変更を考えてみましょう。以前に1つまたは複数のアグリゲートの間で変更を加

えると、潜在的な概念(問題)として残り、調査・修正しなければならなくなります。これに対し、イベントは概念(問題)を明

確にします。たとえば、多くのシステムにおいて、Hibernateまたは Entity Frameworkのようなツールで、副作用が発生した

事実があります。ユースケースに副作用をもたらすなら、それは潜在的な概念(問題)です。イベントを導入すれば、概念を明確

化し、ユビキタス言語に新しい部分を追加できます。つまり、「Relocating a customer(お客様の再配置)」が既存のユビキタ

Page 26: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 26

ス言語に何らかの変更を加えるのではなく、CustomerRelocatedEventの定義を新たに加えるということです。

In terms of code, an event is simply a data holding structure as can be seen in Listing 1.

リスト4の通り、イベントは単純なデータ構造体です。

public class InventoryItemDeactivatedEvent {

public readonly Guid InventoryItemId;

public readononly string Comment;

public InventoryItemDeactivatedEvet(Guid id, string comment) {

InventoryItemId = id;

Comment = comment;

}

Listing 4 A Simple Event | リスト4 簡易イベント

The code listing looks very similar to the code listing that was provided for a Command the main differences

exist in terms of significance and intent. Commands have an intent of asking the system to perform an operation

whereas events are a recording of the action that occurred.

リストのコードはコマンドのコードに似ていますが、特に重要性と意図という点でこの2つは異なっています。コマンドはシステ

ムに対して処理を実行するように依頼する意図があるのに対し、イベントは発生したアクションを記録するものです。

Other Definitions and Discussion | 他の定義や議論

There is a related concept to a Domain Event in this description that is defined in Streamlined Object Modeling

(SOM). Many people use the term “Domain Event” In SOM when discussing “The Event Principle”

Streamlined Object Modeling(SOM)で定義されているものに「ドメインイベント」があり、これに関連する概念があります。

多くの人々は、「Event Principle(イベント主義/原理)」を議論するとき、SOMの「ドメインイベント」という用語を使います。

Model the event of people interacting at a place with a thing with a transaction object. Model a point-in-time

interaction as a transaction with a single timestamp; model a time-interval interaction as a transaction with

multiple timestamps. (Jill Nicola, 2002ll, p. 23)

トランザクションオブジェクト、事柄、場所で相互作用している人々のイベントをモデル化します。単一タイムスタンプでのトラ

ンザクションとして、ポイントインタイム(その時点の短い時間)の相互作用をモデル化します。複数タイムスタンプでのトラン

ザクションとして、インターバルタイム(時間の間隔)の相互作用をモデル化します。(Jill Nicola, 2002ll, p. 23)

Although many people use the terminology of a Domain Event to describe this concept the terminology is not

having the same definition as a Domain Event in the context of this document. SOM uses another terminology

for the concept that better describes what the object is, a Transaction. The concept of a transaction object

is an important one in a domain and absolutely deserves to have a name. An example of such a transaction might

be a player swinging a bat, this is an action that occurred at a given point in time and should be modeled

as such in the domain, this is not however the same as a Domain Event.

多くの人々はこの概念を記述する際にドメインイベントの用語を使いますが、この用語は、上の文献でのドメインイベントと定義

が同じではありません。SOMではトランザクションのオブジェクトが何であるかについて適切に記述する概念については、もう一

つの用語を使います。ドメインではトランザクションオブジェクトの概念は重要なものの一つであり、何らかの名前を付けるだけ

の価値があります。そのようなトランザクションの例として、バットを振るプレイヤーが挙げられます。その時点で発生するアク

ションであり、ドメイン内でそのようにモデル化すべきアクションです。しかし、このアクションはドメインイベントと同じでは

ありません。

This also differs from Martin Fowler’s example of what a Domain Event is.

また、これはMartin Fowler氏のドメインイベントの説明例と異なります。

“Example: I go to Babur’s for a meal on Tuesday, and pay by credit card. This might be modeled as an event,

whose type is “Make Purchase”, whose subject is my credit card, and whose occurred date is Tuesday. If Babur’s

uses and old manual system and doesn’t transmit the transaction until Friday, then the noticed date would

Page 27: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 27

be Friday.” (Fowler)

”例:火曜日にBaburに食事に行き、クレジットカードで支払います。これは「Make Purchase」イベントとしてモデル化できま

す。イベントの主題はクレジットカードで、日付は火曜日です。もし、Baburのシステムが古く、金曜日までそのトランザクショ

ンを送信しない場合、イベントの通知日付は金曜日になります。” (Fowler)

Further along

(中略)

“By funneling inputs of a system into streams of Domain Events you can keep a record of all the inputs to

a system. This helps you to organize your processing logic, and also allows you to keep an audit log of the

system” (Fowler)

”システム入力をドメインイベントのストリームに送ることによって、システムへの入力内容すべての記録を保持できます。こう

すれば、処理ロジックを体系づけられるし、システムの監視ログを保持できます。” (Fowler)

The astute reader may pick up that what Martin is actually describing here is a Command as was discussed

previously when discussing Task Based UIs. The language of “Make Purchase” is wrong. A purchase was made.

It makes far more sense to introduce a PurchaseMade event. Martin did actually make a purchase at the location,

they did actually charge his credit card, and he likely ate and enjoyed his food. All of these things are

in the past tense, they have already happened and cannot be undone.

抜け目のない読者なら、Martin 氏が実際に記述した内容は、先述の「タスクベース・ユーザインタフェース」で触れたコマンド

であることに気付くでしょう。「Make Purchase」の表現は誤りです。購入は終わっているのです。PurchaseMade イベントを導

入する方がずっと意味があります。Martin 氏は実際にその場所で購入し、クレジットカードで実際に引き落とされて、食事を楽

しんだわけです。すべては過去形であり、すでに起こったものであり、元に戻れません。

An example such as the sales example given also tends to lead towards a secondary problem when built within

a system. The problem is that the domain may be responsible for filling in parts of the event. Consider a

system where the sale is processed by the domain itself, how much is the sales tax? Often the domain would

be calculating this as part of its calculations. This leads to a dual definition of the event, there is the

event as is sent from the client without the sales tax then the domain would receive that and add in the sales

tax, it causes the event to have multiple definitions, as well as forcing mutability on some attributes. Dual

events can sidestep this issue (one for the client with just what it provides and another for the domain including

what it has enriched the event from the client with) but this is basically the command event model and the

linguistic problems still exist.

この販売例のような例での問題は、システム構築時には優先度の低いものとして後回しにされがちです。イベントの一部を処理す

る債務がドメインにあるのが問題です。ドメイン自身が販売を処理するシステムについて考えてみましょう。販売税はいくらです

か?たいてい、ドメインが計算の一種として、税金を計算するでしょう。これはイベントの二重定義につながります。クライアン

トから売上税を含まない情報を送信するものとしてのイベントがあり、そして、ドメインが受信したら売上税を追加します。この

ロジックだと、いくつかの属性を可変にしなければなりません。また、イベントも複数の定義を持つ原因になります。二重イベン

トはこの問題(一つはイベントを発行したクライアント、もう一つはクライアントから受信したイベントで情報が追加されている)

を回避可能です。しかし、これは根本的にはコマンドイベント・モデルであり、依然、言語学的な問題もあります。

A further example of the linguistic problems involved can be shown in error conditions. How should the domain

handle the fact that a client told it to do something that it cannot? This condition can exist for many reasons

but let’s imagine a simple one of the client simply not having enough information to be able to source the

event in a known correct way. Linguistically the command/event separation makes much more sense here as the

command arrives in the imperative “Place Sale” while the event is in the past tense “SaleCompleted”. It is

quite natural for the domain to reject a client attempting to “Place a sale”; it is not natural for the domain

to tell the client that something in the past tense no longer happened. Consider the discussion with a domain

expert; does the domain have a time machine? Parallel realities are far too complex and costly to model in

most business systems.

言語学的な問題に関して、別の例として、エラーが状態が挙げられます。クライアントから処理不能なリクエストが来た場合、ド

メインはどう処理すべきでしょうか?このような状態は、様々な理由から発生します。しかし、想像してみましょう。単純なもの

としては、ただ単にクライアントがイベントを正しく生成できるだけの情報を持っていないというのがあります。ここで、言語学

Page 28: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 28

的にコマンド/イベントを分離することは、より多くの意味をもたらします。コマンドは命令形の「Place Sale」である一方、

イベントは過去形の「SaleCompleted」です。ドメインが「Place a sale」を実行しようとしているクライアントを拒絶しても、

ごく自然なことです。ドメインがクライアントに何も起こらなかったことを過去形で話すのは自然ではありません。ドメインの専

門家との議論を考えてみましょう。ドメインはタイムマシンを持っていますか?ほとんどのビジネスシステムシステムでは、並行

発生する現実を反映しようとすると、モデルが非常に複雑になりコストがかさみます。

These are exactly the problems that have led to the separation of the concepts of Commands and Events. This

separation makes the language much clearer and although subtle it tends to lead developers towards a clearer

understanding of context based solely on the language being used. Dual definitions of a concept force the

developer to recognize and distinguish context, this weight can translate into both ramp up time for new

developers on a project and another thing a member of the team needs to “remember”. Anytime a team member

needs to remember something to distinguish context there is a higher probability that it will be overlooked

or mistook for another context. Being explicit in the language and avoiding dual definitions helps make things

clearer both for domain experts, the developers, and anyone who may be consuming the API.

これらがまさにコマンドとイベントの概念の分離を導入する契機となる問題です。この分離は言語を非常に明白にします。また、

わずかではあるが、ただ単に使用言語に沿うだけで、コンテキスト(文脈)の理解を助長します。概念の二重定義は、コンテキス

ト(文脈)の正しい認識・識別に、開発者が苦しみます。分離すれば開発の重点が移り、プロジェクトの新しい開発者に時間的余

裕を与え、チームメンバーが新しいことを覚えるようになります。チームメンバーがコンテキスト(文脈)を識別するための何か

を覚える必要性に追われているとすれば、たいていは、もう一つのコンテキスト(文脈)を見逃しているか誤解している可能性が

高いでしょう。言語を明確化して二重定義を回避すれば、ドメインの専門家、開発者および、APIの使用者は、物事の理解が明白

になります。

Events as a Mechanism for Storage | ストレージ向けメカニズムとしてのイベント

When most people consider storage for an object they tend to think about it in a structural sense. That is

when considering how the “sale” discussed above should be stored they think about it as being stored as a

“Sale” that has “Line Items” and perhaps some “Shipping Information” associated with it. This is not however

the only way that the problem can be conceptualized and other solutions offer different and often interesting

architectural properties.

ほとんどの人々がオブジェクトのストレージを考えるとき、データ構造を意識する傾向があります。先述した「Sale(販売)」の

格納方法を考えるとき、「Line Items(項目)」や「Shipping Information(出荷情報)」などを含む「Sale(販売)」として格

納することを考えます。しかし、これは問題を概念化する唯一の方法ではありません。他にも異なる解決策や、興味深い特性を持

つアーキテクチャもあります。

Consider for a moment the creation of a small Order object for a web based sale system. Most developers would

envision something similar to what is represented in Figure 1. That is a structural viewpoint of what the

Order is. An Order has n Line Items and Shipping Information. Of course this is an overly simplified view

of what an Order is but it can be seen that the focus is upon the structure of the order and its parts.

Web ベースの販売システムにおいて、小さな注文オブジェクトを生成する場合を考えましょう。ほとんどの開発者は、図 13 のよ

うなものを心に描くでしょう。図は、注文を構造的に見たものです。注文には、n個のLine Items(項目)とShipping Information

(出荷情報)があります。もちろん、これはごく単純な注文のビュー(外観)ですが、注文のデータ構造やその一片に焦点を当て

ています。

Page 29: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 29

Figure 13 A Structural View of an Order | 図13 注文の構造的なビュー

This is not the only way that this data can be viewed. Previously in the area of discussions there was a discussion

about the concept of a transaction. Developers deal with the concept of transactions regularly, they can be

viewed as representing the change between a point and the next subsequent point. They are also regularly called

“Deltas”. The delta is between two static states can always be defined but more often than not this is left

to be an implicit concept, usually relegated to a framework such as Hibernate in the Java world or Entity

Framework in the Microsoft world. These frameworks save the original state and then calculate the differences

with the new state and update the backing data model accordingly. The making of these deltas explicit can

be highly valuable both in terms of technical benefits and more importantly in business benefits.

このデータの外観は、上図だけではありません。先ほど、トランザクションの概念について述べました。開発者は日常的にトラン

ザクションの概念に対処し、過去と未来のデータの変更点を検討します。よく「デルタ(差分)」と呼ばれているものです。デルタ

は2つの固定された静的ステートの差分を表すものですが、たいていは潜在的な概念に留めていて、Java界のHibernateやマイ

クロソフト界のEntity Frameworkなどのフレームワークに委譲しています。これらのフレームワークは、元のステートを保存し、

新しいステートとの差分を計算し、その結果に応じてバッキングデータモデルを更新します。デルタを明示的に作成することは、

技術的な利点、もっというと、ビジネスに利点をもたらす意味で重要です。

The usage of such deltas can be seen in many mature business models. The canonical example of delta usage

is in the field of accounting. When looking at a ledger such as in Figure 2 each transaction or delta is being

recorded. Next to it is a denormalized total of the state of the account at the end of that delta. In order

to calculate this number the current delta is applied to the last known value. The last known value can be

trusted because at any given point the transactions from the “beginning of time” for that account could be

re-run in order to reconcile the validity of that value. In there exists a verifiable audit log.

多くの成熟したビジネスモデルで、デルタを使用しています。標準的なデルタ使用例として、会計のフィールドにあります。図 2

の元帳(帳簿)を見てください。元帳にはトランザクションまたはデルタが記録されています。その隣にはデルタの最後尾にある

非正規化された口座のステートの総計があります。現在のデルタはこの数値計算のために最新値に適用され、その最新値は信頼で

きます。なぜなら、その口座の「開始時間」を起点としたトランザクションは、値の正当性を確認するために、どの所定の時点で

も再実行可能だからです。そこには検証可能な監視ログがあります。

Date Comment Change Current Balance

1/1/2000 Deposit from 1372 +10000.00 10000.00

1/3/2000 Check 1 -4000.00 6000.00

1/4/2000 Purchase Coffee -3.00 5997.00

1/6/2000 Purchase Internet -5.00 5992.00

1/8/2000 Deposit from 1373 +1000.00 6992.00

Figure 14 A Simplified Ledger | 図14 単純化した元帳

Because all of the transactions or deltas associated with the account exist, they can be stepped through

verifying the reult. The “Current Balance” at any point can be derived either by looking at the “Current Balance”

or by adding up all of the “Changes” since the beginning of time for the account. The second property is obviously

valuable in a domain such as accounting as accountants are dealing with money and the ability to check that

calculations were performed correctly is extremely valuable, it was even more valuable before computers when

Page 30: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 30

it was common place to have an exhausted accountant make a mistake in a calculation at 3 am when they should

be sleeping instead of working with the books.

口座ごとにすべてのトランザクションまたはデルタがあるので、処理結果の検証を通して進めることが可能です。「経常勘定」を見

ることによって、または、口座開設時からのすべての「変更」を合計することによって、任意の時点の「経常勘定」を引き出し可

能です。金額を処理する会計士にとっては、計算等を行う分野では、第二の特性(訳注:デルタのことだと思われる)が明らかに

貴重です。計算が正しく行われたかどうかをチェックする能力は、非常に貴重です。会計士は書籍を片手にして、寝る時間を削っ

て午前3時まで作業してもミスを犯すことが多かったのです。疲労困憊な会計士にとっては、コンピュータは貴重でした。

There are however some other interesting properties to this mechanism of representing state, as an example,

it is possible to go back and look at what a state was at a given point in time. Consider for that the account

was allowed to reach a balance of below zero and there is a rule that says it is not supposed to. It is possible

and relatively easy, to view the account as it was just prior to processing that transaction that put it into

the invalid state and see what state it was in, making it far easier to reproduce what often times end up

as heisenbugs in other circumstances.

しかしながら、ステートを表現するこのメカニズムには、いくつかの興味深い特性があります。たとえば、過去に戻って、任意の

時点でどのようなステートだったかどうかを参照可能であることです。想定されていないにもかかわらず、口座の勘定が0未満に

なった場合を考えてみましょう。トランザクションを処理する前に無効なステートが挿入され、どのようなステートになっていた

かを確認するために、口座を参照するのは可能だし、比較的簡単です。ハイゼンバグ(調査しようとすると変貌したり消えたりす

るバグ)を他の環境で再現するも、容易になります。

These types of benefits are not only limited to naturally transaction based domains though. In fact every

domain is a naturally transaction based domain when Domain Driven Design is being applied. When applying Domain

Driven Design there is a heavy focus on behaviors, normally coinciding with use cases, Domain Driven Design

is interested in how users use the system.

しかし、これらの利点は、当然ドメインベースのトランザクションに限ったことではありません。実際、ドメイン駆動設計が適用

されていれば、あらゆるドメインは、ドメインベースのトランザクションです。ドメイン駆動設計を適用するとき、ユースケース

に正しく一致するよう、ふるまいに重点的に焦点を当てます。ドメイン駆動設計は、ユーザがシステムをどう使用するかに関心が

あります。

Returning to the Order example from Figure 1, the same order could be represented in the form of a transactional

model as shown in Figure 3.

図13の注文例に戻りますが、同じ注文でも、図15のような処理モデルの形式で表現できます。

Figure 15 Transactional View of Order | 図15 注文の処理ビュー

This can be applied to any type of object. By replaying through the events the object can be returned to the

last known state. It is mathematically equivalent to store the end of the equation or the equation that represents

it. There is a structural representation of the object, but it exists only by replaying previous transactions

to return the structure to its last known state, data is not persisted in a structure but as a series of

Page 31: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 31

transactions. One very interesting possibility here is that unlike when storing current state in a structural

way there is no coupling between the representation of current state in the domain and in storage, the

representation of current state in the domain can vary without thought of the persistence mechanism.

この形式だと、どのようなオブジェクトにも適用できます。イベントを再生することによって、最新ステートをオブジェクトに返

却できます。数学的に、等式で最後に変数に格納すること(または、等式の表現)に等しいです。オブジェクトには構造的な表現

がありますが、最新ステートの構造体に格納するために、前回のトランザクションを再生するために存在するものです。データは

構造体に永続化されませんが、一連のトランザクションの結果として永続化されます。この形式において、非常に興味深い可能性

の一つとして、現在のステートを構造化して格納する場合と異なり、ドメイン内とストレージ内でそれぞれ保持している現在のス

テートの表現の結合がありません。永続化メカニズムを考慮せずに、ドメイン内の現在ステートの表現を変えさせることができる

のです。

It is vitally important to note the language in Figure 3. All of the verbs are in the past tense. These are

Domain Events. Consider what would happen if the language were in the imperative tense, “Add 2 socks item

137”, “Create Cart”. What if there were behaviors associated with adding and item (such as reserving it from

an inventory system via a webservice call), should these behaviors be when reconstituting an object? What

if logic has changed so that this item could no longer be added given the context? This is one of many examples

where dual contexts between Commands and Events are required, there is a contextual difference between returning

to a given state and attempting to transition to a new one.

図15には言語面でも極めて重要なものがあります。すべての動詞は過去形であり、これらの動詞はドメインイベントです。もし、

動詞が命令形であり、「Add 2 Socks Item 137」「Create Card」という表現だとしたら、どうなるか考えてみましょう。項目の

「追加」と「(Webサービス呼び出し経由でインベントリシステムから確保された)アイテム」に割り当てられたふるまいがあると

したら、オブジェクトを再構築する時にこれらのふるまいはどうなるでしょうか?処理ロジックが変更され、このアイテムがもう

追加されることがなくなったら、どうなるでしょうか?これは多くある例の一つです。つまり、コマンドとイベントの間で二重コ

ンテキスト(文脈)が必要となっている例です。与えられたステートを返すことと、新しいステートに遷移しようとすること、こ

の2つの間にコンテキスト(文脈)上の違いがあります。

There is no Delete | 削除するものは無い

A common question that arises is how to delete information. It is not possible as previously jump into the

time machine and say that an event never happened (eg: delete a previous event). As such it is necessary to

model a delete explicitly as a new transaction as shown in Figure 4. Further discussion on the business value

of handling deletes in this mechanism can be found in “Business Value of the Event Log”.

よく寄せられる質問として、情報を削除する方法が挙げられますが、これは可能ではありません。タイムマシンの件で先述しまし

たが、イベントが決して起こらなかったと言うのと同様です。図 16 で示すように、新しいトランザクションとして明示的な削除

をモデル化する必要があります。このメカニズムで削除処理を行うビジネス価値については、後の「Business Value of the Event

Log」の節で触れます。

Is

Page 32: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 32

Figure 16 Transactional View of Order with Delete | 注文の削除のトランザクションビュー

In the event stream in Figure 4 the two pairs of socks were added then later removed. The end state is equivalent

to not having added the two pairs of socks. The data has not however been deleted, new data has been added

to bring the object to the state as if the first event had not happened, this process is known as a Reversal

Transaction.

図16のイベントストリームでは、2足分の靴下を追加し、その後で削除しています。最終的なステートは、2足分の靴下が追加さ

れてない状態と同じです。データが削除されていなくても、新しいデータが追加されています。つまり、最初のイベント(Added 2

Socks Item 137)が発生しなかったかのようにするために、新しいデータ(Removed 2 Socks Item 137)が追加されたという

ことです。この処理はリバーサルトランザクションと呼ばれています。

By placing a Reversal Transaction in the event stream not is the object returned to the state as if the item

had not been added, the reversal leaves a trail that shows that the object had been in that state at a given

point in time.

イベントストリームにリバーサルトランザクションを取り入れることによって、オブジェクトは、あたかもアイテムが追加されて

いないかのようなステートで返されます。リバーサルトランザクションでは、その時点のオブジェクトのステートを、(ログなどに)

痕跡として残します。

There are also architectural benefits to not deleting data. The storage system becomes an additive only

architecture, it is well known that append-only architectures distribute more easily than updating

architectures because there are far fewer locks to deal with.

データの削除を行わない点にも、アーキテクチャ上の利点があります。ストレージシステムに対するアーキテクチャは「追加」だ

けになります。これは「append-only」アーキテクチャであり、更新処理よりも簡単です。なぜなら更新処理にはロックが必要で

すが、追加処理にはロックが不要だからです。

Performance and Scalability | パフォーマンスとスケーラビリティ

As an append-only model storing events is a far easier model to scale. There is however other benefits in

terms of performance and scalability especially compared with a stereotypical relational model. As an example,

the storage of events offers a much simpler mechanism to optimize as it is limited to a single append-only

model. There are many other benefits.

append-onlyモデルでは、イベントの格納はスケーリングが非常に簡単です。それだけでなく、特にステレオタイプ関係のモデル

と比較して、性能とスケーラビリティに関する利点もあります。たとえば、イベントのストレージは、非常に単純なメカニズムを

提供するものであり、ストレージシステムを単一のappend-onlyに限定して、最適化できます。多くの利点があるわけです。

Partitioning | パーティション分割

A very common performance optimization in today’s systems is the use of Horizontal Partitioning. With Horizontal

Partitioning the same schema will exist in many places and some key within the data will be used to determine

in which of the places the data will exist. Some have renamed the term to “Sharding” as of late. The basic

idea is that you can maintain the same schema in multiple places and based on the key of a given row place

it in one of many partitions.

最近は一般的なパフォーマンス最適化の方法として、Horizontal Partitioning(水平パーティション分割)を使用します。水

平パーティション分割では、同じスキーマが多くの場所に存在し、いくつかのキーはデータの場所を決定するために使用します。

最近は「Sharding(データベースシャーディング)」という名前で呼ばれています。基本的な考え方は、複数のデータベースで同

じスキーマを保守できる点です。所定の行のキーが、多くのパーティションの中の位置を示します。

One problem when attempting to use Horizontal Partitioning with a Relational Database it is necessary to define

the key with which the partitioning should operate. This problem goes away when using events. Aggregate IDs

are the only partition point in the system. No matter how many aggregates exist or how they may change structures,

the Aggregate Id associated with events is the only partition point in the system.

リレーショナルデータベースで水平パーティション分割を試みる際の問題点の一つが、パーティション分割を実施するためのキー

を定義する必要がある点です。でも、イベントを使えば、この問題は解決できます。「Aggregate IDs(アグリゲート ID)」がそ

のシステムにおける唯一のパーティションポイントです。アグリゲートの個数が多くなっても、構造を変更することがあっても、

気にする必要がありません。イベントに割り当てられたAggregate Idが、そのシステムの唯一のパーティションポイントです。

Page 33: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 33

Horizontally Partitioning an Event Store is a very simple process.

「水平パーティション分割」と「イベント格納」は、非常にシンプルな処理です。

Saving Objects | オブジェクトの格納

When dealing with a stereotypical system utilizing a relational data storage it can be quite complex to figure

out what has changed within the Aggregate. Again many tools have been built to help alleviate the pain that

arises from this often complex task but is the need for a tool a sign of a bigger problem?

リレーショナルデータストレージを利用しているステレオタイプシステムに対処するとき、アグリゲート内の変更を理解するには

本当に複雑です。複雑なタスクで生じる苦痛を軽減するツールも作成されてきましたが、ツールが必要ということは、問題が大き

くなる徴候ではないでしょうか?

Most ORMs can figure out the changes that have occurred within a graph. They do this generally by maintaining

two copies of a given graph, the first they hold in memory and the second they allow other code to interact

with. When it becomes time to save a complex bit of code is run, walking the graph the code has interacted

with and using the copy of the original graph to determine what has changed while the graph was in use by

the code. These changes will then be saved back to the data storage system.

ほとんどのORMs(O/Rマッピング)では、グラフ内で発生した変更を理解できます。一般的にはグラフの2つのコピーを作成し、

1 つ目はオンメモリで保持し、2 つ目は他のコードとの相互作用のために使います。時が来たら、元のグラフと他のコードと相互

作用に使うグラフを比較して、変更内容を決定します。そして、これらの変更内容は、データストレージシステムにバックアップ

されます。

In a system that is Domain Event centric, the aggregates are themselves tracking strong events as to what

has changed within them. There is no complex process for comparing to another copy of a graph, instead simply

ask the aggregate for its changes. The operation to ask for changes is far more efficient than having to figure

out what has changed.

ドメインイベント中心のシステムでは、アグリゲートは変更内容に関する強いイベントをトラッキング(追跡)します。他グラフ

のコピーとの比較作業は複雑ではなく、ただ単にその変更をアグリゲートに要求すればいいのです。変更内容を理解することより

も、変更を要求する方がはるかに効率的です。

Loading Objects | オブジェクトのロード

A similar issue exists when loading objects. Consider the work that is involved with loading a graph of objects

in a stereotypical relational database backed system. Very often there are many queries that must be issued

to build the aggregate. In order to help minimize the latency cost of these queries many ORMs have introduced

a heuristic of Lazy Loading also known as Delayed Loading where a proxy is given in lieu of the real object.

The data is only loaded when some code attempts to use that particular object.

オブジェクトをロードするときにも、似た問題が存在します。リレーショナルデータベースを使うステレオタイプのシステムにお

ける、オブジェクトのグラフをロード処理を考えてみましょう。たいてい、アグリゲートを構築するために、大量のクエリを発行

します。これらのクエリ発行による潜在的コストを最小限にするために、多くの ORMs は「Delayed Loading(遅延ロード)」と

呼ばれる「Lazy Loading」のヒューリスティックを導入してきました。Delayed Loadingでは、プロキシが本物の代わりに使わ

れます。コードが特定オブジェクトを使おうとするときにのみ、データがロードされます。

Lazy Loading is useful because quite often a given behavior will only use a certain portion of data out of

the aggregate and it prevents the developer from having to explicitly represent which data that is while

amortizing the cost of the loading of the aggregate. It is this need for amortization of cost that shows a

problem.

ふるまいは通常はアグリゲートから取り出したデータの一部分を使うだけであり、明確なデータ表現を持つ必要がないため、アグ

リゲートをロードするコストを償還する意味でLazy Loadingは有用です。つまり、コスト問題を償還するために必要なのです。

Aggregates are considered as a whole represented by the Aggregate Root. Conceptually an Aggregate is loaded

and saved in its entirety. (Evans, 2001).

アグリゲート(s)は、アグリゲートルートによって表現される全体像として考慮します。概念的には、アグリゲートは全体を読み

込み・書き出します。(Evans, 2001).

Page 34: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 34

Conceptually it is much easier to deal with the concept of an Aggregate being loaded and saved in its entirety.

The concept of Lazy Loading is not a trivial one when added and is especially not trivial when optimizing

use cases. The heuristic is needed because loading full aggregates from a relational database is operationally

too slow.

全体の読み込み・書き出しを行うアグリゲートの概念に対処するのは、概念的には非常に簡単です。Lazy Loadingの概念を追加

することは些細なことではありませんし、特にユースケースを最適化することも些細なことではありません。リレーショナルデー

タベースからすべてのアグリゲートをロードするのは非常に遅い処理なので、ヒューリスティック(発見的手法=手法を試行錯誤

すること)が必要です。

When dealing with events as a storage mechanism things are quite different. There is but one thing being stored,

events. Simply load all of the events for an Aggregate and replay them. There can only ever be a single query

on the system, there is no need to attempt to implement things like Lazy Loading. This is bad for people who

want to build complex and quite often impressive frameworks for managing things like Lazy Loading but it is

good for development teams who no longer need to learn these frameworks.

ストレージメカニズムとしてイベントに対処するときは、事情がまったく異なります。格納するのはイベントです。アグリゲート

では単純に、すべてのイベントをロードして再生します。システム上に単一のクエリがあるだけで、Lazy Loadingのようなもの

を試みる必要はありません。Lazy Loadingのような管理を行う、複雑で荘厳なフレームワークを構築したがりますが良くありま

せん。このようなフレームワークを習得する必要がないのが、開発チームにとっては良いのです。

Many would quickly point out that although it requires more queries in a relational system, when storing events

there may be a huge number of events for some aggregates. This can happen quite often and a relatively simple

solution exists for the problem.

リレーショナルシステムではもっと多くのクエリーが必要であると、多くの人はすぐ指摘します。イベントを格納するとき、アグ

リゲートでは膨大な数のイベントを扱うことが良くあります。しかし、この問題を解決する比較的簡単な解決策が存在します。

Rolling Snapshots | スナップショットの巻き出し

A Rolling Snapshot is a denormalization of the current state of an aggregate at a given point in time. It

represents the state when all events to that point in time have been replayed. Rolling Snapshots are used

as a heuristic to prevent the need to load all events for the entire history of an aggregate. Figure 5 shows

a typical Event Stream. One way of process thing the event stream is to replay the events from the beginning

of time until the end of the event stream is reached.

Rolling Snapshotは、その時点のアグリゲートの現在のステートを非正規化したものであり、すべてのイベントがその時点まで

に再生したときのステートを表現します。アグリゲートの完全な履歴を取得するにはすべてのイベントをロードする必要がありま

すが、それを回避するヒューリスティックとしてRolling Snapshotが使われています。典型的なイベントストリームを図17に

示します。処理方法の一つとして、イベントストリームは開始時間~最後尾のイベントを再生するためにあります。

Figure 17 An Event Stream | イベントストリーム

The problem that exists is that there may be a very large number of events between the beginning of time and

the current point. It can be easily imagined that there is an event stream with a million or more events that

Page 35: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 35

have occurred, such an event stream would be quite inefficient to load.

開始時間~現在時間の間に膨大な数のイベントが存在する可能性があることが、懸念事項です。100万個以上の発生イベントがイ

ベントストリームに蓄積されると、イベントストリームをロードする効率が悪化することは想像に難くありません。

The solution is to use a Rolling Snapshot, to place a denormalization of the state at a given point in time.

It would then be possible to only play the events from that point in time forward in order to load the Aggregate.

所定時点のステートを非正規化して格納するために、Rolling Snapshotを使うのが解決策です。すると、アグリゲートをロード

するために、前方に向かって時間を追ってイベントを再生すればよいのです。

Figure 18 Event Stream with Snapshot | スナップショット付きのイベントストリーム

Figure 6 shows an Event Stream with a Rolling Snapshot placed within it. The process for rebuilding an Aggregate

changes when using Rolling Snapshots. Instead of reading from the beginning of time forward, it is read backwards

putting the events on to a stack until either there were no more events left or a snapshot was found. The

snapshot would then if found be applied and the events would be popped off the stack and applied until the

stack was empty.

内部をRolling Snapshotに置き換えたイベントストリームを、図18に示します。このアグリゲートを再構築する処理は、Rolling

Snapshot を使う場合に変化します。開始時間から時間を追って読み込むのではなく、イベントがあるスタックをイベントが無く

なるかスナップショットが見つかるまで、逆方向に読み込みます。スナップショットが見つかれば、それを適用します。イベント

はスタックが空になるまで、スタックから取り出して適用します。

It is important to note that although this is an easy way to conceptualize how Rolling Snapshots work, that

this is a less than ideal solution in a production system for various reasons. Further discussion on the

implementation of Rolling Snapshots can be found in “Building an Event Storage”.

これはRolling Snapshotの動作を概念化する簡単な方法ですが、製品システムでは様々な理由により理想的ではないことに注意

することが大切です。Rolling Snapshotの実装の詳細は、「Building an Event Storage(イベントストレージの構築)」で触

れます。

The snapshot itself is nothing more than a serialized form of the graph at that given point in time. By having

the state of that graph at that point in time replaying all the events prior to that snapshot can be avoided.

Snapshots can be taken asynchronously by a process monitoring the Event Store.

スナップショット自身は、その時点のグラフをシリアライズした形式に過ぎませんが、このグラフがあればスナップショットより

前のすべてのイベントを読み込むのを回避できます。スナップショットは、Event Storeをモニタリングするプロセスによって非

同期に作成できます。

Introducing Rolling Snapshots allows control of the worst case when loading from events. The maximum number

of events that would be processed can be tuned to optimize performance for the system in question. With the

introduction of Rolling Snapshots it is a relatively trivial process to achieve one to two orders of magnitude

of performance gain on the two operations that the Event Storage supports. It is important though to remember

that Rolling Snapshots are just a heuristic and that conceptually the event stream is still viewed in its

entirety.

Page 36: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 36

Rolling Snapshotの導入により、イベントロード時の最悪のケースを制御できます。対象システムのパフォーマンスを最適化す

るために、処理するイベントの最大数をチューニングできます。Rolling Snapshotの導入は、イベントストレージがサポートす

る2つの処理(訳注:ロードとセーブのこと?)上で、1~2桁のパフォーマンス向上を達成する程度の比較的些細なプロセスです。

しかし、Rolling Snapshotはまだヒューリスティックであること、また、概念的にはイベントストリームはまだその全体像を眺

めるものであることを意識しておいてください。(訳注:まだ模索中であり、改善余地があるということ)

Impedance Mismatch | インピーダンス・ミスマッチ

Using events as a storage mechanism also offers very different properties when compared to a typical relational

model when the impedance mismatch that exists between a typical relational model and the object oriented domain

model is analyzed. Scott Ambler describes the problem in an essay on agiledata.org as

ストレージメカニズムとしてイベントを使うときの特性は、典型的なリレーショナルモデルとは非常に異なります。典型的なリレ

ーショナルモデルとオブジェクト指向ドメインモデルを分析すると、この2つの間にインピーダンスミスマッチ(インピーダンス

不適合)が存在します。Scott Ambler氏はagiledata.orgでこの問題について記述しています。

“Why does this impedance mismatch exist? The object-oriented paradigm is based on proven software engineering

principles. The relational paradigm, however, is based on proven mathematical principles. Because the

underlying paradigms are different the two technologies do not work together seamlessly. The impedance mismatch

becomes apparent when you look at the preferred approach to access: With the object paradigm you traverse

objects via their relationships whereas with the relational paradigm you join the data rows of tables. This

fundamental difference results in a non-ideal combination of object and relational technologies, although

when have you ever used two different things together without a few hitches?” (Ambler)

「なぜ、インピーダンス・ミスマッチが存在するのか?オブジェクト指向パラダイムはソフトウェア工学の原理に基づいて実証さ

れたものですが、リレーショナルパラダイムは数理に基づいて実証されたものです。根底にあるパラダイムが異なるので、この 2

つのテクノロジーはシームレスに(継ぎ目なく)連携しません。ストレージへのアクセスについて望ましい方法を検討するとき、

インピーダンス・ミスマッチが明らかになります。オブジェクト指向パラダイムではリレーショナルを介してオブジェクトをトラ

バース(横断)するのに対して、リレーショナルパラダイムではテーブルの行にデータを追加します。この根本的な相違点が、オ

ブジェクトパラダイムとリレーショナルパラダイムの 2テクノロジー間に、理想的ではない不整合をもたらします。2つの異なる

テクノロジーを同時に使うときに、何らかの支障が出ます。」(Ambler)

The impedance mismatch between the domain model and the relational database has a large cost associated with

it. There are many tools that aim to help minimize the effects of the impedance mismatch such as Object Relational

Mappers (ORM). They tend to work well in most situations but there is still a fairly large cost associated

to the impedance mismatch even when using tools such as ORMs. The cost is that a developer really needs to

be intimately with both the relational model and the object oriented model. They also need to be familiar

with the many subtle differences between the two models. Scott identifies this with

ドメインモデルとリレーショナル・データベース間のインピーダンス・ミスマッチにより、大きなコストが生まれます。オブジェ

クト・リレーショナル・マッパー(ORM)などで起きるインピーダンス・ミスマッチを最小限にするツールがたくさんあります。ツ

ールはほとんどの状況で効果が上がる傾向がありますが、ツールを使用してもインピーダンス・ミスマッチの影響による大きなコ

ストがまだ残っています。開発者がリレーショナルモデルとオブジェクト指向モデルの両方をまだ心の底から必要としているとこ

ろに、本当のコストがあるのです。開発者は、2つのモデルの多くの微妙な相違点を熟知する必要があります。Scott氏曰く:

“To succeed using objects and relational databases together you need to understand both paradigms, and their

differences, and then make intelligent tradeoffs based on that knowledge.” (Ambler)

「オブジェクトとリレーショナルデータベースを共に上手に使用するには、両パラダイムとその相違点を理解し、さらにトレード

オフについても熟知する必要があります。」(Ambler)

Some of these subtle differences can be found in Wikipedia under the “Object-Relational Impedance Mismatch”

page but to include some of the major differences.

微妙な相違点についてはWikipediaの「Object-Relational Impedance Mismatch」に説明がありますが、いくつかの主な相違

点については説明がありません。

Declarative vs. imperative interfaces — Relational thinking tends to use data as interfaces, not behavior

as interfaces. It thus has a declarative tilt in design philosophy in contrast to OO's behavioral tilt. (Some

Page 37: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 37

relational proponents propose using triggers, stored procedures, etc. to provide complex behavior, but this

is not a common viewpoint.) (Object-Relational Impedance Mismatch)

インタフェースの宣言 vs. 命令:リレーショナル的な思考では、ふるまいをインタフェースとして使うのではなく、データをイ

ンタフェースとして使う傾向があります。オブジェクト指向のふるまいとは対照的に、設計哲学に基づいた宣言について議論しま

す。(リレーショナル支持者は、トリガー、ストアドプロシージャなどを使用して複雑なふるまいを定義することを提案しますが、

これは一般的な視点ではありません)。(Object-Relational Impedance Mismatch)

Structure vs. behaviour — OO primarily focuses on ensuring that the structure of the program is reasonable

(maintainable, understandable, extensible, reusable, safe), whereas relational systems focus on what kind

of behaviour the resulting run-time system has (efficiency, adaptability, fault-tolerance, liveness, logical

integrity, etc.). Object-oriented methods generally assume that the primary user of the object-oriented code

and its interfaces are the application developers. In relational systems, the endusers' view of the behaviour

of the system is sometimes considered to be more important. However, relational queries and "views" are common

techniques to re-represent information in application- or task-specific configurations. Further, relational

does not prohibit local or application-specific structures or tables from being created, although many common

development tools do not directly provide such a feature, assuming objects will be used instead. This makes

it difficult to know whether the stated nondeveloper perspective of relational is inherent to relational,

or merely a product of current practice and tool implementation assumptions. (Object-Relational Impedance

Mismatch)

構造 vs. ふるまい:オブジェクト指向では、プログラム構造の合理性(可用性、容易性、拡張性、再使用性、安全性など)を保

証することに、主な焦点を当てます。ところが、リレーショナルシステムでは、ランタイムが結果的にどのようにふるまうか(効

率性、適応性、フォールト・トレランス、生存性、論理的完全性など)について、焦点を当てます。オブジェクト指向の手法では、

一般的に、オブジェクト指向コードとそのインタフェースの主要ユーザはアプリケーション開発者であると仮定します。リレーシ

ョナルシステムでは、時々、システムのふるまいに対するエンドユーザの視点を重要視します。しかし、リレーショナルのクエリ

と「視点」は、アプリケーション固有の構成またはタスク固有の構成において、情報を表現する一般的な技術です。さらに、リレ

ーショナルでは、多くの一般的な開発ツールが機能を直接提供していなくても、その代わりにオブジェクトを使用することを想定

して、ローカル/アプリケーション固有の構造または、テーブルを生成するのを禁止しません。このため、所定のリレーショナル

非開発者の展望(パースペクティブ)がリレーショナル固有なのか、または、ただ単に現在の実装やツールによる影響なのかを知

るのが困難になります。(Object-Relational Impedance Mismatch)

Set vs. graph relationships - The relationship between different items (objects or records) tend to be handled

differently between the paradigms. Relational relationships are usually based on idioms taken from set theory,

while object relationships lean toward idioms adopted from graph theory (including trees). While each can

represent the same information as the other, the approaches they provide to access and manage information

differ. (Object-Relational Impedance Mismatch)

集合 vs. グラフリレーショナル: 異なる項目間(オブジェクトまたはレコード)の関係では、これらのパラダイム間で処理が異

なります。リレーショナルの関係は通常、集合論から引用したイディオムに基づいていて、オブジェクトの関係はグラフ理論(ツ

リーを含む)から引用したイディオムに沿う傾向があります。同じ情報を表現するにしても、情報へのアクセスと管理の方法が異

なります。(Object-Relational Impedance Mismatch)

There are many other subtle differences such as data types, identity, and how transactions work. The

object-relational impedance mismatch can be quite a pain to deal with and it requires a very large amount

of knowledge to deal with effectively.

これらは、他にもデータ型、識別方法、トランザクション処理の方法など、微妙な相違点が多くあります。オブジェクトとリレー

ショナルのインピーダンスミスマッチに対処するのは非常に苦痛であり、効率的に対処するには多くの知識を必要です。

There is not an impedance mismatch between events and the domain model. The events are themselves a domain

concept, the idea of replaying events to reach a given state is also a domain concept. The entire system becomes

defined in domain terms. Defining everything in domain terms not only lowers the amount of knowledge that

developers need to have, it also limits the number of representations of the model needed as the events are

directly tied to the domain model itself.

イベントとドメインモデル間には、インピーダンスミスマッチがありません。イベントはそれ自体がドメイン概念であり、所定の

ステートに辿り着くまでにイベントを再生するというアイデアはドメイン概念でもあります。すべてのシステムは、ドメインの用

語で定義されます。ドメインの用語ですべてを定義することは、開発者が必要とする知識の量を減らすだけではありません。イベ

Page 38: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 38

ントがドメインモデル自身と直接結びつくので、モデルを表現する数を制限します。

Business Value of the Event Log | イベントログのビジネス価値

It needs to be made clear at the very start of this section that the value of the Event Log is directly correlated

with places that you would want to use Domain Driven Design in the first place. Domain Driven Design should

be used in places where the business derives competitive advantage. Domain Driven Design itself is very difficult

and expensive to apply; a company will however receive high ROI on the effort if the domain is complex and

if they derive competitive advantage from it. Using an Event Log similarly will have high ROI when dealing

with an area of competitive advantage but may have negative ROI in other places.

本章の説明に入る前に、イベントログの価値は、ドメイン駆動設計を最初に使用したい部分と直接的な関係があることを断ってお

きます。ビジネスで競争優位性を獲得したい部分で、ドメイン駆動設計を使う必要があります。ドメイン駆動設計自体が非常に難

しく、適用コストが高いからです。しかし、ドメインが複雑であり、また、そのドメインで競争優位性を獲得すれば、企業は努力

に見合った高いROIを得られます。同様にして、イベントログも、競争優位性を持つ分野に対応するときは高いROIを得られます

が、そうでない分野ではROIが低くなるでしょう。

Storing only current state only allows to ask certain kinds of questions of the data. For example consider

orders in the stock market. They can change for a few reasons, an order can change the amount of volume that

they would like to buy/sell, the trading system can automatically adjust the volume of an order, or a trade

could occur lowering the volume available on the current order.

現在のステートだけを格納する場合、ある程度のデータの問い合わせだけが可能です。例として、株式市場での注文を考えてみま

しょう。これはいくつかの理由により変更可能です。たとえば、注文で売買したい量の総数を変更する、売買システムで注文量を

自動的に調整する、または、注文可能な量が減少したなどです。

If posed with a question regarding current liquidity such as the price for a given number of shares in the

market, it really does not matter which of these changes occurred, it does not really matter how the data

got the way it was, it matters what it is at a given point in time. A vast majority of queries even in the

business world are focused on the what, labels to send customers mails, how much was sold in April, how many

widgets are in the warehouse.

株式数の価格など現在の流動性に関する問い合わせを送るとき、どの変動が起きたのか、また、データのどのように取得したかは

重要ではありません。その時点の「what(何)」が重要です。ビジネス界での多くのクエリは、いまだに、顧客に送るメールのラ

ベルの内容、4月の売り上げ状況、在庫状況などに焦点を当てています。

There are however other types of queries that are becoming more and more popular in business, they focus on

the how. Examples can commonly be seen in the buzzword “Business Intelligence”. Perhaps there is a correlation

between people having done an action and their likelihood of purchasing some product? These types of questions

generally focus on how something came into being as opposed to what it came out to be.

しかし、ビジネスで注目を浴びているクエリが他にあり、このクエリでは「how(方法)」に焦点を当てています。良い例が、バズ

ワードの「ビジネスインテリジェンス」にあります。人々の行動と、製品を購入する可能性の間に相関性があるのだろうか?この

種のクエリでは、「何が発生した」ではなく「どのように発生したか」に焦点を当てます。

It is best to go through an example. There is a development team at a large online retailer. In an iteration

planning meeting a domain expert comes up with an idea. He believes that there is a correlation between people

having added then removed an item from their cart and their likelihood of responding to suggestions of that

product by purchasing it at a later point. The feature is added to the following iteration.

そこで、例を調べてみましょう。大きな小売業者に開発チームがあります。イテレーションでの設計会議では(訳注:アジャイル

開発のイテレーション)、ドメインの専門家がアイデアを出します。ドメインの専門家は、人々が商品をカートに追加した後に削除

することと、その商品の提案に応じて後で商品を購入する可能性の間に、何らかの相関性があると信じています。そして、次のイ

テレーションを経て、その機能を追加します。

The first hypothetical team is utilizing a stereotypical current state based mechanism for storing state.

They plan that in this iteration they will add tracking of items via a fact table that are removed from carts.

They plan for the next iteration that they will then build a report. The business will receive after the second

iteration a report that can show them information back to the previous iteration when the team released the

Page 39: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 39

functionality that began tracking items being removed from carts.

第1のチームでは、ステレオタイプなメカニズムを使用していて、現在のステートを格納しています。ステートを格納するメカニ

ズムを利用して、ステレオタイプな現在状態を保持しています。このイテレーションでは、チームは実テーブルを踏査してカート

から削除された商品を追跡する機能を加えることを計画します。2 回目のイテレーション後に、前イテレーションで追加した機能

のフィードバックを示すレポートを受け取ります。

This is a very stereotypical process, at some organizations the report and the tracking may be released

simultaneously but this is a relatively small detail in the handling. From a business perspective the domain

experts are happy, they made a request of the team and the team was able to quickly fulfill the request, new

functionality has been added in a quick and relatively painless way. The second team will however have quite

a different result.

これは非常にステレオタイプな作業です。いくつかの組織では、追跡情報を含むレポートを公表するでしょう。しかし、これは比

較的小さな作業です。ビジネス観点で言うと、要望がすぐに遂行され新機能が追加され、機能追加に伴う悪影響も比較的少なく、

ドメインの専門家は満足します。しかし、第2のチームではまったく異なる結果を出します。

The second team has been storing events; they represent their current state by building up off of a series

of events. They just like the first team go through and add tracking of items removed from carts via a fact

table but they also run this handler from the beginning of the event log to back populate all of the data

from the time that the business started. They release the report in the same iteration and the report has

data that dates back for years.

第2のチームでは、イベントを格納するメカニズムを使用していて、一連のイベントから現在のステートを構築します。第1チー

ムと同様に、実テーブルを踏査してカートから削除された商品を追跡する機能を追加します。ただし、このチームでは、最初のイ

ベントログから収集するハンドラも実行して、システム運用開始時から蓄積している全データについて収集します。同じイテレー

ションで、過去に遡ったデータを含むレポートを公表します。

The second team can do this because they have managed to store what the system actually did as opposed to

what the current state of data is. It is possible to go back and look and interpret the old data in new and

interesting ways. It was never considered to track what items were removed from carts or perhaps the number

of times a user removes and items from their cart was considered important. These are both examples of new

and interesting ways of looking at data.

現在のステートを保持するメカニズムと違って、第2チームではシステムの処理内容を格納しているため、後から新規の関心事が

出てきても、過去に遡ってデータを参照して解釈することができるわけです。カートからどの商品を削除したかを追跡することは、

当初は決して考慮していませんでした。または、ユーザが削除した回数や、カートから削除した商品の個数が重要だと考慮してい

たでしょう。以上、新規に追加した関心事に応じてデータを参照する例を紹介しました。

As the events represent every action the system has undertaken any possible model describing the system can

be built from the events.

イベントが様々なアクションを表現すれば、システムを記述するあらゆるモデルでも、イベントから構築できることを保証します。

Businesses regularly come up with new and interesting ways of looking at data. It is not possible with any

level of confidence to predict how a business will want to look at today’s data in five years. The ability

for the business to look at the data in the way that it wants in five years is of an unknown but possibly

extremely high value; it has already been stated that this should be done in areas where the business derives

its competitive advantage so it is relatively easy to reason that the ability to look at today’s data in an

unexpected way could be a competitive advantage for the business. How do you value the possible success or

failure of a company based upon an architectural decision now?

ビジネスではデータ分析に対して、定期的に新しい関心事が出てきます。今日のデータを、5 年後のビジネスがどのように分析し

たいかを予測するのは不可能です。5 年間でビジネスが求める方法でデータを分析する能力は未知ですが、ビジネスにとっては大

きな価値があります。ビジネスが競争優位性を生む分野でイベントログを活用すべきであることを述べました。そして、今日のデ

ータを意外な方法で分析する能力がビジネス競争優位性に繋がるということを、比較的簡単に推論できます。では、企業の構造的

意志決定の成功/失敗の可能性をどう評価しますか?

How do software teams justify looking at their Magic 8 Ball to predict what the business will need in five

or even ten years? Many try to use YAGNI (You Ain’t Gonna Need It) (Wikipedia) but YAGNI only applies when

Page 40: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 40

you actually know that you won’t need it, how can the dynamic world of business and how they may want to look

at data in five or ten years be predicted?

ソフトウェアチームはMagic 8 Ball(マジックエイトボール)を見て、今後の5~10年間でビジネスが必要とするものを占うな

んてことをはしません。多くのチームは YAGNIをトライします。しかし、YAGNI(You Ain't Gonna Need It=機能は実際に必

要となるまでは追加しない;Wikipedia参照)は必要としないことが実際にわかっている場合に限って適用できるものです。ビジ

ネスのダイナミックな世界において5~10年間でどんなデータを分析したいのかを予測できますか?

Is it more expensive to actually model every behavior in the system? Yes.

Is it more expensive in terms of disk cost and thought process to store every event in the system? Yes.

Are these costs worth the ROI when the business derives a competitive advantage from the data?

システムで実際にあらゆるふるまいをモデル化するのはコストが高いか?→はい。

システムであらゆるイベントを格納するため、多くのディスクが必要であり、思考プロセスが難しくなるか?→はい。

ビジネスがデータを活用して競争優位性を獲得するための、これらのコストがROI向上に結びつくか?

Works Cited | 参考文献

Ambler, S. W. (n.d.). The Object Relational Mismatch. Retrieved from agiledata.org:

http://www.agiledata.org/essays/impedanceMismatch.html

Evans, E. (2001). Domain Driven Design. Addisson Wesley.

Fowler, M. (n.d.). Domain Event. Retrieved from EAA Dev:

http://martinfowler.com/eeaDev/DomainEvent.html

Jill Nicola, M. M. (2002ll). Streamlined Object Modelling. Prentice H.

Object-Relational Impedance Mismatch. (n.d.). Retrieved from Wikipedia:

http://en.wikipedia.org/wiki/Object-relational_impedance_mismatch

Wikipedia. (n.d.). You ain't gonna need it. Retrieved from wikipedia:

http://en.wikipedia.org/wiki/You_ain't_gonna_need_it

Page 41: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 41

Building an Event Storage | イベントストレージの構築

In “Events as a Storage Mechanism” the concept of rebuilding state from a series of events was looked at from

a conceptual viewpoint. This chapter will focus on the implementation of an actual Event Storage and some

of the issues that come up in producing an implementation.

「Events as a Storage Mechanism」では、概念的思考に基づいて、一連のイベントからステートを再構築する概念を述べまし

た。本章では、実際のEvent Storageの実装と、その実装を行う上での問題点について触れます。

The implementation discussed in this chapter is not intended to be a production quality Event Storage, more

so it is provided as a discussion point around how to build an Event Storage. The implementation here although

not highly performant could meet the needs of a large percentage of applications that are built today.

本章では製品レベルの Event Strageの実装には触れずに、Event Storageの構築方法に関する議論を展開します。ただし、こ

こで述べる実装は、今日構築されているほとんどのアプリケーションのニーズに対処できるだけの機能を備えていません。

For the explanatory implementation it is easiest to build the Event Storage in an existing technology such

as a RDBMS. This will alleviate many of the technical issues that can arise that are out of the scope of a

basic discussion on how to build an event storage such as transaction commit models or data locality for read

performance.

実装の説明としては、RDMBSのような既存テクノロジーで Event Storageを構築するのが最も簡単です。イベントストレージの

構築方法に関しては、トランザクション・コミットモデル、または、読み込み性能のためのデータローカリティ(プログラムがデ

ータを参照する時の局所性)などがありますが、Event Storageはこのような基本的な議論の範囲外で発生しうる多くの技術的な

問題を軽減します。

Structure | 構造

A basic Event Storage can be represented in a Relational Database utilizing only two tables.

2つのテーブルのみを使用するリレーショナルデータベースでは、基本的なEvent Storageを表現できます。

Column Name Column Type

AggregateId Guid

Data Blob

Version Int

Figure 19 Table Layout for Events Table | 図19 Eventテーブルのレイアウト

This table represents the actual Event Log. There will be one entry per event in this table. The event itself

is stored in the [Data] column. The event is stored using some form of serialization, for the rest of this

discussion the mechanism will assumed to be built in serialization although the use of the memento pattern

can be highly advantageous.

図19のテーブルは実際のイベントログを格納するものです。このテーブルには、イベントごとに1つずつエントリがあり、「Data」

列にはイベントを格納します。イベントはシリアライズした形式で格納します。(デザインパターンの一種である)Momentパター

ンの利用が非常に有効ですが、後述するメカニズムではシリアライゼーションで構築するものと仮定しています。

The table is shown with the minimum amount of information possible, most organizations would want to add a

few columns such as the time that the change was made or context information associated with the change. Examples

of context information might include the user that initiated the change, the ip address they sourced the change

from, or their level of permission when they sourced the change.

このテーブルには最小限の情報しかありませんが、「更新日時」、「更新を行ったコンテキスト情報」などの列を追加したいという要

件が多くあるでしょう。たとえば、コンテキスト情報には、更新したユーザ、IPアドレス、または、更新した時点のパーミッショ

ンレベルなどの情報が含まれます。

A version number is also stored with each event in the Events Table. This can generally be thought of as an

increasing integer for most cases. Each event that is saved has an incremented version number. The version

number is unique and sequential only within the context of a given aggregate. This is because Aggregate Root

boundaries are consistency boundaries.

Page 42: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 42

この Eventsテーブルには、バージョン番号も格納します。バージョン番号は通常、インクリメントし続ける数値です。格納する

各イベントには、インクリメントしたバージョン番号があります。所定アグリゲートのコンテキスト内では、バージョン番号はユ

ニークな連続した番号です。なぜなら、アグリゲートルートの境界が一貫性を持つ境界だからです。

The [AggregateId] column is a foreign key that should be indexed; it points to the next table which is the

Aggregates table.

「AggregateId」列は、インデックス番号が割り振られた外部キーであり、AggregatesテーブルのIDを指します。

Column Name Column Type

AggregateId Guid

Type Varchar

Version Int

Figure 20 Table Layout for Aggregates Table | 図20 Aggregatesテーブルのレイアウト

Author comment: I have gone back and forth between calling this concept “Aggregate” in the Event Storage in

lieu of another name such as “Event Provider” as “Aggregate” is really a domain concept and an Event Storage

could work without a domain.

著者注:「アグリゲート」はまさにドメイン概念ですが、Event Storageはドメイン無しで実現できます。そのため、私はEvent

Storageにおけるこの概念を、「イベントプロバイダ」の代わりに「アグリゲート」と呼ぶべきかどうか右往左往してきました。

The Aggregates table is representing the aggregates currently in the system, every aggregate must have an

entry in this table. Along with the identifier there is a denormalization of the current version number. This

is primarily an optimization as it could be derived from the Events table but it is much faster to query the

denormalization that it would be to query the Events table directly. This value is also used in the optimistic

concurrency check.

Aggregates テーブルは、システムの現在のアグリゲートを表現します。このテーブルでは、すべてのアグリゲートごとにエント

リがあります。識別子に加えて、現在のバージョン番号を非正規化したものを格納します。Events テーブル由来のこのバージョ

ン番号は、主に最適化のためにありますが、この非正規化バージョン番号をクエリするよりも、直接 Eventsテーブルをクエリす

る方が速いです。この番号は、オプティミスティック同時実行制御(optimistic concurrency)によるチェックで使います。

Also included is a [Type] column for this example, this would be the fully qualified name of the type of aggregate

being stored. This can be useful for various purposes not the least of which is debugging, it is however

unnecessary for the creation of a basic Event Storage.

この例には「Type」列もありますが、これはアグリゲートの完全な型名です。この列は基本的なEvent Storageでは不要ですが、

少なくともデバッグなどの様々な目的で有用です。

Operations | 操作

Event Storages are far simpler than most data storage mechanisms as they do not support general purpose querying.

An Event Storage at its simplest level has only two operations. Having only two operations makes an Event

Storage simpler than most data storage mechanisms as well as easier to optimize.

多目的のクエリをサポートしていない場面では、Event Strogeはほとんどのデータストレージメカニズムよりもはるかに単純で

す。最も単純なレベルのEvent Storageには2つの操作しかありません。2つしかないので、Event Storageはほとんどのデー

タストレージメカニズムより単純であり、最適化も簡単です。

The first operation is to get all of the events for an aggregate. It is extremely important that the events

are ordered in the same order that they were written, the version number can be used for this purpose. This

can all be done quite simply using an underlying RDBMS.

1 つめの操作は、アグリゲートのすべてのイベントを取得するためのものです。イベントを書き出し順に格納することが非常に重

要であり、その目的でバージョン番号が使用可能です。基底にあるRDBMSを使用することにより、本当に単純に処理できます。

SELECT * FROM EVENTS WHERE AGGREGATEID=’’ ORDER BY VERSION

This is the only query that should be executed by a production system against the Event Storage. A possible

Page 43: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 43

secondary query that can be useful is to limit this result set by an actual date to see the state of an object

at a point in time, but generally a production system should not be doing this.

これは、製品システムが Event Storage に対して実行すべき唯一のクエリです。その次のクエリで、その時点におけるオブジェ

クトのステートを参照するために、日付を使って結果セットを絞り込もうとします。しかし、通常の製品システムでは、このクエ

リを実行してはいけません。

The other operation an Event Storage must support is the writing of a set of events to an aggregate root.

This can be done either in code or in a stored procedure. A stored procedure or dynamically generated SQL

containing if statements is preferred as without the insert process will take multiple round trips. The

pseudo-code for the insert process can be seen in Listing 5.

2 つめの操作は、アグリゲートルートにイベント一式を書き出すためのものです。書き出し処理は、プログラムやストアドプロシ

ージャで作成します。ストアドプロシージャまたは動的生成のSQLは、INSERT無しで往復処理ができるようにIFステートメント

を使うのが望ましいです。リスト5は挿入プロセスを実行する擬似コードです。

Begin

version = SELECT version from aggregates where AggregateId = ''

if version is null

Insert into aggregates

version = 0

end

if expectedversion != version

raise concurrency problem

foreach event

insert event with incremented version number

update aggregate with last version number

End Transaction

Listing 5 Write Operation in Event Storage | リスト5 Event Storageでの書き出し処理

The write operation is also relatively simple though there are a few subtleties to be found within it. The

basic narrative is that it first checks to see if an aggregate exists with the unique identifier it is to

use, if there is not one it will create it and consider the current version to be zero. It will then attempt

to do an optimistic concurrency test on the data coming in if the expected version does not match the actual

version it will raise a concurrency exception. Providing the versions are the same, it will then loop through

the events being saved and insert them into the events table, incrementing the version number by one for each

event. Finally it will update the Aggregates table to the new current version number for the aggregate. It

is important to note that these operations are in a transaction as it is required to insure that optimistic

concurrency amongst other things works in a distributed environment.

いくつかの細かい処理がありますが、書き出し処理も比較的単純です。基本的な流れを説明します。まず、ユニークな識別子を使

ってアグリゲートが存在するかどうかをチェックし、存在しなければアグリゲートを生成してバージョン番号を0にします。次に、

入ってくるデータに対して、オプティミスティック同時実行制御でチェックを行い、期待されているバージョン番号と実際のバー

ジョン番号が同値でなければ、例外をスローします。バージョン番号が同値なら、すべてのイベントについて、Events テーブル

にイベントを挿入しバージョン番号をインクリメントするという処理を反復します。最後に、新しい現在のバージョン番号を反映

するために、Aggregates テーブルを更新します。これらの処理を、1 つのトランザクションで行うのが重要です。これは、分散

環境において他の処理が動作していても、オプティミスティック同時実行制御を保証するためです。

The contract for an Event Storage in code can be defined with the following interface.

Event Storageに対するプログラムは、リスト6のようなインタフェースで定義できます。

public interface IEventStore {

void SaveChanges(Guid AggregateId, int OriginatingVersion, IEnumerable<Event> events);

IEnumerable<Event> GetEventsFor(Guid AggregateId);

}

Listing 6 Interface for an Event Store | リスト6 Event Storage向けインタフェース

Page 44: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 44

Although not a trivial exercise to create a production quality Event Storage the overall concepts behind an

Event Storage are relatively easy. Likely in the future there will be many off the shelf Event Storage systems

available as either products or open source projects. There is however one very important optimization that

was discussed in “Events as a Storage Mechanism” that really should exist in most systems and that is the

concept of a “Rolling Snapshot”.

製品レベルの Event Strageを作成するのは決して簡単ではありませんが、Event Storageを背景とした全体的な概念は比較的

簡単です。将来、多くの既製(=off the shelf)Event Storageシステムが、製品またはオープンソースプロジェクトから出てく

るでしょう。ただし、一つの重要な最適化があります。この最適化は、「Event as a Storage Mechanism」で記述したように、

ほとんどのシステムでまさに必要なものであり、「Rolling Snapshot」の概念です。

Rolling Snapshots | スナップショットの巻き出し

Rolling Snapshots are a heuristic to prevent the need to load all of the events when issuing a query to rebuild

an Aggregate. They are a denormalization of the aggregate at a given point in time. A change to the query

logic and an additional table are all that is necessary to add the heuristic to the basic Event Storage. Further

discussion on Rolling Snapshots at a conceptual level can be found in the “Events as a Storage Mechanism”

chapter.

Rolling Snapshots は、アグリゲートを再構築するクエリの発行時に、すべてのイベントをロードするコストを回避するヒュー

リスティックです。Rolling Snapshots は、所定時刻におけるアグリゲートを非正規化したものです。クエリ処理を変更したり

テーブルを新規追加したりすると、すべて、基本的な Event Storage にそのヒューリスティックを追加する必要があります。

Rolling Snapshotsの概念的なレベルについては、「Events as a Storage Mechanism」を参照してください。

Column Name Column Type

AggregateId Guid

SerializedData Blob

Version Int

Figure 21 Definition of Snapshots Table | 図21 Snapshotsテーブルの定義

The Snapshots table is relatively basic. It’s primary data in the blob that contains the serialized version

of the aggregate at a given point in time. The serialized data could be in any one of a host of possible schemas,

binary, XML, raw text, etc. The decision on how to serialize the snapshots is really dependent upon the system

being built. A version number is included with the snapshot, it represents which version of the aggregate

the snapshot represents.

図 21は基本的な Shapshotsテーブルです。Blob内のプライマリデータには、所定時刻におけるアグリゲートのシリアライズバ

ージョンがあります。シリアライズするデータとしては、スキーマ、バイナリ、XML、または、テキストなどがあります。構築す

るシステムに応じて、スナップショットのシリアライズ方法を決めます。バージョン番号はスナップショットが表現するアグリゲ

ートのバージョンであり、スナップショットにも含まれています。

In order to have snapshots being created a process that handles the task of creating the snapshots needs to

be introduced. This process can live outside of the Application Server as a background process. There can

be a single process running or many depending on needs due to throughput. All snapshots happen asynchronously.

Figure 4 shows a conceptual architecture with a [SnapShotter] process introduced.

スナップショットを作成するためには、アプリケーションサーバとは別に、スナップショットの生成処理を行うプロセス

(ShapShotter)をバックグランドプロセスとして起動する必要があります。SnapShotterは単一プロセスでもよいし、スループ

ットのニーズに応じて複数プロセスで動作し、非同期でスナップショットを作成します。図22は、SnapShotterを含むアーキテ

クチャの概念図です。

Page 45: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 45

Figure 22 Introduction of a Snapshotter | 図22 SnapShotterの導入

The [SnapShotter] sits behind the Event Storage and periodically queries for any Aggregates that need to have

a snapshot taken because they have gone past the allowed number of events. This query can be done quite easily

in the simple Event Storage discussed by joining the Aggregates table to the Snapshots table on the Aggregate

identifier. The difference is calculated by subtracting the last snapshot version from the current version

with a where clause that only returned the aggregates with a difference greater than some number. This query

will return all of the Aggregates that a snapshot to be created. The snapshotter would then iterate through

this list of Aggregates to create the snapshots (if using multiple snapshotters the competing consumer pattern

works well here).

ShapShotterはEvent Storageの向こう側にあります。SnapShotterはスナップショット採取対象のアグリゲートに対して定期

的にクエリを発行し、設定数のイベントをスナップショットとして格納します。AggregatesテーブルをSnapshotsテーブルの同

じAggregateIdのエントリと結合すれば、単純なEvent Storageでは、このクエリをごく簡単に実行できます。いくつかのバー

ジョン番号より大きいアグリゲートを返すだけのWHERE節を使って、現在のバージョン番号から最終スナップショットのバージョ

ン番号を引いて差分を計算します。このクエリの発行により、スナップショットを作成するためのすべてのアグリゲートを取得し

ます。そして、SnapShotter はアグリゲートのリストをイテレートして、複数のスナップショットを作成します(複数の

Snapshotterを並行実行する場合、Competing Consumerパターンを適用するのが良い)。

The process of creating a snapshot involves having the domain load up the current version of the Aggregate

then take a snapshot of it. The creation of the snapshot can be done in many ways. Once the snapshot has been

taken, it is saved back to the snapshot table so that queries will have the snapshot available.

スナップショットを生成するプロセスは、ドメインにアグリゲートの現バージョン番号をロードさせ、そのスナップショットを採

ります。スナップショットの生成には、多くの方法があります。一度スナップショットを採取したら、クエリでスナップショット

を取ってこれるようにスナップショットのテーブルに格納します。

Many use the default serialization package available with their platform with good results though the Memento

pattern is quite useful when dealing with snapshots. The Memento pattern (or custom serialization) better

insulates the domain over time as the structure of the domain objects change. The default serializer has

versioning problems when the new structure is released (the existing snapshots must either deleted and recreated

or updated to match the new schema). The use of the Memento pattern allows the separated versioning of the

snapshot schema from the domain object itself.

スナップショットの処理にはMementoパターンを使うのが有効であっても、当該プラットフォームで利用可能なデフォルトのシリ

アライゼーションパッケージを使うことが多いです。Mementoパターン(または、カスタムシリアライゼーション)は、ドメイン

オブジェクト構造の変更に従って、長い年月をかけて少しずつドメインを分離します。デフォルトのシリアライザは、新しい構造

をリリースする場合のバージョン管理に問題を抱えています(既存のスナップショットを削除、再生成、または、新しいスキーマ

に合わせて更新する必要がある)。Memento パターンを使用すれば、ドメインオブジェクト自身からスナップショット・スキーマ

Page 46: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 46

のセパレート・バージョン管理(分離バージョン管理?)ができるようになります。

In “Events as a Storage Mechanism” a different, simpler mechanism was shown for the storage of snapshots.

That system had the snapshots in line in the Event Log, this other mechanism although conceptually simpler

has a few issues that can come up in a production system. The issues revolve around the need of ordering of

the snapshot within the event log.

「Events as a Storage Mechanism」で、スナップショットのストレージについて、異なった単純なメカニズムを述べました。

そのシステムにはイベントログを並べたスナップショットを持っていましたが、他の単純な概念を使うメカニズムの場合、製品シ

ステムでいくつかの問題を抱えます。イベントログ内のスナップショットをクエリする必要性が、問題の根源です

Consider that the Snapshotter has realized that an Aggregate Root needs to have a snapshot taken. It loads

up the Aggregate and takes the snapshot. Unfortunately while it was doing this, one of the Application Servers

made a change to the same Aggregate. As the snapshot is position dependent within the Event Log, it would

receive an optimistic concurrency failure. The easy answer would be to simply repeat the process but what

if it failed again? The snapshotter on a very busy Aggregate could end up in a situation where it would have

a very low probability of actually writing the snapshot successfully.

スナップショットを採取する必要があるアグリゲートルートを、SnapShotterが正規化する場合を考えてみましょう。アグリゲー

トをロードし、スナップショットを採取するとします。この処理を実行している間に、運悪く、アプリケーションサーバが同一の

アグリゲートに対して変更を加えたとします。スナップショットはイベントログ内の位置に依存しているので、オプティミスティ

ック同時実行制御でエラーが発生するでしょう。これに対する簡単な対処方法としては、単純に SnapShotter の実行を繰り返す

ことです。しかし、またエラーが発生したらどうしますか?非常にビジーな状態のアグリゲート上で動作する SnapShotter は、

スナップショットを正常に書き込む可能性が非常に低い状況で終わることになるでしょう。

By separating the snapshots into their own table and associating them to a version of the aggregate this problem

is solved. Ordering of snapshots is not needed, the snapshot does not even need to be at the latest version,

the snapshot that is taken is valid at the version it was taken.

各テーブルごとにスナップショットを採取して、アグリゲートのバージョン番号で結びつけるようにすれば、この問題は解決でき

ます。スナップショットをクエリする必要はなく、また、最新のバージョン番号に対するスナップショットも必要なく、採取する

スナップショットは採取済みバージョン番号であれば有効です。

Snapshots are a heuristic that will dramatically improve the performance of many systems, though not all systems

need snapshotting. It is generally recommended to handle development without snapshotting as it can always

be introduced later as a simple performance enhancement for the system.

すべてのシステムがスナップショットの採取を必要としているわけではないですが、多くのシステムではスナップショットは性能

を劇的に改善するヒューリスティックです。しかし、のちにシステムに対する単純な性能改善方法を導入できるようにする意味で

は、一般的には、スナップショット採取無しで開発を進めるのを推奨します。

Event Storage as a Queue | キューとしてのイベントストレージ

It has been previously discussed that the events coming out of a domain are also an [Integration Model]. Very

often these events are not only saved but also published to queue where they are dispatched asynchronously

to listeners either within the same system (the reporting model is a good example) or to other applications.

An issue that exists with many systems publishing events is that they require a two-phase commit between whatever

storage they are using (Relational or otherwise) and the publishing of their events to the queue.

先述のとおり、ドメインから発行するイベントは「統合モデル」でもあります。通常、イベントは格納するだけでなく、キューに

も送信し、同一システム(レポーティングモデルが良い例)のリスナか、他のアプリケーションのリスナに対して非同期に配信し

ます。多くのシステムでは、イベント発行について問題を抱えています。ストレージ(リレーショナルかどうかを問わない)と、

キュー対するイベント発行の間に、2フェーズのコミットを必要としています。

The reason that the two-phase commit is needed is that a catastrophe could occur during the small period of

time between when the write to the data storage commits and when the write to the queue commits. If a failure

were to happen during this period the message would not be published on the queue (or if the other direction

it may be published but the change may not be saved). If either case were to happen the listeners of the events

would be out of sync with the producer.

Page 47: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 47

データストレージへの書き出しで行われるコミットと、キューへの書き出しで行われるコミットの2つは短い期間ですが、その間

に障害が発生する可能性があるため、2 フェーズのコミットが必要になります。この期間に障害が起きたら、キュー対してメッセ

ージが発行されません。仮にメッセージの方向が違う場合、メッセージを発行できたとしても、変更が格納されません。仮に両方

のケースが起きた場合、プロデューサとイベントリスナはともに、同期処理の蚊帳の外に置かれてしまいます。

The two-phase commit can be expensive but for low latency systems there is a larger problem when dealing with

this situation. Generally the queue itself is persistent so the event becomes written on disk twice in the

two-phase commit, once to the Event Storage and once to the persistent queue. Given for most systems having

dual writes is not that important but if you have low latency requirements it can become quite an expensive

operation as it will also force seeks on the disk. Figure 23 illustrates the two-phase commit between data

storage and a publishing queue.

2 フェーズのコミットは非常にコストが高くなりがちです。しかし、低レイテンシなシステムであっても、さらに重大な問題があ

ります。一般的にキュー自体は永続的なので、2フェーズのコミットによりイベントが2度ディスクに書き出される(イベントス

トレージに 1度、永続キューに 1度)ことになります。ほとんどのシステムでは二重書き出しは問題にならないかもしれません。

しかし、ディスクのシークを強要する場合、低レイテンシの要件に対して非常にコストが高くなることもあります。図 23 は、2

フェーズのコミット(データストレージへの格納とキューへの発行の間)を示しています。

Figure 23 Two Phase Commit with Queue | 図23 2フェーズのコミット

Some try to get around this problem by only writing to a queue then have something on the other side of the

queue update the data storage with the changes represented by the events, this however has some issues. The

largest issue is that not all of the events will be able to be written to the storage, eventual consistency

has been introduced and it is possible that an optimistic concurrency problem will occur on the write of the

events. Dealing with this problem in a production system is non-trivial.

一部のシステムではキューへの書き出しだけにして、イベントが表現する変更をデータストレージに反映するためにもう1つのキ

ューを用意して、この問題を回避しようとします。それでも若干の問題があります。最も重大な問題は、すべてのイベントがスト

レージに書き出されるとは限らない点です。結果、整合性を導入しても、イベントの書き出しにおけるオプティミスティック同時

実行制御で問題が発生する可能性があります。製品システムにとっては、この問題に対処することは容易ではありません。

Many organizations do the opposite, use the event storage as a queue. Adding a sequence number to the Events

table previously discussed allows the use the Event Storage as a queue. Figure 24 illustrates the change to

the schema of the Events table.

多くの組織では、逆にイベントストレージをキューとして使います。先述の Eventsテーブルにシーケンス番号を追加して、イベ

ントストレージをキューとして使います。Eventsテーブルのスキーマの変更を、図24に示します。

Column Name Column Type

AggregateId Guid

Data Blob

SequenceNumber Long

Figure 24 Events Table as a Queue | 図24 キューとしてのイベントテーブル

The database would insure that the values of sequence number would be unique and incrementing, this can be

Page 48: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 48

easily done using an auto-incrementing type. Because the values are unique and incrementing a secondary process

can chase the Events table, publishing the events off to their queue. The chasing process would simply have

to store the value of the sequence number of the last event it had processed, it could even update this value

with a two-phase commit bringing the update and the publish to the queue into the same transaction. This process

can be seen in Figure 7.

データベースでは自動インクリメント型を使えば、シーケンス番号がユニークになることを容易に保証できます。そうすれば、第

2のプロセスは Eventsテーブルを追跡して、キューにイベントを発行できます。この追跡プロセスは、単純に、処理済みの最終

イベントのシーケンス番号を格納する義務があるだけです。追跡プロセスは2フェーズのコミットでシーケンス番号を更新し、キ

ューへの更新と発行を同一トランザクションで実行できます。この処理の流れを、図25に示します。

Figure 25 Event Storage as a Queue | キューとしてのEvent Storage

The work has been taken off of the initial processing in a known safe way. The publish can happen asynchronously

to the actual write. This lowers the latency of completing the initial operation, it also will limit the number

of disk writes in the processing of the initial request to one. This strategy can be extremely valuable when

dealing with low latency requirements as it allows much of the work on the initial processing to be offloaded

to another process asynchronously and in a safe way, there is little difference whether the publish happens

as part of the initial processing or asynchronously as generally messages are published asynchronously anyways,

using the Event Store as a queue just raises the time until the message is actually published slightly, this

can be viewed as slightly raising the SLA.

この追跡プロセスは、安全な方法で初期プロセスと同様の結果をもたらします。キューへの発行によって非同期の書き込みが可能

です。初期プロセスが低レイテンシで完了するので、ディスクへの書き出し数も抑制します。この手順は、低レイテンシの要件に

対応する価値が大いにあります。初期プロセスを、非同期かつ安全な方法で追跡プロセスに移管するので、初期プロセスの処理数

が増えます。初期プロセスの一部としてキューに発行する場合と、追跡プロセスが非同期でメッセージを発行する場合とで、ほと

んど差がありません。Event Storageをキューとして使用しても、メッセージを実際に発行するまでの時間がわずかに増えるだけ

で、SLA(Service Level Agreement)もわずかに増えるだけしょう。

Page 49: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 49

CQRS and Event Sourcing | CQRSとイベント供給

CQRS and Event Sourcing become most interesting when combined together. This chapter looks at the intersection

of these two concepts within a system where Domain Driven Design has been applied.

CQRSとイベント供給の相互結合には、興味深いものがあります。本章では、ドメイン駆動設計を適用したシステムにおけるこの2

つの概念の相互作用について見ていきます。

CQRS and Event Sourcing have a symbiotic relationship. CQRS allows Event Sourcing to be used as the data storage

mechanism for the domain. One of the largest issues when using Event Sourcing is that you cannot ask the system

a query such as “Give me all users whose first names are ‘Greg’”. This is due to not having a representation

of current state. With CQRS the only query that exists within the domain is GetById which is supported with

Event Sourcing.

CQRSとイベント供給には共生関係があります。CQRSではドメイン向けデータストレージのメカニズムとして、イベント供給を使

います。イベント供給を使う際の一番大きな問題の一つとして、「Gregという名前のユーザを列挙してください」といったクエリ

をシステムに問い合わせることができない点があります。なぜなら、システムが現在のステートの表現を持っていないからです。

イベント供給をサポートしているCQRSでは、ドメイン内にはGetByIdのクエリしかありません。

Event Sourcing is also very important when building out a non-trivial CQRS based system. The problem with

integration between the two models is a large one. The maintaining of say relational models, one for read

and the other for write, is quite costly. It becomes especially costly when you factor in that there is also

an event model in order to synchronize the two. With Event Sourcing the event model is also the persistence

model on the Write side. This drastically lowers costs of development as no conversion between the models

is needed.

イベント供給は、非凡な CQRSベースのシステムを構築する際には、非常に重要です。この 2モデル間を統合する際の問題は、重

要な問題の一つです。読み込みと書き出しのリレーショナルモデルの議論を継続するのが難しく、特に、この2つを同期するため

のイベントモデルの存在を考慮するのが非常に困難です。イベント供給では、イベント・モデルは、書き出し側の永続モデルでも

あります。モデル間の変換が不要なので、開発コストを大幅に下げます。

Figure 26 Stereotypical Architecture Sending Commands | 図26 コマンドを送信するステレオタイプなアーキテクチャ

The original stereotypical architecture with using commands in Figure 1 can be compared to Figure 2 CQRS with

Event Sourcing and found to be roughly equivalent amounts of work.

コマンドを使用する初期のステレオタイプなアーキテクチャを図26に、イベント供給を使用するCQRSを図27に示します。ざっ

と見ると、作業量が同程度であることがわかります。

Page 50: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 50

Figure 27 CQRS with Event Sourcing | 図27 イベント供給を使用するCQRS

Cost Analysis | コスト分析

The client will be identical amounts of work between the two architectures. This is because the client operates

in the exact same way. In both architectures the client receives DTOs and produces Commands that tell the

Application Server to do something.

この 2 つのアーキテクチャのどちらを使っても、クライアントは同じ方法で操作するので、クライアント側の作業量は同じです。

両アーキテクチャとも、クライアントはDTOsを受け取ったら、アプリケーションサーバに対して依頼するコマンドを生成します。

The queries between the two models will also be very similar in terms of cost. In the stereotypical architecture

the queries are being built off of the domain model, in the CQRS based architecture they are being built by

the Thin Read Layer projecting directly to DTOs. As was discussed in “Command and Query Responsibility

Segregation” the Thin Read Layer should be equally or in some cases less expensive.

この2つのモデルにおけるクエリは、コスト面では同じくらいです。ステレオタイプなアーキテクチャでは、クエリはドメインモ

デルで構築されます。CQRSベースのアーキテクチャでは、クエリはThin Read Layerで構築され、DTOsに投影します。「Command

and Query Responsibility Segregation」で述べたように、Thin Read Layer はコストが同じか、場合によっては増えない

ようにするべきです。

The main differentiation between the two architectures when looking at cost is in the domain model and

persistence. In the stereotypical architecture an ORM was doing most of the heavy lifting in order to persist

the domain model within a Relational Database. This process introduces an Impedance Mismatch between the domain

model and the storage mechanism, the Impedance Mismatch as discussed in “Events as a Storage Mechanism” can

be highly costly both in productivity and the knowledge that developers need to have.

2 つのアーキテクチャのコスト面における主な相違点は、ドメインモデルと永続性にあります。ステレオタイプなアーキテクチャ

では、ORMはリレーショナルデータベース内でドメインモデルを永続化するために、大部分の重いリフティングを行っていました。

このプロセスは、ドメインモデルとストレージメカニズムとの間にインピーダンスミスマッチを起こします。「Events as a

Storage Mechanism」で述べたように、インピーダンスミスマッチは、生産性の低下を招くとともに、開発者に必要な知識が増大

します。

The CQRS and Event Sourcing based architecture does not have an Impedance Mismatch between the domain model

and the storage mechanism on the Write side. The domain produces events, these same events are all that is

stored. The usage of events is all that the domain model knows about. There is however an impedance mismatch

in the read model. The Event Handlers must take events and update the read model to its concept of what the

events mean. The Impedance Mismatch here is between the Events and the Relational Model.

Page 51: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 51

CQRSとイベント供給ベースのアーキテクチャには、書き出し側にはドメインモデルとストレージメカニズムとの間にインピーダン

スミスマッチがありません。ドメインがイベントを生成し、すべてのイベントを格納します。イベントの使用は、ドメインモデル

が知っていることのすべてです。しかし、読み込み側にはインピーダンスミスマッチが存在します。イベントハンドラはイベント

を取り出して、読み込みモデルをそのイベントが意味する概念に反映しなければなりません。イベントとリレーショナルモデルの

間にインピーダンスミスマッチがあります。

The Impedance Mismatch between events and a Relational Model is much smaller than the mismatch between an

Object Model and a Relational Model and is much easier to bridge in simple ways. The reason for this is that

the Event Model does not have structure, it is representing actions that should be taken within the Relational

Model.

イベントとリレーショナルモデル間のインピーダンスミスマッチは、オブジェクトモデルとリレーショナル間のミスマッチよりも

はるかに小さく、そのブリッジもはるかに容易に単純な方法で実現できます。理由として、イベントモデルは構造を持たず、リレ

ーショナルモデルの範囲内で発生するアクションを表現するためです。

Looked at from this perspective, the two architectures have roughly the same amount of work being done. It's

not that its a lot more work or a lot less work; its just different work. The event based model may be slightly

more costly due to the need of definition of events but this cost is relatively low and it also offers a smaller

Impedance Mismatch to bridge which helps to make up for the cost. The event based model also offers all of

the benefits discussed in “Events” that also help to reduce the overall initial cost of the creation of the

events.

全貌をざっと見る限り、この2つのアーキテクチャは処理する作業量が同じです。ただし、作業が多い/少ないというのではなく、

作業内容が異なります。イベントベースのモデルではイベントの定義のためにわずかにコストがかかる場合がありますが、このコ

ストは比較的小さく、コストが大きいインピーダンスミスマッチの抑制に貢献します。イベントベースのモデルは、「Events」で

述べたすべての利益を生むだけでなく、イベントの作成に必要なすべての初期コストの抑制にも貢献します。

That said the CQRS and Event Sourcing model is actually less expensive in most cases!

CQRSとイベント供給モデルは、ほとんどのケースでは実際は高価ではなかったということです!

Integration | 統合

Everything up until this point has been comparing the systems in isolation. This rarely happens within an

organization. More often than not organizations do only rely on systems but on systems of systems that are

integrated in some way.

以上、分離システムを比較してきましたが、そのようなことは組織内では滅多にありません。たいていの組織は、何らかの方法で

統合したシステムのシステムに頼るだけです。

With the stereotypical architecture no integration has yet been supported, except of course perhaps integration

through the database which is a well established anti-pattern for most systems. Integration is viewed as an

afterthought.

アンチパターンで確立したデータベースを統合したシステムを除き、ステレオタイプなアーキテクチャでは今まで統合システムを

サポートしていませんでした。システムの統合は、後出しのケースが多いです。

The integration must be custom written. Many organizations choose to build services over the top of their

model to allow for integration. Some of these services may be the same services that the clients use but more

often than not there is additional work that must be done in order to support integration.

統合は顧客で実施しなければなりません。多くの組織では、統合を可能にするためにこれらのモデルの上部にサービスを構築する

ことを選択します。これらのサービスの一部は、クライアントが使用するサービスと同じである場合があります。しかし、たいて

いは、統合をサポートするために追加で実施しなければならない作業もあります。

A larger problem exists when the product is being delivered to many customers. It is the teams responsibility

to provide hooks for all of the customers and how they would like to integrate with the system. This often

becomes a very large and unwieldy piece of code, especially on systems that are installed at hundreds or thousands

of different clients all of which have different needs. The business model here tends to be to bill the client

for each piece of custom integration, this can be quite profitable but it is a terrible model in terms of

Page 52: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 52

software.

製品を多くの顧客に出荷するときには、大きな問題があります。すべての顧客にフックと、システムを統合する方法を提供するの

が、チームの債務です。これにより、特に異なるニーズを持つクライアントが百も千もインストールされているようなシステムで

は、肥大化とコードの複雑化とシステムの肥大化に繋がります。このようなビジネスモデルは、顧客にはカスタムメイド統合の各

機能ごとに請求する傾向があります。有利に働く場合がありますが、ソフトウェア界の恐ろしいモデルです。

With the CQRS and Event Sourcing based model, integration has been thought of since the very first use case.

The Read side needs to integrate and represent what is occurring on the Write Side, it is an integration point.

The integration model is “production ready” all throughout the initial building of the system and it is being

tested throughout by the integration with the Read Side.

CQRSとイベント供給ベースのモデルでは、統合は一番最初のユースケースから考案されました。読み込み側は、書き出し側で発生

している事柄を統合し、表現する必要があります。これが統合のポイントです。統合モデルは、すべてのシステムの初期構築のあ

らゆるところで「production ready」であり、読み込み側の統合によって継続的にテストが行われています。

The event based integration model is also known to be complete as all behaviors within the system have events.

If the system is capable of doing something, it is by definition automatically integrated. In some circumstances

it may be desirable to limit the publishing of events but it is a decision to limit what is published as opposed

to needing to write code to publish something.

イベントベース統合モデル(訳注:参考文献「A framework for event-based software integration」)は、システム内のす

べてのふるまいがイベントを持つ完全なモデルであるとも知られています。システムが何かを実行する能力があるならば、それは

自動的に統合された定義に基づいています。いくつかの環境では、イベント発行を制限するのが望ましい場合があります。ただし、

発行を制限する場合でも、イベント発行をコーディングする必要性が無くなるわけではありません。

The event based model is also by nature a push model that contains many advantages over the pull model. If

the stereotypical architecture desired a push based model then there would be large amounts of work added

to track events and ensure that they were synchronized with what the system recorded in its own data model.

また、イベントベースのモデルは本来、pull型モデルに勝る多くの利点を持つpush型モデルです。ステレオタイプなアーキテク

チャが push型ベースのモデルを望む場合、イベント追跡のため、また、システムが自身のデータモデルに記録したものとの同期

したことを保証するために、多くの作業を追加することになるでしょう。

Differences in Work Habits | 作業習慣における相違点

The two architectures also differ greatly in parallelization of work. In the stereotypical architecture work

is generally done in vertical slices. There are four common methodologies used.

2 つのアーキテクチャには、作業の並行化においても大きな相違点があります。ステレオタイプなアーキテクチャでは、作業は垂

直スライスで実行します。4つの共通の方法論を使っています。

Data Centric: Start with database and working out.

Client Centric: Start with client and work in.

Façade/Contract First: Start with façade, then work back to data model then work finally implement client

Domain Centric: Start with the domain model, work out to the client then implement data model

データ中心: データベースで始まり、データベースに出力する

クライアント中心: クライアントで始まり、クライアントに入力する

ファサード/コントラクト第一: ファサードで始まり、データモデルに戻って作業し、最後にクライアントを実装する

ドメイン中心: ドメインモデルで始まり、クライアントに出力し、データモデルを実装する

These methodologies all have a commonality; they tend to work in vertical slices. The same developers will

work on a feature through these steps. The same can be done with the CQRS and Event Sourcing based architecture

but it does not need to be. Consider a very high level view of the systems as contained in Figure 28.

これらの方法論はすべて共通点があります。垂直スライスで作業する傾向があります。同じ開発者たちは、これらのステップを通

して機能を作り込みます。CQRSとイベント供給ベースのアーキテクチャでも同じですが、必須ではありません。図28のシステム

の鳥瞰図について考えてみましょう。

Page 53: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 53

Figure 28 High Level View of CQRS and Event Sourcing | 図28 CQRSとイベント供給の鳥瞰図

The architecture can be viewed as three distinct decoupled areas. The first is the client; it consumes DTOs

and produces Commands. The second is the domain; it consumes commands and produces events. The third is the

Read Model; it consumes events and produces DTOs. The decoupled nature of these three areas can be extremely

valuable in terms of team characteristics.

このアーキテクチャには、3つの領域があります。1つめはクライアントであり、DTOsを消費しコマンドを生成します。2つめは

ドメインであり、コマンドを消費し、イベントを生成します。3つめは読み込みモデルであり、イベントを消費し、DTOsを生成し

ます。3つの領域に分離することは、チーム特性に関して、非常に重要です。

Parallelization | 並列化

It is relatively easy to have five to eight developers working on vertical slices at a given point without

running into too many conflicts in what is being done. This is because for a small number of developers it

is relatively easy to communicate what each developer is working on and to insure that there are few if any

areas where developers overlap. This problem becomes much more difficult as you scale up the number of

developers.

開発者が 5~8 人であれば、同時に縦スライスで作業しても衝突が多発しにくく、開発が比較的容易です。なぜなら、開発者が少

人数であれば、作業内容について互いにコミュニケートしやすく、作業の重複も少なくなります。開発者の人数を増やすと、問題

がずっと難しくなります。

Instead of working in vertical slices the team can be working on three concurrent vertical slices, the client,

the domain, and the read model. This allows for a much better scaling of the number of developers working

on a project as since they are isolated from each other they cause less conflict when making changes. It would

be reasonable to nearly triple a team size without introducing a larger amount of conflict due to not needing

to introduce more communication for the developers. They still communicate in the same way but they communicate

about smaller decoupled pieces. This can be extremely beneficial when time to market is important as it can

drastically lower the amount of calendar time to get a project done.

チームは、垂直スライスで作業する代わりに、3 つの並列な垂直スライス(クライアント、ドメイン、読み込みモデル)で作業可

能です。開発者は互いに分離していて変更作業の衝突が起きにくいため、プロジェクトの開発者を増員しやすくなります。開発者

のコミュニケーション量が増えることがなく、多くの衝突も増えないので、3 倍近く合理的になるでしょう。作業領域を細分化す

ることにより、開発者同士のコミュニケーションが従来通りであっても、プロジェクト完了までの暦時間が大幅に減り、出荷まで

の時間も短縮します。

All Developers are not Created Equally | 開発者は同じものを作らない

There, it has been said. On a team there are many different types of developers, some attributes to consider

in differences amongst developers include

前から言われていることですが、様々なタイプの開発者がいるチームでは、開発者間には考慮すべき特質があります。

Technical Proficiency | 技術力

Page 54: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 54

Knowledge of the Business Domain | ビジネスドメインの知識

Cost | コスト

Soft Skills | 柔軟なスキル

The points of decoupling are natural and support the specialization of teams in given areas. As an example

in the domain, the best candidate is a person who is high in cost but also has a large amount of business

knowledge, technical proficiency, and soft skills to talk with domain experts. When dealing with the read

model and the generation of DTOs this is simply not the case, it is a relatively straight forward thing to

do. The requirements are different which often leads to the next item.

領域を分離する目的は自然であり、特定領域に対するチームの専門化を促進します。ドメイン領域の開発者としては、手当てが高

い代わりに、豊富なビジネス知識、技術力、柔軟なスキルを所有し、ドメインの専門家と会話できる人材が最良の候補例です。し

かし、読み込みモデルと DTOs 生成に対処する場合は、話が違います。比較的、作業内容に直結します。次に示すように、開発者

に対する必須要件が異なります。

Outsourcing | アウトソーシング

It is often not cost effective to keep low cost, medium skilled developers on a team. The overhead of keeping

employees in terms of salary costs as well as compliance with various governmental regulations is often not

worth the benefits of having the developers as employees. If a company is in a high cost locale, the company

can certainly get cheaper developers offshore. Whether offshore or onshore the separation helps with

successfully outsourcing part of a project.

手当てが低い中級レベルの開発者をチームに抱えると費用対効果が良くないことがあります。従業員を抱えることは給与経費の面

でオーバーヘッドが高く、様々な行政規則の遵守する意味でも開発者を従業員として抱える価値がない場合もあります。会社が地

価が高いところにある場合、オフショアにより開発者を低コストで確保できます。領域の分離はオフショア/オンショアに関わら

ず、プロジェクトの一部を外注しやすくなります。

Outsourced projects often fail because large amounts of communication are required between the outsourcers

and the local team or domain experts. With these communications many problems can come up including time

differences, cultural, and linguistic.

内部チーム/ドメインの専門家と外注先との間に非常に多くのコミュニケーションを必要とするため、外注したプロジェクトが失

敗することがよくあります。特に、時差、文化、言語の違いが、コミュニケーション問題を顕著化します。

The Read Model as an example is an ideal area of the system to outsource. The contracts for the Read Model

as well of specifications for how it work are quite concrete and easily described. Little business knowledge

is needed and the technical proficiency requirements on most systems will be in the midrange.

読み込みモデルは、外注契約や仕様書を具体的に容易に記述できるため、外注に向いています。必要なビジネス知識が少なく、ほ

とんどのシステムでは技術力の必須要件も中層レベルです。

The Domain Model on the other hand is something that will not work at all if outsourced. The developers of

the Domain Model need to have large amounts of communications with the domain experts. The developers will

also benefit greatly by having initial domain knowledge. These developers are best kept locally within the

team and should be highly valued.

一方、ドメインモデルは、外注がまったくうまくできません。ドメインモデルの開発者は、ドメインの専門家と非常に多くのコミ

ュニケーションを行わなければなりません。開発者はドメインに関する初期知識を持っていることも大切です。このような開発者

はチーム内に置いておいた方がよく、高く評価しなければなりません。

A company can save large amounts of capital by outsourcing this area of the system at a low risk, this capital

can then be reinvested in other, more important areas of the system. The directed use of capital is very important

in reaching a higher quality, lower cost system.

会社はシステムを外注することにより、低リスクで大量の資本を節約でき、システムの他の重要な領域に回すことができます。資

本運用は、より高品質かつ低価格なシステムを構築するうえで重要です。

Specialization | 特殊化/専門化

A problem exists when working with vertical slices. The “best” developers, with best being defined as most

valuable, work with the domain. When working with a vertical slice though anecdotal evidence suggests that

Page 55: CQRS Documents by Greg Young - MINATO.TV · 2014-04-07 · CQRS and Event Sourcing ... It is important to note that although Figure 1 is drawn without a data tier one could place

CQRS Documents by Greg Young

http://cqrsinfo.com 55

they spend roughly 20-30% of their time in this endeavor.

垂直スライスでの作業には問題があります。「ベスト」な開発者(最も重要な開発者)は、ドメインで作業します。垂直スライスで

の作業では、開発者たちは本作業には約20-30%の時間しか努力しないことを示唆する事例証拠があります。

With the secondary architecture, the team of developers working with the domain spend 80+% of their time working

with the domain and interacting with Domain Experts. The developers have no concern for how the data model

is persisted, or what data needs to be displayed to users. The developers focus on the use cases of the system.

They need only know Commands and Events.

第2のアーキテクチャでは、ドメインで作業しているチームの開発者たちは、ドメインの作業とドメインの専門家との共同作業に

80%以上の時間を費やします。開発者たちはデータモデルがどのように永続化されるのか、または、どんなデータをユーザに見せ

る必要があるのかについては、関心がありません。開発者たちは、システムのユースケースに焦点を当てます。知る必要があるの

は、コマンドとイベントだけです。

This specialization frees them to engage in the far more important activities of reaching a good model and

a highly descriptive Ubiquitous Language with the Domain Experts. It also helps to optimize the time of the

Domain Experts as opposed to having them sit idly while the “technical” aspects of vertical slices are being

worked on.

十分に専門化がされていれば、ドメインの専門家との共同作業で、良いモデルと高レベルなユビキタス言語を目指す非常に重要な

活動に従事する必要が無くなります。垂直スライスのテクニカル部分に取り組んでいる間に、ドメインの専門化がただ座っている

だけという時間をも減らします。

Only Sometimes | 時には

There are many benefits offered through the separation but they do not need to be used. It is also quite common

to have a normal sized team still work in vertical slices. There are benefits in terms of risk management

amongst other things to having a small to medium sized team work in vertical slices of the whole system.

分離は多くのメリットをもたらしますが、開発者たちは使われる必要はありません。従来の垂直スライスで作業するチームでは、

ノーマルな人数で構成するのはごく一般的なことです。システム全体を垂直スライスで作業する小~中規模のチームを持つことは、

他のリスク管理に関してメリットがあります。

The real benefit with the CQRS and Event Sourcing based architecture is that the option exists to bring it

into three distinct vertical slices with each having its own attributes optimized as opposed to using a one

size fits all mechanism.

CQRS とイベント供給ベースのアーキテクチャを使用する真のメリットは、すべてのメカニズムを 1 つの垂直スライスで行うのに

対し、それぞれ最適化した特性を持つ3つの垂直スライスに分離するためのオプションがあることです。

EOF