diff --git a/cqrs/README.md b/cqrs/README.md index e69de29bb..d7463715c 100644 --- a/cqrs/README.md +++ b/cqrs/README.md @@ -0,0 +1,29 @@ +--- +layout: pattern +title: CQRS +folder: cqrs +permalink: /patterns/cqrs/ +pumlid: +categories: Architectural +tags: + - Java + - Difficulty-Intermediate +--- + +## Intent +CQRS Command Query Responsibility Segregation - Seperate the query side from the command side. + +![alt text](./etc/cqrs.png "CQRS") + +## Applicability +Use the CQRS pattern when + +* you want to scale the queries and commands independently. +* you want to use different data models for queries and commands. Useful when dealing with complex domains. +* you want to use architectures like event sourcing or task based UI. + +## Credits + +* [Greg Young - CQRS, Task Based UIs, Event Sourcing agh!](http://www.amazon.com/Effective-Java-Edition-Joshua-Bloch/dp/0321356683) +* [Martin Fowler - CQRS](http://codebetter.com/gregyoung/2010/02/16/cqrs-task-based-uis-event-sourcing-agh/) +* [Oliver Wolf - CQRS for Great Good](https://www.youtube.com/watch?v=Ge53swja9Dw) diff --git a/cqrs/etc/cqrs.png b/cqrs/etc/cqrs.png new file mode 100644 index 000000000..28174bc9a Binary files /dev/null and b/cqrs/etc/cqrs.png differ diff --git a/cqrs/etc/cqrs.ucls b/cqrs/etc/cqrs.ucls index ffaf57a91..6cdfebbb2 100644 --- a/cqrs/etc/cqrs.ucls +++ b/cqrs/etc/cqrs.ucls @@ -1,6 +1,111 @@ + associations="true" dependencies="false" nesting-relationships="true" router="FAN"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cqrs/etc/cqrs.urm.puml b/cqrs/etc/cqrs.urm.puml new file mode 100644 index 000000000..6dd65dd3a --- /dev/null +++ b/cqrs/etc/cqrs.urm.puml @@ -0,0 +1,124 @@ +@startuml +package com.iluwatar.cqrs.util { + class HibernateUtil { + - LOGGER : Logger {static} + - SESSIONFACTORY : SessionFactory {static} + + HibernateUtil() + - buildSessionFactory() : SessionFactory {static} + + getSessionFactory() : SessionFactory {static} + } +} +package com.iluwatar.cqrs.app { + class App { + + App() + + main(args : String[]) {static} + } +} +package com.iluwatar.cqrs.dto { + class Author { + - email : String + - name : String + - username : String + + Author() + + Author(name : String, email : String, username : String) + + equals(obj : Object) : boolean + + getEmail() : String + + getName() : String + + getUsername() : String + + hashCode() : int + + toString() : String + } + class Book { + - price : double + - title : String + + Book() + + Book(title : String, price : double) + + equals(obj : Object) : boolean + + getPrice() : double + + getTitle() : String + + hashCode() : int + + toString() : String + } +} +package com.iluwatar.cqrs.commandes { + class CommandServiceImpl { + - sessionFactory : SessionFactory + + CommandServiceImpl() + + authorCreated(username : String, name : String, email : String) + + authorEmailUpdated(username : String, email : String) + + authorNameUpdated(username : String, name : String) + + authorUsernameUpdated(oldUsername : String, newUsername : String) + + bookAddedToAuthor(title : String, price : double, username : String) + + bookPriceUpdated(title : String, price : double) + + bookTitleUpdated(oldTitle : String, newTitle : String) + - getAuthorByUsername(username : String) : Author + - getBookByTitle(title : String) : Book + } + interface ICommandService { + + authorCreated(String, String, String) {abstract} + + authorEmailUpdated(String, String) {abstract} + + authorNameUpdated(String, String) {abstract} + + authorUsernameUpdated(String, String) {abstract} + + bookAddedToAuthor(String, double, String) {abstract} + + bookPriceUpdated(String, double) {abstract} + + bookTitleUpdated(String, String) {abstract} + } +} +package com.iluwatar.cqrs.queries { + interface IQueryService { + + getAuthorBooks(String) : List {abstract} + + getAuthorBooksCount(String) : BigInteger {abstract} + + getAuthorByUsername(String) : Author {abstract} + + getAuthorsCount() : BigInteger {abstract} + + getBook(String) : Book {abstract} + } + class QueryServiceImpl { + - sessionFactory : SessionFactory + + QueryServiceImpl() + + getAuthorBooks(username : String) : List + + getAuthorBooksCount(username : String) : BigInteger + + getAuthorByUsername(username : String) : Author + + getAuthorsCount() : BigInteger + + getBook(title : String) : Book + } +} +package com.iluwatar.cqrs.domain.model { + class Author { + - email : String + - id : long + - name : String + - username : String + # Author() + + Author(username : String, name : String, email : String) + + getEmail() : String + + getId() : long + + getName() : String + + getUsername() : String + + setEmail(email : String) + + setId(id : long) + + setName(name : String) + + setUsername(username : String) + + toString() : String + } + class Book { + - author : Author + - id : long + - price : double + - title : String + # Book() + + Book(title : String, price : double, author : Author) + + getAuthor() : Author + + getId() : long + + getPrice() : double + + getTitle() : String + + setAuthor(author : Author) + + setId(id : long) + + setPrice(price : double) + + setTitle(title : String) + + toString() : String + } +} +Book --> "-author" Author +CommandServiceImpl ..|> ICommandService +QueryServiceImpl ..|> IQueryService +@enduml \ No newline at end of file