Thanks so much for this really nice rundown. A few responses inline... On Thursday, July 16, 2015 at 3:23:17 AM UTC-7, Colin Yates wrote: > > Hi Johanna, you may intuit some of my experience by my posts on the DDD > groups ;-). > I've read them all. =)
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!). > Right. I've gotten a huge amount of value out of this. In my domain, only a small amount of the write side complexity is modeled in the software. The rest is in the users' heads and they don't want that automated at this time, lol. Everything after that point is called "reporting", but actually contains a ton of business logic around constructing, disseminating and acting on those "reports" and correlating the timing of those things. Making all that logic explicit has been a huge win. 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 > This is great to hear, and when you get time to do your blog post it will be a nice thing to share with the CQRS community. Build a little love for Clojure. =) 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 > Would love someday to hear any stories you can share. > - not much prior art, at least not much published art. Very few general > answers; ‘it depends’ is the rote answer > Yep - 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 > Yes yes yes. I tried that on a personal project with a deadline. It failed. =/ I was already practiced with DDD, too, but the other 2 were new. - 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. > But on the flip side of that, all consequences of bugs are explicitly recorded. - 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 > And really reduces the amount of complexity to deal with at any one time - 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) > The power! > 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’. > Me neither. My one thought on this is that with Datomic the event schema could be more flexible. The event name is just a tag on the transaction. > 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....@gmail.com > <javascript:>> 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> 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 >>>> >>>> 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 >>>> 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 >>>> --- >>>> 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. >>>> >>>> >>>> >> -- >> 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 >> --- >> 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. >> >> >> > -- > 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 <javascript:> > 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 <javascript:> > 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+u...@googlegroups.com <javascript:>. > For more options, visit 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.