75
CQRS: Crack for Architecture Addicts… -or- …An Idea Who’s Time Has Come?

CQRS:

  • Upload
    travis

  • View
    139

  • Download
    0

Embed Size (px)

DESCRIPTION

CQRS:. Crack for Architecture Addicts… -or- …An Idea Who’s Time Has Come?. Thanks for celebrating 10 years of the .NET Community with INETA. Happy Birthday!. - PowerPoint PPT Presentation

Citation preview

Page 1: CQRS:

CQRS:

Crack for Architecture Addicts…-or-

…An Idea Who’s Time Has Come?

Page 2: CQRS:

Happy Birthday!Thanks for celebrating 10 years of the .NET Community with INETA

Page 3: CQRS:

Tweet for Prizes

Follow us at @ineta. Tweet using the hashtag #INETA10 for a chance to win a prize in our daily random drawing throughout February.

Page 4: CQRS:

Send Your Photo to Win

Post your User Group photo and send us a link (at [email protected]) to be entered in the User Group weekly random drawing during February. We’ll post the link on the birthday page.

Page 5: CQRS:

Birthday Video

GrapeCity is putting together a video featuring user group leaders. See the February newsletter for details and send your video clip to be included.

http://ineta.org/newsletters/2012_02.htm

Page 6: CQRS:

Special offer from CODE MagazineINETA's birthday gift to you! A complimentary one year subscription to Code Magazine is available to all new subscribing U. S. Members. Go to www.codemag.com/subscribe/ineta10 to receive your free subscription!

Page 7: CQRS:

Thank you Platinum Sponsors

http://www.componentone.com

Page 8: CQRS:

Thank you Platinum Sponsors

http://www.esri.com

Page 9: CQRS:

Thank you Platinum Sponsors

http://www.infragistics.com

Page 10: CQRS:

Thank you Platinum Sponsors

http://www.telerik.com

Page 11: CQRS:

Thank you Gold and Silver Sponsors

http://www.grapecity.com

http://www.red-gate.com

Page 12: CQRS:

Thank you Donation Sponsors

oreilly.com

grapecity.com

typemock.com

Page 13: CQRS:

Thank you Donation Sponsors

code-magazine.com

ssware.com

winconnections.com

Page 14: CQRS:

INETA provides structured, peer-based organizational, educational, and promotional support to the growing worldwide community of Microsoft® .NET user groups.

http://ineta.org

About INETA

Page 15: CQRS:

- Community Speakers program- Virtual Groups and Speakers- Community Champions - INETA Live!- Outreach and recognition for user groups- Offers from sponsors for groups and members

http://ineta.org

INETA Programs

Page 16: CQRS:

Keep up with news on programs, training, special events and other happenings in the world of the .NET community.Visit the link on the archive page and enter your email address to be added to the mailing list.

http://ineta.org/newsletters

INETA Newsletter

Page 17: CQRS:

Anyone can register to become part of the program. Group leaders can find speakers as often as you like.

http://ineta.org/Speakers/

Community Speakers Program

Page 18: CQRS:

Learn something new with the community presentation recordings available now on INETA Live!

http://live.ineta.org/

INETA Live

Page 19: CQRS:

Tell us what you do to support the .NET Community and get recognized.

http://inetachamps.com

Community Champions

Page 20: CQRS:

Win a scholarship and paid travel to either DevConnections in Las Vegas or TechEd in Orlando with the Component Code Challenge.

http://ineta.org/CodeChallenge

Get Your Code On and Win

Page 21: CQRS:

Special Offers for INETAMembers and Groups

http://ineta.org/offers

Page 22: CQRS:

CQRS:

Crack for Architecture Addicts…-or-

…An Idea Who’s Time Has Come?

Page 23: CQRS:
Page 24: CQRS:

Do I Suck?

http://speakerrate.com/talks/9298

Page 25: CQRS:

Who am I?• …and why should you care?• Steve Bohlen• I Read Books + Write Software• vs. “Read Software + Write Books”

• Blog, Screencast, Speak, Share, Learn

Page 26: CQRS:

Nearly 20 years developing softwareLISP, Delphi, C/C++, VB, VB.NET, C#, RubySenior Engineer Springsource/VMwareCo-Founder, NYC Alt.Net User Group

http://nyalt.netCo-Organizer, NYC DDD User Group

http://dddnyc.orgContributor: various OSS projects

Nhibernate http://www.nhforge.orgNDbUnit http://www.googlecode.com/ndbunitSpring.NET http://www.springframework.net

blog: http://blog.unhandled-exceptions.come-mail: [email protected]: @sbohlen

CYND D D

Page 27: CQRS:
Page 28: CQRS:

Beta Presentation

Page 29: CQRS:

Opinions Ahead

Page 30: CQRS:
Page 31: CQRS:

Agenda• What’s wrong with Traditional Application Architecture?• What is CQRS?• Commands and Events• Persistence• Understanding Event Sourcing• Exploring a simple CQRS sample app• Exploring a comprehensive CQRS sample app (?)• Resources to Learn more• Q+A

Page 32: CQRS:

What’s wrong withTraditional Application Architecture?

Page 33: CQRS:

Traditional Architecture

Page 34: CQRS:

LAN/WAN

Traditional Architecture

Application Services

Domain Object

Domain Object

Domain Object

Domain Object

Client

Remote Services

Request DTO

Retu

rn D

TO

Comm

and ACK

Retu

rned

RDBMS

Page 35: CQRS:

Application Design Pain Points• Scalability of System is by

larger and larger RDBMS• Surprise, surprise!

• Persistence means ‘save the Current State’ of the domain model

• Query concerns are at odds with Transactional concerns• 1NF vs. 3NF

• more…

Page 36: CQRS:

Domain Modeling Pain Points• Business Rules only exist in

user’s heads• Converting Domain Objects

to DTOs (and back again!)• Domain Object Persistence• Lazy vs. Eager Fetching• Optimizing Domain for

efficient Queries• Setter/Getter Anti-Pattern• Tests are (often) brittle• more…

Page 37: CQRS:

Business Pain Points

• Must know what business questions we want to ask up front

• Optimizing for Queries and Optimzing for Transactions are tied together (and expensive)

• Evolving Requirements is hard/expensive

• more…

Page 38: CQRS:

Self-Delusion• One model can be made

to efficiently serve two (or more!) different masters

• Competing optimization needs of Queries and the Transactions can be efficiently balanced

• Getters/Setters are a necessary evil

• Persisting State is the only way to think about the problem

Page 39: CQRS:
Page 40: CQRS:
Page 41: CQRS:

What is CQRS?

Page 42: CQRS:

Command-Query SeparationCommand-Query Separation (CQS) 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.

-Bertrand Meyer, designing the Eiffel language

Page 43: CQRS:

Interface Segregation Principle

Page 44: CQRS:

Command-QueryResponsibility Segregation

• The CQS principles applied to your domain modeling and system architecture

• Enable each element of your architecture to be optimized for a single responsibility

• Decomposition for your architecture rather than just for your objects

Page 45: CQRS:

LAN/WAN

Slicing and Dicing our Architecture

Application Services

Domain Object

Domain Object

Domain Object

Domain Object

Client

Remote Services

Request DTO

Retu

rn D

TO

Comm

and ACK

Retu

rned

RDBMS

Client

Server

WriteRead

Page 46: CQRS:

LAN/WAN

Refactoring our Architecture

Application Services

Domain Object

Domain Object

Client

Remote Services

Request DTO

Retu

rn D

TO

Application Services

Comm

and ACK

Retu

rned

WriteRead

Light-Weight Query Services

RDBMS

Domain Object

Domain Object

Persistence Persistence

Remote ServicesRemote Services

Eventually

Page 47: CQRS:

C PACAP Theorem: onsistency, vailability, artition-Tolerance; pick any two!

Write

Read

Scaling our Systems

C A P

Page 48: CQRS:

About “Eventual Consistency”• Domain Experts deal in ‘stale’ data all the time

– Edit screens, Reports, Analysis, OLAP• ‘Staleness’ is often already implicitly in our systems

– Caching, Optimistic Concurrency, and more• Eventual Consistency is making that ‘staleness’ an explicit

(and acknowledged) fact in the system• Language matters: say stale and older not out-of-date or

inconsistent– Opportunity to actually discuss ‘how stale is OK?’– Often we make data stale without this discussion at all

Page 49: CQRS:

Commands and Events in CQRS

Page 50: CQRS:

Refresher: the Aggregate Root Pattern

Aggregate Boundary

Entity1

Entity2

Entity3

ValueObject1

ValueObject2

Aggregate Boundary

Entity1

Entity2

ValueObject1

Aggregate Boundary

Entity1

ValueObject1

ValueObject2

Page 51: CQRS:

The BIG Idea

Command Aggregate Root

Event

Event

PlaceOrderCommand

Order Domain Object

OrderPlacedEvent

*or* OrderNotPlacedEvent!

Page 52: CQRS:

Application Domain

The even BIGGER Idea

Command Command Handler

Aggregate Root Event

Event Handler

Event Handler

Aggregate Root

Event Event Handler

Event

Event Handler

Event Handler

Page 53: CQRS:

OutputInput

Domain Testing (conceptual)

Command Command Handler

Aggregate Root Event

Event Handler

Event Handler

Aggregate Root

Event Event Handler

Event

Event Handler

Event Handler

Page 54: CQRS:

Understanding Commands• Commands are directives to the domain to perform some

action• Commands may be declined/rejected by the domain for

various reasons• Processing a Command will result in 0:n Events raised• Commands are always in the imperative:

– PlaceOrder, not OrderPlaced– Recall: in DDD, lexical differences matter

• Commands are a component of the Ubiquitous Language we use to describe our domain

Page 55: CQRS:

Demystifying Commandspublic class PlaceOrderCommand {         

//properties public readonly Guid OrderId;public readonly string Comment;

//ctorpublic PlaceOrderCommand(Guid id, string comment){OrderId = id;Comment = comment; }

}

Page 56: CQRS:

Understanding Events• Events are the result of some action having already

happened in the Domain• Events may never be declined/rejected; they are

evidence that something already happened• Events are always in the past-tense:– OrderPlaced, not PlaceOrder– Recall: in DDD, lexical differences matter

• Events are a component of the Ubiquitous Language we use to describe our domain

Page 57: CQRS:

Demystifying Eventspublic class OrderPlacedEvent {         

//properties public readonly Guid OrderId;public readonly Guid ConfirmationId;public readonly string Comment;

//ctorpublic OrderPlacedEvent(Guid orderId, Guid confirmationId, string comment){OrderId = id;ConfirmationId = id;Comment = comment; }

}

Page 58: CQRS:

Role of Commands and Events

Page 59: CQRS:

Persistence in CQRS

Page 60: CQRS:

Compromises inPersistence Needs

• Query (read) optimization and Transaction (write) Optimization needs are in opposition– 1NF for queries, 3NF for transactions– Scalability needs (imbalanced Reads and Writes)

• Even RDBMS vendors acknowledge this– OLTP vs OLAP

• One set of optimizations shared between Read and Write will by definition be suboptimal for each

Page 61: CQRS:

Choose the Proper Persistence• Optimize the Read store for Queries• Optimize the Write store for Transactions• Let each side be designed for its single-purpose role• Don’t try to twist a single persistence store into

doing “double-duty”– It will do neither well

• RDBMS is no longer our only choice for persistence– NoSQL choices offer different pros/cons

Page 62: CQRS:

Event Sourcing in CQRS

Page 63: CQRS:

Thinking More About Events• Events are past-tense• An Audit-Log of the entire Domain for the life

of the system• A history of what happened over time– not a record of the state of the domain at a point

in time

Page 64: CQRS:

Event Sequencing vs. State

Page 65: CQRS:

Event Sequencing vs. State

Search for Product ID1

Add Product ID1

to Cart

Search for Product ID2

Add Product ID2

to Cart

Remove Product ID1

from Cart

Final State: Cart with Product ID2 in it

Page 66: CQRS:

Typical Application w Audit Log

The System

Audit Log

• Audit Log *might* be right• Have to remember to write

to it “when important”• Side-effect of the system

Page 67: CQRS:

Typical Application w Event Log

The System

Audit Log

• Audit Log *must* be right• Entries are guaranteed to be

recorded when needed• Core to the system’s function

Page 68: CQRS:

Interesting Event PossibilitiesIf Events are a record of what happened in The Domain…• We can (re)create the current state of the Domain by

“replaying” events from the log• If we want a point-in-time view of the system, we can

(re)create the Domain at that time by “replaying” events just to that point– Historical State for “free”– Bug Reproduction

Page 69: CQRS:

Event Store Concepts10

9

8

7

6

5

4

3

2

1

Repl

ay F

orw

ard

Read

to B

egin

ning

10

9

8

snap

7

6

5

4

3

2

1

Repl

ay

Read

Page 70: CQRS:

Events and Domain Persistence• Saving our Aggregate is just serializing events• Loading our Aggregate becomes:/* load the snapshot for this aggregate or if no snapshot, begin w/ empty ‘default’ */var customer = customerRepo.LoadById(customerId);

//replay the events to make its state ‘current’customer.ReplayAllEvents();

//customer ready to accept commands nowConsider: Why do we need an ORM now???

Page 71: CQRS:

Exploring a Simple CQRS Sample

Page 72: CQRS:

Exploring a Comprehensive CQRS Sample

Page 73: CQRS:

Should I do CQRS?

Absolutely Not!…or at least “Probably Not”

Page 74: CQRS:

Additional ResourcesCentral Hub for All Things CQRS

http://www.cqrsinfo.comUdi Dahan’s on CQRS (et. al.)

http://www.udidahan.com/2009/12/09/clarified-cqrs/Simple CQRS Sample Application

https://github.com/gregoryyoung/m-rComprehensive CQRS Sample Application

https://github.com/MarkNijhof/FohjinJonathan Oliver’s Post on his Event Store project

http://blog.jonathanoliver.com/2010/07/cqrs-event-store/Rinat Abdulluin on Getting Started with CQRS

http://abdullin.com/cqrs/Greg Young on Testing Using Events (video)

http://skillsmatter.com/podcast/design-architecture/talk-from-greg-young

Page 75: CQRS:

Rate Me!

http://speakerrate.com/talks/9298