Skip to content

Commit 0982f00

Browse files
authored
Merge pull request iluwatar#595 from isabiq/master
CQRS pattern
2 parents ac721c6 + 871df4f commit 0982f00

21 files changed

+1142
-0
lines changed

cqrs/README.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
---
2+
layout: pattern
3+
title: CQRS
4+
folder: cqrs
5+
permalink: /patterns/cqrs/
6+
pumlid: 7SPR4a0m3030gt00pR_RH6I8QQFouFgC_TfHb6gkd5Q7FQBx363ub4rYpoMTZKuDrYXqDX37HIuuyCPfPPTDfuuHREhGqBy0NUR0GNzAMYizMtq1
7+
categories: Architectural
8+
tags:
9+
- Java
10+
- Difficulty-Intermediate
11+
---
12+
13+
## Intent
14+
CQRS Command Query Responsibility Segregation - Separate the query side from the command side.
15+
16+
![alt text](./etc/cqrs.png "CQRS")
17+
18+
## Applicability
19+
Use the CQRS pattern when
20+
21+
* you want to scale the queries and commands independently.
22+
* you want to use different data models for queries and commands. Useful when dealing with complex domains.
23+
* you want to use architectures like event sourcing or task based UI.
24+
25+
## Credits
26+
27+
* [Greg Young - CQRS, Task Based UIs, Event Sourcing agh!](http://codebetter.com/gregyoung/2010/02/16/cqrs-task-based-uis-event-sourcing-agh/)
28+
* [Martin Fowler - CQRS](https://martinfowler.com/bliki/CQRS.html)
29+
* [Oliver Wolf - CQRS for Great Good](https://www.youtube.com/watch?v=Ge53swja9Dw)

cqrs/etc/cqrs.png

103 KB
Loading

cqrs/etc/cqrs.ucls

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<class-diagram version="1.2.0" icons="true" always-add-relationships="false" generalizations="true" realizations="true"
3+
associations="true" dependencies="false" nesting-relationships="true" router="FAN">
4+
<interface id="1" language="java" name="com.iluwatar.cqrs.commandes.ICommandService" project="cqrs"
5+
file="/cqrs/src/main/java/com/iluwatar/cqrs/commandes/ICommandService.java" binary="false" corner="BOTTOM_RIGHT">
6+
<position height="-1" width="-1" x="291" y="-49"/>
7+
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
8+
sort-features="false" accessors="true" visibility="true">
9+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
10+
<operations public="true" package="true" protected="true" private="true" static="true"/>
11+
</display>
12+
</interface>
13+
<class id="2" language="java" name="com.iluwatar.cqrs.commandes.CommandServiceImpl" project="cqrs"
14+
file="/cqrs/src/main/java/com/iluwatar/cqrs/commandes/CommandServiceImpl.java" binary="false" corner="BOTTOM_RIGHT">
15+
<position height="263" width="256" x="170" y="87"/>
16+
<display autosize="false" stereotype="true" package="true" initial-value="false" signature="true"
17+
sort-features="false" accessors="true" visibility="true">
18+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
19+
<operations public="true" package="true" protected="true" private="true" static="true"/>
20+
</display>
21+
</class>
22+
<interface id="3" language="java" name="com.iluwatar.cqrs.queries.IQueryService" project="cqrs"
23+
file="/cqrs/src/main/java/com/iluwatar/cqrs/queries/IQueryService.java" binary="false" corner="BOTTOM_RIGHT">
24+
<position height="182" width="248" x="176" y="428"/>
25+
<display autosize="false" stereotype="true" package="true" initial-value="false" signature="true"
26+
sort-features="false" accessors="true" visibility="true">
27+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
28+
<operations public="true" package="true" protected="true" private="true" static="true"/>
29+
</display>
30+
</interface>
31+
<class id="4" language="java" name="com.iluwatar.cqrs.queries.QueryServiceImpl" project="cqrs"
32+
file="/cqrs/src/main/java/com/iluwatar/cqrs/queries/QueryServiceImpl.java" binary="false" corner="BOTTOM_RIGHT">
33+
<position height="258" width="253" x="169" y="665"/>
34+
<display autosize="false" stereotype="true" package="true" initial-value="false" signature="true"
35+
sort-features="false" accessors="true" visibility="true">
36+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
37+
<operations public="true" package="true" protected="true" private="true" static="true"/>
38+
</display>
39+
</class>
40+
<class id="5" language="java" name="com.iluwatar.cqrs.domain.model.Book" project="cqrs"
41+
file="/cqrs/src/main/java/com/iluwatar/cqrs/domain/model/Book.java" binary="false" corner="BOTTOM_RIGHT">
42+
<position height="326" width="158" x="778" y="-93"/>
43+
<display autosize="false" stereotype="true" package="true" initial-value="false" signature="true"
44+
sort-features="false" accessors="true" visibility="true">
45+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
46+
<operations public="true" package="true" protected="true" private="true" static="true"/>
47+
</display>
48+
</class>
49+
<class id="6" language="java" name="com.iluwatar.cqrs.dto.Book" project="cqrs"
50+
file="/cqrs/src/main/java/com/iluwatar/cqrs/dto/Book.java" binary="false" corner="BOTTOM_RIGHT">
51+
<position height="219" width="150" x="541" y="607"/>
52+
<display autosize="false" stereotype="true" package="true" initial-value="false" signature="true"
53+
sort-features="false" accessors="true" visibility="true">
54+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
55+
<operations public="true" package="true" protected="true" private="true" static="true"/>
56+
</display>
57+
</class>
58+
<class id="7" language="java" name="com.iluwatar.cqrs.domain.model.Author" project="cqrs"
59+
file="/cqrs/src/main/java/com/iluwatar/cqrs/domain/model/Author.java" binary="false" corner="BOTTOM_RIGHT">
60+
<position height="-1" width="-1" x="608" y="70"/>
61+
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
62+
sort-features="false" accessors="true" visibility="true">
63+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
64+
<operations public="true" package="true" protected="true" private="true" static="true"/>
65+
</display>
66+
</class>
67+
<class id="8" language="java" name="com.iluwatar.cqrs.dto.Author" project="cqrs"
68+
file="/cqrs/src/main/java/com/iluwatar/cqrs/dto/Author.java" binary="false" corner="BOTTOM_RIGHT">
69+
<position height="-1" width="-1" x="834" y="719"/>
70+
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
71+
sort-features="false" accessors="true" visibility="true">
72+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
73+
<operations public="true" package="true" protected="true" private="true" static="true"/>
74+
</display>
75+
</class>
76+
<class id="9" language="java" name="com.iluwatar.cqrs.util.HibernateUtil" project="cqrs"
77+
file="/cqrs/src/main/java/com/iluwatar/cqrs/util/HibernateUtil.java" binary="false" corner="BOTTOM_RIGHT">
78+
<position height="-1" width="-1" x="662" y="412"/>
79+
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
80+
sort-features="false" accessors="true" visibility="true">
81+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
82+
<operations public="true" package="true" protected="true" private="true" static="true"/>
83+
</display>
84+
</class>
85+
<dependency id="10">
86+
<end type="SOURCE" refId="4"/>
87+
<end type="TARGET" refId="9"/>
88+
</dependency>
89+
<dependency id="11">
90+
<end type="SOURCE" refId="2"/>
91+
<end type="TARGET" refId="9"/>
92+
</dependency>
93+
<realization id="12">
94+
<end type="SOURCE" refId="4"/>
95+
<end type="TARGET" refId="3"/>
96+
</realization>
97+
<association id="13">
98+
<end type="SOURCE" refId="5" navigable="false">
99+
<attribute id="14" name="author"/>
100+
<multiplicity id="15" minimum="0" maximum="1"/>
101+
</end>
102+
<end type="TARGET" refId="7" navigable="true"/>
103+
<display labels="true" multiplicity="true"/>
104+
</association>
105+
<realization id="16">
106+
<end type="SOURCE" refId="2"/>
107+
<end type="TARGET" refId="1"/>
108+
</realization>
109+
<classifier-display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
110+
sort-features="false" accessors="true" visibility="true">
111+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
112+
<operations public="true" package="true" protected="true" private="true" static="true"/>
113+
</classifier-display>
114+
<association-display labels="true" multiplicity="true"/>
115+
</class-diagram>

cqrs/etc/cqrs.urm.puml

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
@startuml
2+
package com.iluwatar.cqrs.util {
3+
class HibernateUtil {
4+
- LOGGER : Logger {static}
5+
- SESSIONFACTORY : SessionFactory {static}
6+
+ HibernateUtil()
7+
- buildSessionFactory() : SessionFactory {static}
8+
+ getSessionFactory() : SessionFactory {static}
9+
}
10+
}
11+
package com.iluwatar.cqrs.app {
12+
class App {
13+
+ App()
14+
+ main(args : String[]) {static}
15+
}
16+
}
17+
package com.iluwatar.cqrs.dto {
18+
class Author {
19+
- email : String
20+
- name : String
21+
- username : String
22+
+ Author()
23+
+ Author(name : String, email : String, username : String)
24+
+ equals(obj : Object) : boolean
25+
+ getEmail() : String
26+
+ getName() : String
27+
+ getUsername() : String
28+
+ hashCode() : int
29+
+ toString() : String
30+
}
31+
class Book {
32+
- price : double
33+
- title : String
34+
+ Book()
35+
+ Book(title : String, price : double)
36+
+ equals(obj : Object) : boolean
37+
+ getPrice() : double
38+
+ getTitle() : String
39+
+ hashCode() : int
40+
+ toString() : String
41+
}
42+
}
43+
package com.iluwatar.cqrs.commandes {
44+
class CommandServiceImpl {
45+
- sessionFactory : SessionFactory
46+
+ CommandServiceImpl()
47+
+ authorCreated(username : String, name : String, email : String)
48+
+ authorEmailUpdated(username : String, email : String)
49+
+ authorNameUpdated(username : String, name : String)
50+
+ authorUsernameUpdated(oldUsername : String, newUsername : String)
51+
+ bookAddedToAuthor(title : String, price : double, username : String)
52+
+ bookPriceUpdated(title : String, price : double)
53+
+ bookTitleUpdated(oldTitle : String, newTitle : String)
54+
- getAuthorByUsername(username : String) : Author
55+
- getBookByTitle(title : String) : Book
56+
}
57+
interface ICommandService {
58+
+ authorCreated(String, String, String) {abstract}
59+
+ authorEmailUpdated(String, String) {abstract}
60+
+ authorNameUpdated(String, String) {abstract}
61+
+ authorUsernameUpdated(String, String) {abstract}
62+
+ bookAddedToAuthor(String, double, String) {abstract}
63+
+ bookPriceUpdated(String, double) {abstract}
64+
+ bookTitleUpdated(String, String) {abstract}
65+
}
66+
}
67+
package com.iluwatar.cqrs.queries {
68+
interface IQueryService {
69+
+ getAuthorBooks(String) : List<Book> {abstract}
70+
+ getAuthorBooksCount(String) : BigInteger {abstract}
71+
+ getAuthorByUsername(String) : Author {abstract}
72+
+ getAuthorsCount() : BigInteger {abstract}
73+
+ getBook(String) : Book {abstract}
74+
}
75+
class QueryServiceImpl {
76+
- sessionFactory : SessionFactory
77+
+ QueryServiceImpl()
78+
+ getAuthorBooks(username : String) : List<Book>
79+
+ getAuthorBooksCount(username : String) : BigInteger
80+
+ getAuthorByUsername(username : String) : Author
81+
+ getAuthorsCount() : BigInteger
82+
+ getBook(title : String) : Book
83+
}
84+
}
85+
package com.iluwatar.cqrs.domain.model {
86+
class Author {
87+
- email : String
88+
- id : long
89+
- name : String
90+
- username : String
91+
# Author()
92+
+ Author(username : String, name : String, email : String)
93+
+ getEmail() : String
94+
+ getId() : long
95+
+ getName() : String
96+
+ getUsername() : String
97+
+ setEmail(email : String)
98+
+ setId(id : long)
99+
+ setName(name : String)
100+
+ setUsername(username : String)
101+
+ toString() : String
102+
}
103+
class Book {
104+
- author : Author
105+
- id : long
106+
- price : double
107+
- title : String
108+
# Book()
109+
+ Book(title : String, price : double, author : Author)
110+
+ getAuthor() : Author
111+
+ getId() : long
112+
+ getPrice() : double
113+
+ getTitle() : String
114+
+ setAuthor(author : Author)
115+
+ setId(id : long)
116+
+ setPrice(price : double)
117+
+ setTitle(title : String)
118+
+ toString() : String
119+
}
120+
}
121+
Book --> "-author" Author
122+
CommandServiceImpl ..|> ICommandService
123+
QueryServiceImpl ..|> IQueryService
124+
@enduml

cqrs/pom.xml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?xml version="1.0"?>
2+
<!-- The MIT License Copyright (c) 2014-2016 Ilkka Seppälä Permission is
3+
hereby granted, free of charge, to any person obtaining a copy of this software
4+
and associated documentation files (the "Software"), to deal in the Software
5+
without restriction, including without limitation the rights to use, copy,
6+
modify, merge, publish, distribute, sublicense, and/or sell copies of the
7+
Software, and to permit persons to whom the Software is furnished to do so,
8+
subject to the following conditions: The above copyright notice and this
9+
permission notice shall be included in all copies or substantial portions
10+
of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
11+
KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
12+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
13+
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
14+
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
15+
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
16+
DEALINGS IN THE SOFTWARE. -->
17+
<project
18+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
19+
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
20+
<modelVersion>4.0.0</modelVersion>
21+
<parent>
22+
<groupId>com.iluwatar</groupId>
23+
<artifactId>java-design-patterns</artifactId>
24+
<version>1.17.0-SNAPSHOT</version>
25+
</parent>
26+
<artifactId>cqrs</artifactId>
27+
<dependencies>
28+
<dependency>
29+
<groupId>junit</groupId>
30+
<artifactId>junit</artifactId>
31+
<scope>test</scope>
32+
</dependency>
33+
<dependency>
34+
<groupId>com.h2database</groupId>
35+
<artifactId>h2</artifactId>
36+
</dependency>
37+
<dependency>
38+
<groupId>org.hibernate</groupId>
39+
<artifactId>hibernate-core</artifactId>
40+
</dependency>
41+
</dependencies>
42+
</project>

0 commit comments

Comments
 (0)