<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1078812373343649133</id><updated>2011-07-28T12:56:08.006+02:00</updated><category term='reactive programming'/><category term='reactive extensions'/><category term='cqrs'/><category term='scala'/><category term='ddd'/><category term='architecture'/><category term='java'/><category term='software'/><category term='enterprise'/><category term='rx'/><title type='text'>Erik Rozendaal</title><subtitle type='html'>Enterprise Software, Scalable Systems, New Technology</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://erikrozendaal.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1078812373343649133/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://erikrozendaal.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Erik</name><uri>http://www.blogger.com/profile/15605260836165216544</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_eKenFQT8ss0/SyaTvTF0mqI/AAAAAAAAAAM/-AvY_uYstA8/S220/Erik.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>3</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1078812373343649133.post-108177025337248199</id><published>2010-10-19T18:47:00.012+02:00</published><updated>2010-10-19T20:59:22.965+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='rx'/><category scheme='http://www.blogger.com/atom/ns#' term='reactive extensions'/><category scheme='http://www.blogger.com/atom/ns#' term='cqrs'/><category scheme='http://www.blogger.com/atom/ns#' term='reactive programming'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Event Sourcing and State Derivation</title><content type='html'>&lt;p&gt;One of the most interesting aspects of the &lt;a href="http://cqrs.wordpress.com/"&gt;CQRS&lt;/a&gt; architecture is the ability to use event sourcing within your business applications. Representing &lt;span style="font-style:italic;"&gt;all&lt;/span&gt; state changes as domain events has various benefits, not in the least being able to look back upon historical data to derive new information.&lt;/p&gt;

&lt;p&gt;However, although historical information is nice, every system must also know its current state. Accessing the current state in traditional applications is just a database lookup. Can we do this in an event-based systems without adding a lot of complexity?&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;p&gt;In my &lt;a href="http://github.com/erikrozendaal/cqrs-lottery"&gt;Java CQRS example application&lt;/a&gt; I used the following pattern:&lt;/p&gt;

&lt;pre  style="font-family:arial;font-size:12px;border:1px dashed #CCCCCC;width:99%;height:auto;overflow:auto;background:#f0f0f0;;background-image:URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif);padding:0px;color:#000000;text-align:left;line-height:20px;"&gt;&lt;code style="color:#000000;word-wrap:normal;"&gt; public class Lottery {  
   private final Set&amp;lt;LotteryTicket&amp;gt; tickets = new HashSet&amp;lt;LotteryTicket&amp;gt;();  
   private double ticketPrice;  
   private double prizeAmount;  
   private void onLotteryCreatedEvent(LotteryCreatedEvent event) {  
     this.ticketPrice = event.getTicketPrice();  
     this.prizeAmount = event.getPrizeAmount();  
   }  
   private void onTicketPurchasedEvent(LotteryTicketPurchasedEvent event) {  
     tickets.add(new LotteryTicket(aggregate, event.getTicketNumber(), event.getCustomerId().getId()));  
   }  
 }  
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So for each type of event a method is added that updates the current state. Some framework magic (involving reflection and other dark arts) take care of taking the event stream and invoking the right method on the Lottery instance. This approach works quite well for simple cases, but the event handling code seems hard to reuse in other contexts, especially when multiple different events update the same state (not an issue in this example). Something like the &lt;a href="http://stackoverflow.com/questions/2273796/cqrs-the-query-side"&gt;one table per view&lt;/a&gt; pattern could become quite unwieldy this way.&lt;/p&gt;

&lt;p&gt;Another problem is that this approach was only used by the core domain. The reporting side implements similar logic using plain old JDBC, so the UI can easily show the current state of the system to the user.&lt;/p&gt;

&lt;h2&gt;Reactive Programming&lt;/h2&gt;

&lt;p&gt;Fortunately, some interesting new frameworks have started to come out that explicitely deal with event based applications. One of these is the &lt;a href="http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx"&gt;Reactive Extensions (RX)&lt;/a&gt; framework from Microsoft. Note that I've not been the &lt;a href="http://abdullin.com/journal/2010/9/26/theory-of-cqrs-command-handlers-sagas-ars-and-event-subscrip.html"&gt;only one&lt;/a&gt; to see that RX could be beneficial to CQRS applications.&lt;/p&gt;

&lt;p&gt;Since I'm used to the Java VM and I also want to learn more about &lt;a href="http://www.scala-lang.org/"&gt;Scala&lt;/a&gt; and RX I took some of the concepts of RX and reimplemented these in Scala over the course of a weekend, mainly to find out how reactive programming can help when dealing with event-driven systems. In Scala the example becomes:&lt;/p&gt;

&lt;pre  style="font-family:arial;font-size:12px;border:1px dashed #CCCCCC;width:99%;height:auto;overflow:auto;background:#f0f0f0;;background-image:URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif);padding:0px;color:#000000;text-align:left;line-height:20px;"&gt;&lt;code style="color:#000000;word-wrap:normal;"&gt; class Lottery extends Subject[LotteryEvent] {  
   val prizeAmount = collect { case event: LotteryCreated =&amp;gt; event.prizeAmount }.first  
   val ticketPrize = collect { case event: LotteryCreated =&amp;gt; event.ticketPrize }.first  
   val tickets = collect { case event: TicketPurchased =&amp;gt; new LotteryTicket(this, event.customerId, event.ticketNumber) }  
 }  
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Here Lottery is a &lt;code&gt;Subject[LotteryEvent]&lt;/code&gt;, meaning that it can observe a stream of &lt;code&gt;LotteryEvent&lt;/code&gt;s and then republish these to other subscribers. To determine the Lottery's current &lt;code&gt;prizeAmount&lt;/code&gt;, the &lt;code&gt;&lt;a href="http://daily-scala.blogspot.com/2010/04/filter-with-flatmap-or-collect.html"&gt;collect&lt;/a&gt;&lt;/code&gt; method is used to subscribe to &lt;code&gt;this&lt;/code&gt; Lottery instance and filter on &lt;code&gt;LotteryCreated&lt;/code&gt; events. The first such event determines the &lt;code&gt;prizeAmount&lt;/code&gt;. The &lt;code&gt;ticketPrize&lt;/code&gt; is similarly defined.&lt;/p&gt;

&lt;p&gt;The Lottery's &lt;code&gt;tickets&lt;/code&gt; contains the information from all the &lt;code&gt;TicketPurchased&lt;/code&gt; events.&lt;/p&gt;

&lt;p&gt;Although the amount of code doesn't differ much, the definitions of the reactive versions can easily be reused in other contexts (with a little refactoring) and doesn't require any reflection. Furthermore, the reactive framework contains many more combinators that allow you to handle multiple event streams, corrolate events, etc.&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;The reactive version may not be a clear win, but it looks interesting enough to investigate further. Especially interesting will be extending this to more complex scenarios as well as persisting these derived states to a database for quick querying.&lt;/p&gt;

&lt;p&gt;And finally, a word of caution: trivial examples like this can be very misleading.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1078812373343649133-108177025337248199?l=erikrozendaal.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erikrozendaal.blogspot.com/feeds/108177025337248199/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://erikrozendaal.blogspot.com/2010/10/event-sourcing-and-state-derivation.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1078812373343649133/posts/default/108177025337248199'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1078812373343649133/posts/default/108177025337248199'/><link rel='alternate' type='text/html' href='http://erikrozendaal.blogspot.com/2010/10/event-sourcing-and-state-derivation.html' title='Event Sourcing and State Derivation'/><author><name>Erik</name><uri>http://www.blogger.com/profile/15605260836165216544</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_eKenFQT8ss0/SyaTvTF0mqI/AAAAAAAAAAM/-AvY_uYstA8/S220/Erik.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1078812373343649133.post-3129932797253080502</id><published>2010-04-24T12:37:00.011+02:00</published><updated>2010-04-25T12:10:50.385+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='enterprise'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><category scheme='http://www.blogger.com/atom/ns#' term='ddd'/><category scheme='http://www.blogger.com/atom/ns#' term='architecture'/><category scheme='http://www.blogger.com/atom/ns#' term='cqrs'/><title type='text'>CQRS presentation for the Dutch DDD User Group is now available</title><content type='html'>&lt;p&gt;Monday, March 1st 2010 I gave a presentation on Command-Query Responsibility Segregation (CQRS) at the &lt;a href="http://www.dddnl.org/"&gt;Dutch DDD User Group&lt;/a&gt;. There were about two or three times more people there compared to the previous meetup, probably due to the presence of &lt;a href="http://codebetter.com/blogs/gregyoung/"&gt;Greg Young&lt;/a&gt;, who provided many useful insights during the discussions.&lt;/p&gt;

&lt;p&gt;The main part was recorded and is now available on YouTube. The &lt;a href="http://dl.dropbox.com/u/3055498/Presentations/CQRS%20presentation%20-%20DDDnl.pdf"&gt;slides are also available&lt;/a&gt;. For ease of viewing (and to work around YouTube's 10 minute limit) the presentation has been split up into the following parts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="http://www.youtube.com/watch?v=lmv5q9cMRZs"&gt;Introdution and background&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.youtube.com/watch?v=leP-kXMs5Ow"&gt;From three tier to CQRS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.youtube.com/watch?v=9rPSNY97gMs"&gt;Events&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.youtube.com/watch?v=tO5mMGPZrsM"&gt;Event sourcing and reporting&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.youtube.com/watch?v=2XH4aczYXg4"&gt;Domain versus reporting logic&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.youtube.com/watch?v=8GSNR8Wa_zM"&gt;Encapsulated domain model&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.youtube.com/watch?v=FUxHGHKM0qA"&gt;(A)synchronous&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.youtube.com/watch?v=B8KsdhZX_Jc"&gt;Event sourcing versus object-relational mapping&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.youtube.com/watch?v=tADHqLNZtS4"&gt;Event sourcing versus object-relational mapping, auditing, and history&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.youtube.com/watch?v=haCjiJrwQOI"&gt;Command and event design&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.youtube.com/watch?v=kJvdkW0Nn4I"&gt;System integration, performance, and scalability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.youtube.com/watch?v=otcbXnE0Rj4"&gt;Testability, storing commands, and production support&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1078812373343649133-3129932797253080502?l=erikrozendaal.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erikrozendaal.blogspot.com/feeds/3129932797253080502/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://erikrozendaal.blogspot.com/2010/04/cqrs-presentation-for-dutch-ddd-user.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1078812373343649133/posts/default/3129932797253080502'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1078812373343649133/posts/default/3129932797253080502'/><link rel='alternate' type='text/html' href='http://erikrozendaal.blogspot.com/2010/04/cqrs-presentation-for-dutch-ddd-user.html' title='CQRS presentation for the Dutch DDD User Group is now available'/><author><name>Erik</name><uri>http://www.blogger.com/profile/15605260836165216544</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_eKenFQT8ss0/SyaTvTF0mqI/AAAAAAAAAAM/-AvY_uYstA8/S220/Erik.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1078812373343649133.post-3041144657315058711</id><published>2009-12-14T20:37:00.015+01:00</published><updated>2009-12-14T22:22:25.903+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='enterprise'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><category scheme='http://www.blogger.com/atom/ns#' term='ddd'/><category scheme='http://www.blogger.com/atom/ns#' term='architecture'/><category scheme='http://www.blogger.com/atom/ns#' term='cqrs'/><title type='text'>CQRS: The Domain - Design Options</title><content type='html'>&lt;p&gt;When using the &lt;a href="http://www.udidahan.com/2009/12/09/clarified-cqrs/"&gt;Command-Query Responsibility Segregation&lt;/a&gt; architecture the domain is solely responsible for executing &lt;em&gt;update&lt;/em&gt; behavior.&lt;/p&gt;

&lt;p&gt;Removing the query responsibility from your domain code enables new ways of designing and implementing the domain. The only additional requirement is that your domain must raise &lt;em&gt;domain events&lt;/em&gt; so that the query database (and other interested parties) can be kept up-to-date.&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;h2&gt;Object-Relational Mapping&lt;/h2&gt;

&lt;p&gt;Just as with a traditional three-tier architecture the domain can be persisted using an ORM tool like (n)Hibernate, JPA, etc. Since the domain no longer needs to support query operations the relationships and mappings are likely to be simpler. This will reduce the impact of the ORM tool on your domain, but won't eliminate it entirely.&lt;/p&gt;

&lt;p&gt;Domain events must also be raised. This is most easily done with some simple infrastructure and accessed simply through a static method: &lt;tt&gt;DomainEvents.raise(event)&lt;/tt&gt;. This is the approach used by Udi Dahan and is explained by his &lt;a href="http://www.udidahan.com/2009/06/14/domain-events-salvation/"&gt;Domain Events - Salvation&lt;/a&gt; article.&lt;/p&gt;

&lt;p&gt;This approach has the advantage that you can reuse your knowledge of an ORM managed domain model and may also be useful when migrating from a three-tier architecture to a CQRS architecture.&lt;/p&gt;

&lt;p&gt;The main disadvantage of this approach is that there is no guarantee that the state changes persisted by the ORM match the state changes represented by your domain events. Depending on your needs this may or may not be a problem.&lt;/p&gt;

&lt;h2&gt;Event Sourcing&lt;/h2&gt;

&lt;p&gt;Another approach is to only persist the events, not the actual domain objects. Since all state changes are represented by events, the state of your domain can be restored by reloading and replaying all applicable events. This is the approach advocated by &lt;a href="http://codebetter.com/blogs/gregyoung/"&gt;Greg Young&lt;/a&gt; and combines Domain-Driven Design with &lt;a href="http://martinfowler.com/eaaDev/EventSourcing.html"&gt;Event Sourcing&lt;/a&gt;. See &lt;a href="http://blog.xebia.com/2009/12/05/cqrs-designing-the-event-store/"&gt;my blog&lt;/a&gt; on the design of the event store for some implementation considerations and there is also an &lt;a href="http://github.com/erikrozendaal/cqrs-lottery"&gt;example application&lt;/a&gt; using this approach.&lt;/p&gt;

&lt;p&gt;With this approach, your Aggregates become event sources and consistency boundaries that can be loaded and stored independently.&lt;/p&gt;

&lt;p&gt;Advantages include a domain model free of any ORM mapping and a fully consistent audit log. Events are also guaranteed to be consistent with your domain model, since your domain is loaded using the same events that are send out to the query model.&lt;/p&gt;

&lt;p&gt;A disadvantage is that relationships between aggregates can be somewhat harder to manage than with a traditional ORM mapped domain model.&lt;/p&gt;

&lt;h2&gt;Other Options&lt;/h2&gt;

&lt;p&gt;When using Event Sourcing the persistence concerns are almost completely taken out of the domain code and moved into infrastructure. This opens up the possibility of using a completely different paradigm whe implementing the domain. One example would be the use of a functional programming language to implement your domain logic. &lt;/p&gt;

&lt;p&gt;In this case each command can be represented as a function: &lt;tt&gt;f :: [Event] -&gt; [Event]&lt;/tt&gt;. The input to the function would be the historical events already persisted and the output would be the events representing the results of executing the command. The infrastructure takes care of persisting and publishing the events, leaving the domain functions side-effect free.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1078812373343649133-3041144657315058711?l=erikrozendaal.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erikrozendaal.blogspot.com/feeds/3041144657315058711/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://erikrozendaal.blogspot.com/2009/12/cqrs-domain-design-options.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1078812373343649133/posts/default/3041144657315058711'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1078812373343649133/posts/default/3041144657315058711'/><link rel='alternate' type='text/html' href='http://erikrozendaal.blogspot.com/2009/12/cqrs-domain-design-options.html' title='CQRS: The Domain - Design Options'/><author><name>Erik</name><uri>http://www.blogger.com/profile/15605260836165216544</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_eKenFQT8ss0/SyaTvTF0mqI/AAAAAAAAAAM/-AvY_uYstA8/S220/Erik.jpg'/></author><thr:total>0</thr:total></entry></feed>
