Hi Johanna, you may intuit some of my experience by my posts on the DDD groups ;-).
By far the hardest thing I found was applying DDD, identifying bounded contexts etc. However, from a technical point of view the thing that most stood out to me was the power of recording the decision, and effect of every single decision as an event. All mutation is captured in the event log. My ‘aggregate roots’ tend to be a namespace with a multi-method of ‘react-to’ which takes in a command and emits a bunch of events. Those events tend to be trivially mapped to state transitions of the aggregate root. Hydrating the aggregate root then becomes (let [events (event-store/load-for aggregate-id) ar (apply merge events)…]). The strict separation of domain logic/model from the views (and supporting infrastructure) is a significant win; every screen has a server side view with a server side de-normalised store (yeah, OK, a table ;-)). In our domain there are a bunch of different ‘modules’ (I won’t call them BCs!). However, some of our views map across those modules. Imagine I am looking at my current order, I also want to see when it is dispatched from the warehouse or if there is a cheaper deal etc. I also found that many of our existing applications were making key business decisions at the time of querying; what is the sort order for these things, how many things are out of stock etc. It was shocking how many decisions weren’t explicitly in the code/codified in SQL (as a team we are all culpable, but this was written before I got here - ha!). Putting it succinctly, I found there are many-to-many relationships between modules and views. Modelling this in a ‘traditional’ way would have been a great big ball of mud where one piece of code was concerned with far too many things; there is a significant disconnect between the use cases and the views. >From a maintenance point of view - fantastic. ‘How did this get to be this’ is >by far the most necessary question our support teams need to answer, now the >answer is trivia - all (actually almost all) mutation is done via events - >look in the event log. If a view changes then we can simply delete the view >and replay all of the events to build the new view. The Clojure tooling needed for this is remarkably small and the conceptual fit is fantastic; immutability - check (event log); data everywhere - yep, events flow through the system; decomplecting everywhere and always - yep, aggregate roots are ignorant of everything apart from their splice of business logic, views are ignorant of everything apart from the screen they support; functional concerns - yep, aggregate roots and views are just reductions of the event log Pain points: - it is really tempting to share common views/normalise the DB. Do I really de-duplicate the patient name everywhere or have a t_patient table? - having an event store as the SOR changes everything, everywhere, for everyone. Messes with your mind - DDD is a discipline, not something you can read a book about and do. It is a specialist non-technical skill - getting it wrong can lead to more mess and heartache than the big balls of mud we are at least familiar with - not much prior art, at least not much published art. Very few general answers; ‘it depends’ is the rote answer - DDD and event sourcing and CQRS are very different (complementary but different) beasts - tackling all three caused a lot of pain because there is no familiarity anywhere - performance can suffer, it can also be significantly improved, but my intuition was worth nothing due to the change of paradigms - making decisions when querying actually provides a lot of grace - fix the bug, deploy and the problem goes away. When you have an event log and every decision is explicitly captured you lose that grace. You can add compensating events or (although frowned upon) go through and mutate your events (yeah, I said it was frowned upon). That event log can become a chain around your feet. - nobody is going to have a clue what you are talking about until you can educate them Plus points: - the words best and most accurate audit log - separation and the fine granularity of models makes parallel development and maintenance significantly simpler - view models are transient, throw them on different servers to scale - fine - exposes many many key business decisions which weren’t handled explicitly - concepts are a natural fit for the functional world - I am a better developer, engineer and domain expert because of the rigour required - very little infrastructure required to achieve this - you can view the world as a sequential set of mutations to smaller and more focused state machines - a clear separation of read and write means your write can be more expensive to make your reads more efficient (given that most systems read _far_ more than they write) - being able to restore your system to any moment in time is just fantastic. Opens the door to simulations, replaying history, diagnostics etc. - it tickles your ‘geek’ spot (you know, the one tickled by using Linux instead of Windows, or tiling instead of floating, or being able to use grep, awk and sed together with regular expressions without having to open a book or google) I haven’t had much experience with Datomic, but I think the event log and Datomic both treat time as an explicit concern and neither are simply plugin replacements for ‘a database’. That’s probably enough; I would love to do this properly in a blog post/github demo project but I just don’t have the time :(, but I’m happy to respond to questions/upgrades/advice etc. Thanks, Colin > On 15 Jul 2015, at 22:14, Johanna Belanger <johanna.belan...@gmail.com> wrote: > > I am always eager to hear anything and everything about your experience with > this. Especially downsides. =) > > I haven't done ES yet. My hydration code is definitely not that lovely. What > do you think about ES vs Datomic? (Probably not the right thread for that > question, huh?) > > On Sunday, July 12, 2015 at 8:20:54 AM UTC-7, Colin Yates wrote: > My latest project uses a CQRS and event sourcing design and the power it > gives, coupled with Clojure is just fantastic. Hydrating an object becomes > (merge {} (event-store/load ar-id)) - just fantastic. > > I too find a lot of sympathy between CQRS, event sourcing, FRP and Clojure > which I keep meaning to blog about, but my todo list is a mile long. Still, > highly recommend that architecture. Lots of downsides; everything is a trade > off, but conceptually, yeah, it gets a lot right. > >> On 12 Jul 2015, at 05:34, Matt Bailey <ambit...@ <>gmail.com >> <http://gmail.com/>> wrote: >> >> Johanna, >> >> I noticed you mentioned CQRS. In my work, we use CQRS heavily, specifically >> the Axon framework for Java (utilizing Spring and Hibernate). I got into >> Clojure through watching Rich Hickey's talks and figured that any language >> that he wrote had to be good. >> >> It's remarkable to me how cleanly the concepts applied in CQRS map to >> concepts in Clojure. The funny thing is that CQRS would never be necessary >> if it wasn't for languages like C# and Java. >> >> It can be discouraging to see people's eyes glaze over when you talk about >> code as a series of transformations on the input. Many people limit their >> understanding of code to a very procedural style with ifs, elses and "helper >> methods" that have side effects. >> >> Sorry I don't have any words of wisdom on how to evangelize Clojure, but I >> am glad to see someone else noted the parallels between CQRS and a more >> functional style of programming. >> >> Cheers! >> -Matt >> >> On Saturday, July 11, 2015 at 2:47:31 PM UTC-7, Johanna Belanger wrote: >> That's really cool, thanks! >> >> On Saturday, July 11, 2015 at 5:27:37 AM UTC-7, juvenn wrote: >> Hi Johanna, >> >> I don’t know if it'll work for your team, but I find Shaun Le Bron's >> "Interactive guide to Tetris in ClojureScript” the most succinct and >> beautiful way of showing power of Clojure and ClojureScript. >> >> https://github.com/shaunlebron/t3tr0s-slides >> <https://github.com/shaunlebron/t3tr0s-slides> >> >> Have fun! >> -- >> Juvenn Woo >> Sent with Sparrow <http://www.sparrowmailapp.com/?sig> >> >> On Saturday, 11 July, 2015 at 1:24 pm, Johanna Belanger wrote: >> >>> I ended up giving him a brief description of Clojure, with stress on its >>> ability to do heavy lifting with very little code, and sent him a link to >>> Neal Ford's talk "The Curious Clojurist" >>> <https://www.youtube.com/watch?v=bxLnpgnDApg>. We'll see what happens. >>> Thanks everyone for your advice. >>> >>> On Thursday, July 9, 2015 at 3:20:23 PM UTC-7, Johanna Belanger wrote: >>> Hi :) >>> >>> I've recently broached the subject of Clojure with another dev in my >>> organization, and his response was basically "What's Clojure"? and I'm not >>> sure how to answer that in a way that might inspire him. "It's a >>> dynamically-typed functional Lisp with persistent immutable data structures >>> that runs on the JVM" doesn't seem like it will grab his interest. =) >>> >>> I work primarily in .NET, and he does enterprise Java. I don't know him >>> well enough to know how happy he is with it. He did express interest in >>> learning .Net. >>> >>> I came to an appreciation of Clojure through >>> >>> -CQRS (the power of decomplection!) >>> -Sussman and Abelson's SICP class at MIT online (the power of homoiconicity >>> and functions!) >>> -the death of Silverlight (alternatives to Javascript in the browser?) >>> >>> By the time I found Rich Hickey's talks (eg Simple Made Easy) I was pretty >>> well primed to love Clojure. I've been using it for little personal >>> projects and prototyping for a couple of years, but I haven't put it in >>> production because no one else here knows it. >>> >>> Could anyone tell me how they got from enterprise Java to Clojure? >>> >>> Thanks very much, >>> Johanna >>> >>> >>> -- >>> You received this message because you are subscribed to the Google >>> Groups "Clojure" group. >>> To post to this group, send email to clo...@ <>googlegroups.com >>> <http://googlegroups.com/> >>> Note that posts from new members are moderated - please be patient with >>> your first post. >>> To unsubscribe from this group, send email to >>> clojure+u...@ <>googlegroups.com <http://googlegroups.com/> >>> For more options, visit this group at >>> http://groups.google.com/group/clojure?hl=en >>> <http://groups.google.com/group/clojure?hl=en> >>> --- >>> You received this message because you are subscribed to the Google Groups >>> "Clojure" group. >>> To unsubscribe from this group and stop receiving emails from it, send an >>> email to clojure+u...@ <>googlegroups.com <http://googlegroups.com/>. >>> For more options, visit https://groups.google.com/d/optout >>> <https://groups.google.com/d/optout>. >> >> >> -- >> You received this message because you are subscribed to the Google >> Groups "Clojure" group. >> To post to this group, send email to clo...@googlegroups.com <> >> Note that posts from new members are moderated - please be patient with your >> first post. >> To unsubscribe from this group, send email to >> clojure+u...@googlegroups.com <> >> For more options, visit this group at >> http://groups.google.com/group/clojure?hl=en >> <http://groups.google.com/group/clojure?hl=en> >> --- >> You received this message because you are subscribed to the Google Groups >> "Clojure" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to clojure+u...@googlegroups.com <>. >> For more options, visit https://groups.google.com/d/optout >> <https://groups.google.com/d/optout>. > > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with your > first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > <http://groups.google.com/group/clojure?hl=en> > --- > You received this message because you are subscribed to the Google Groups > "Clojure" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to clojure+unsubscr...@googlegroups.com > <mailto:clojure+unsubscr...@googlegroups.com>. > For more options, visit https://groups.google.com/d/optout > <https://groups.google.com/d/optout>. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.