On Sun, Jan 29, 2012 at 2:58 PM, Philip Jander <jan...@janso.de> wrote: > There seems to be an increasing amount of topic added to "cqrs". > So far, my personal definition (based IIRC on one of Greg's conference > talks) was "two models where previously was only one", one optimized for > transaction and one for read/query access, where the second model is a > deterministic function of the first. > You can do that with PHP, no problem :)
I didn't mean to say that you couldn't do CQRS with PHP, but rather if the average PHP app should be considered CQRS, because the reads are separate from the writes?
Well, I think there's a distinction about a particular deployment of an architecture and whether or not it can't be deployed distributed.
Any CQRS implementation where the read and write databases use the same /type/ of data can obviously be on one machine that shares a database instance. I wouldn't necessarily say this isn't CQRS; but, if that's you intended deployment, what benefits to you hope to gain from CQRS?
CQRS gives you huge decoupling benefits. For example if you separate reads from writes, one shouldn't influence the other. (typical reporting example is someone does a huge report and because the write database is somewhere else, the application isn't impacted). If the read/write databases are in the same DB instance, that influence gain is lost.
On Sat, Jan 28, 2012 at 3:15 PM, sudarshan <sudarsha...@gmail.com> wrote: > I am not sure about the terminology here, the blog post I showed above > mentions it as cqrs, maybe its something more like cqs ....
> I think just separating out the read from writes itself is a good > first step ...especially for simpler projects which do not run in a > distributed environment ...
> So according to you cqrs implies having separate physical data > stores ?
> On Jan 26, 10:29 pm, Peter Ritchie <pe...@peterRitchie.com> wrote: > > So, if you're not segregating your read and your write database, why do > you > > think you're doing CQRS? Is it just the denormalization?
> > If we assume that one possible deployment of CQRS is that the read and > the > > write database are not segregated; what benefits to you see coming from > > this?
> > Let's assume that the benefits have to be over and above what Command > Query > > Separation principle would give you...
> > > The model where he talks about using views to project a denormalised > > > view of your database.
> > > I think its the 4th daigram in the post ..
> > > I am presently not even working in a distributed environment ... and i > > > have been wanting to know the communities view in using such a > > > pattern .... Especially in domains which do not need massive scaling > > > but have a certain degree of inherent complexity/behavior ....
> > > Thanks
> > > On Jan 26, 9:05 pm, Peter Ritchie <pe...@peterRitchie.com> wrote: > > > > MVC is typically a web-based pattern (at least recently). CQRS isn't > > > > limited to web-based front-ends.
> > > > But, I would go so far to say that it would be different to DDD/CQRS > > > > because you probably wouldn't be using DDD, just CQRS.
> > > > MVC typically means the controller "mediates" between the View and > the > > > > Model. And the data access layer "is understood to be underneath or > > > > encapsulated by the model". Most descriptions of MVC don't even > mention > > > > database.
> > > > Cheers -- Peter
> > > > On Thu, Jan 26, 2012 at 10:31 AM, Tom Janssens <d4sk...@gmail.com> > > > wrote: > > > > > By CRUD I assumed the classical MVC model without a real app layer > > > > > (Controllers accessing the DB directly etc). > > > > > In my experience this is quite the opposite of the approach you use > > > with > > > > > DDD/CQRS.
"Web-based" was a poor choice of words. A pattern used primarily on the web...
MVC works very well on the web because the controller is typically responsible for handling input events (actually, if the controller isn't doing that, then it's probably not MVC)... This is great with web because you're stateless, when you get a input event you don't have a view yet; so it goes right to the controller and it's responsible for doing something with a view, if it needs to.
Client applications, on the other hand, typically the UI is the view and all input events go through the UI (and thus the view). With MVC this kinda means the View tells the controller about input and then waits for the controller to tell it to do something about that input. Still MVC, and may give you lots of benefits as a pattern; but tends to get tedious to many devs having this circular communication get anything done.
> On Jan 26, 2012, at 4:05 PM, Peter Ritchie wrote:
> MVC is typically a web-based pattern (at least recently). CQRS isn't > limited to web-based front-ends.
> But, I would go so far to say that it would be different to DDD/CQRS > because you probably wouldn't be using DDD, just CQRS.
> MVC typically means the controller "mediates" between the View and the > Model. And the data access layer "is understood to be underneath or > encapsulated by the model". Most descriptions of MVC don't even mention > database.
> Cheers -- Peter
> On Thu, Jan 26, 2012 at 10:31 AM, Tom Janssens <d4sk...@gmail.com> wrote:
>> By CRUD I assumed the classical MVC model without a real app layer >> (Controllers accessing the DB directly etc). >> In my experience this is quite the opposite of the approach you use with >> DDD/CQRS.
I think much of the benefit of CQRS lies in the business value inherent in the domain portion of the project, not necessarily the different storage implementations. Albeit, I usually have seperated read and write stores, but CQRS doesn't require that. The data store is largely an implementation detail I can distill the same data store into a write model and read model at the same time, making the benefit to be driven by the behaviour of each of those models rather than the data store underneath.
Again, actually its quite the contrary. MVC was designed to work initially in a fat client environment quite successfully (long before the web).
Original MVC implementation input was handled directly by the controller not the view as you mention, that in turn makes changes to the model and might instruct the view refresh or assume some other state. In some scenarios the view is notified directly by the model by subscribing to model events. The workflow is quite similar to CQRS.
Now, it may be the case where you used a particular fat client UI framework that implemented a variation of MVC in the way you described.
On the web, say in the last 8 years or so, as Web Apps got fatter and web app frameworks got more mature, MVC started to be a more feasible pattern to be used in Web Apps-
Initially the concept of controller I believe got diluted by auto generating view event handlers in a lot Web Frameworks including for instance ASP.NET. Which basically leads to the design you mention where the controller is optional and if one exists is then called by these handlers. But lately with advances such as REST and AJAX the controller is becoming more and more explicit in a web ui.
> "Web-based" was a poor choice of words. A pattern used primarily on the web...
> MVC works very well on the web because the controller is typically responsible for handling input events (actually, if the controller isn't doing that, then it's probably not MVC)... This is great with web because you're stateless, when you get a input event you don't have a view yet; so it goes right to the controller and it's responsible for doing something with a view, if it needs to.
> Client applications, on the other hand, typically the UI is the view and all input events go through the UI (and thus the view). With MVC this kinda means the View tells the controller about input and then waits for the controller to tell it to do something about that input. Still MVC, and may give you lots of benefits as a pattern; but tends to get tedious to many devs having this circular communication get anything done.
If you don't have separate read and write stores, what does "segregated" me to you?
I'm honestly curious about these types of deployments. I'm trying to figure out what the perceived benefits are to a deployment that isn't truly segregated. i.e. over and above CQS, what do you hope to benefit from CQRS?
Cheers -- Peter
On Mon, Jan 30, 2012 at 12:18 PM, Craig Wilson <craiggwil...@gmail.com>wrote:
> I think much of the benefit of CQRS lies in the business value inherent in > the domain portion of the project, not necessarily the different storage > implementations. Albeit, I usually have seperated read and write stores, > but CQRS doesn't require that. The data store is largely an implementation > detail I can distill the same data store into a write model and read model > at the same time, making the benefit to be driven by the behaviour of each > of those models rather than the data store underneath.
On Mon, Jan 30, 2012 at 3:40 PM, Peter Ritchie <pe...@peterritchie.com> wrote: > If you don't have separate read and write stores, what does "segregated" me > to you?
> I'm honestly curious about these types of deployments. I'm trying to figure > out what the perceived benefits are to a deployment that isn't truly > segregated. i.e. over and above CQS, what do you hope to benefit from CQRS?
> Cheers -- Peter
> On Mon, Jan 30, 2012 at 12:18 PM, Craig Wilson <craiggwil...@gmail.com> > wrote:
>> I think much of the benefit of CQRS lies in the business value inherent in >> the domain portion of the project, not necessarily the different storage >> implementations. Albeit, I usually have seperated read and write stores, >> but CQRS doesn't require that. The data store is largely an implementation >> detail I can distill the same data store into a write model and read model >> at the same time, making the benefit to be driven by the behaviour of each >> of those models rather than the data store underneath.
Oh, I agree. I always separate the stores. However, I'm just saying that it isn't a requirement and that the main benefit of CQRS (for me and my team) was the behavioral aspects of it. The optimized read and write data stores were just an extra benefit.
Agreed. But, you could say that's simply use of DTO and abiding by basic stability and layering principles. I'm not sure that's a CQRS differentiator...
Having materialized views sounds a lot like First Law of Distribution--but, we're getting back to distribution.
Does it make sense that "segregation" in CQRS means segregation via distribution?
On Mon, Jan 30, 2012 at 3:42 PM, Greg Young <gregoryyou...@gmail.com> wrote: > Separating just to not push writes through domain but to use > materialized views etc can be rather useful in many cases.
The basic architecture definitely facilitates physical separation of databases.
Speaking of the optimized reads/writes; are you taking that a step further and separating reporting out of the mix into something like BI warehouses?
Cheers -- Peter
On Mon, Jan 30, 2012 at 3:52 PM, Craig Wilson <craiggwil...@gmail.com>wrote:
> Oh, I agree. I always separate the stores. However, I'm just saying that > it isn't a requirement and that the main benefit of CQRS (for me and my > team) was the behavioral aspects of it. The optimized read and write data > stores were just an extra benefit.
We have highly normalized data store to satisfy some political pressures. The BI guys use this to build OLAP cubes and what not. Our read stores are usually in MongoDB.
@Tom:
Separate models need not necessarily mean separate data models :)
@Peter:
Even if you don't have "segregated storage", handling changes through
monadic composable handlers can reduce coupling and make adding cross
functional & infrastructural concerns easier. Having a separate direct
query interface to the data can also make querying simpler.
[I'm not saying all CQRS apps should use the same data store, but that
just because you use the same store doesn't mean you can't do CQRS]
On Jan 30, 8:40 pm, Peter Ritchie <pe...@peterritchie.com> wrote:
> If you don't have separate read and write stores, what does "segregated" me
> to you?
> I'm honestly curious about these types of deployments. I'm trying to
> figure out what the perceived benefits are to a deployment that isn't truly
> segregated. i.e. over and above CQS, what do you hope to benefit from CQRS?
> Cheers -- Peter
> On Mon, Jan 30, 2012 at 12:18 PM, Craig Wilson <craiggwil...@gmail.com>wrote:
> > I think much of the benefit of CQRS lies in the business value inherent in
> > the domain portion of the project, not necessarily the different storage
> > implementations. Albeit, I usually have seperated read and write stores,
> > but CQRS doesn't require that. The data store is largely an implementation
> > detail I can distill the same data store into a write model and read model
> > at the same time, making the benefit to be driven by the behaviour of each
> > of those models rather than the data store underneath.
On Tue, Jan 31, 2012 at 2:32 AM, ashic <ashic.mah...@gmail.com> wrote: > @Tom: > Separate models need not necessarily mean separate data models :)
> @Peter: > Even if you don't have "segregated storage", handling changes through > monadic composable handlers can reduce coupling and make adding cross > functional & infrastructural concerns easier. Having a separate direct > query interface to the data can also make querying simpler.
> [I'm not saying all CQRS apps should use the same data store, but that > just because you use the same store doesn't mean you can't do CQRS]
> On Jan 30, 8:40 pm, Peter Ritchie <pe...@peterritchie.com> wrote: >> If you don't have separate read and write stores, what does "segregated" me >> to you?
>> I'm honestly curious about these types of deployments. I'm trying to >> figure out what the perceived benefits are to a deployment that isn't truly >> segregated. i.e. over and above CQS, what do you hope to benefit from CQRS?
>> Cheers -- Peter
>> On Mon, Jan 30, 2012 at 12:18 PM, Craig Wilson <craiggwil...@gmail.com>wrote:
>> > I think much of the benefit of CQRS lies in the business value inherent in >> > the domain portion of the project, not necessarily the different storage >> > implementations. Albeit, I usually have seperated read and write stores, >> > but CQRS doesn't require that. The data store is largely an implementation >> > detail I can distill the same data store into a write model and read model >> > at the same time, making the benefit to be driven by the behaviour of each >> > of those models rather than the data store underneath.
I'm willing to concede on "segregated storage" and accept that a CQRS implementation supports segregated storage in that whether or not storage is actually segregated is a configuration detail.
I think your mention of monadic decomposition is very important. I haven't seen this explicitly stated before. I think it's very important for messages, and thus commands and events, to be as "atomic" (e.g. monadic) as they can be and still have meaning in the domain.
Simplifying things down to the smallest possible tasks offers the greatest decoupling, greatest cohesion, and the greatest flexibility in how you schedule and distribute the tasks. Where a task is something that processes a message.
On Tue, Jan 31, 2012 at 5:32 AM, ashic <ashic.mah...@gmail.com> wrote: > @Tom: > Separate models need not necessarily mean separate data models :)
> @Peter: > Even if you don't have "segregated storage", handling changes through > monadic composable handlers can reduce coupling and make adding cross > functional & infrastructural concerns easier. Having a separate direct > query interface to the data can also make querying simpler.
> [I'm not saying all CQRS apps should use the same data store, but that > just because you use the same store doesn't mean you can't do CQRS]
While decomposition is definitely a very good thing, I was referring
to composition of handlers (which are monads - single argument
methods). Something like:
var someHandler = new SomeCommandHandler().Handle;
var loggerWrappedHandler = new LoggingHandler(someHandler).Handle;
var transactionalHandler = new
TransactionalHandler(loogerWrappedHandler).Handle;
bus.Register<SomeCommand>(transactionalHandler);
In an MVC app for example, the controller can then simply take in an
IBus and dispatch commands by bus.Send(command);
Cross functional infrastructural requirements are then kept entirely
in the composition root and it becomes much easier to support OCP and
SRP. AOP, IoC etc. without any weird magic - just one composition
root. It's a benefit of using the command pattern rather than CQRS but
it is one of those selectable thngies that you get to pick and choose.
On Jan 31, 8:30 pm, Peter Ritchie <pe...@peterRitchie.com> wrote:
> I'm willing to concede on "segregated storage" and accept that a CQRS
> implementation supports segregated storage in that whether or not storage
> is actually segregated is a configuration detail.
> I think your mention of monadic decomposition is very important. I haven't
> seen this explicitly stated before. I think it's very important for
> messages, and thus commands and events, to be as "atomic" (e.g. monadic) as
> they can be and still have meaning in the domain.
> Simplifying things down to the smallest possible tasks offers the greatest
> decoupling, greatest cohesion, and the greatest flexibility in how you
> schedule and distribute the tasks. Where a task is something that
> processes a message.
> Cheers -- Peter
> On Tue, Jan 31, 2012 at 5:32 AM, ashic <ashic.mah...@gmail.com> wrote:
> > @Tom:
> > Separate models need not necessarily mean separate data models :)
> > @Peter:
> > Even if you don't have "segregated storage", handling changes through
> > monadic composable handlers can reduce coupling and make adding cross
> > functional & infrastructural concerns easier. Having a separate direct
> > query interface to the data can also make querying simpler.
> > [I'm not saying all CQRS apps should use the same data store, but that
> > just because you use the same store doesn't mean you can't do CQRS]
I think that's oversimplifies monads slightly... I could take an existing code base and simply perform introduce parameter object refactoring on all methods and have all "monadic" methods.
Introducing an application-controlled way of invoking those methods (like a bus and calling them "message handlers") and you get only trivial AOP, decoupling, and cohesion. The fact that you can now compose handlers doesn't presuppose you can realistically get all your cross-functional requirements out of your message handlers. Take a 1000 line message handler for example.
I think there's much more to a "monadic" design than just performing introduce parameter object refactoring and introducing pipelining. You also have to decompose the system to get irreducible message handlers from the aspect of the domain. Maybe "monadic" is just a bad choice of words for that concept.
Irreducible, or atomic, domain message handlers (and thus more granular SRP) introduce more cohesion and decoupling benefits that help with understanding, maintainability, parallelisability, ability to distribute work, etc. These are the benefits I see from a message-oriented architecture like CQRS.
So, in effect I'm saying that for a message-oriented architecture it's more important to apply good object-oriented design and analysis techniques. That could mean DDD, GRASP, Functional-Class Decomposition, etc...
On Wed, Feb 1, 2012 at 8:39 AM, ashic <ashic.mah...@gmail.com> wrote: > While decomposition is definitely a very good thing, I was referring > to composition of handlers (which are monads - single argument > methods). Something like:
> var someHandler = new SomeCommandHandler().Handle; > var loggerWrappedHandler = new LoggingHandler(someHandler).Handle; > var transactionalHandler = new > TransactionalHandler(loogerWrappedHandler).Handle;
> In an MVC app for example, the controller can then simply take in an > IBus and dispatch commands by bus.Send(command);
> Cross functional infrastructural requirements are then kept entirely > in the composition root and it becomes much easier to support OCP and > SRP. AOP, IoC etc. without any weird magic - just one composition > root. It's a benefit of using the command pattern rather than CQRS but > it is one of those selectable thngies that you get to pick and choose.
> On Jan 31, 8:30 pm, Peter Ritchie <pe...@peterRitchie.com> wrote: > > I'm willing to concede on "segregated storage" and accept that a CQRS > > implementation supports segregated storage in that whether or not storage > > is actually segregated is a configuration detail.
> > I think your mention of monadic decomposition is very important. I > haven't > > seen this explicitly stated before. I think it's very important for > > messages, and thus commands and events, to be as "atomic" (e.g. monadic) > as > > they can be and still have meaning in the domain.
> > Simplifying things down to the smallest possible tasks offers the > greatest > > decoupling, greatest cohesion, and the greatest flexibility in how you > > schedule and distribute the tasks. Where a task is something that > > processes a message.
> > Cheers -- Peter
> > On Tue, Jan 31, 2012 at 5:32 AM, ashic <ashic.mah...@gmail.com> wrote: > > > @Tom: > > > Separate models need not necessarily mean separate data models :)
> > > @Peter: > > > Even if you don't have "segregated storage", handling changes through > > > monadic composable handlers can reduce coupling and make adding cross > > > functional & infrastructural concerns easier. Having a separate direct > > > query interface to the data can also make querying simpler.
> > > [I'm not saying all CQRS apps should use the same data store, but that > > > just because you use the same store doesn't mean you can't do CQRS]
1000 line command handlers would suggest something quite wrong
somewhere. My point was that composing the pipeline and functional
decomposition are both benefits of commands.If the pipeline
composition becomes really complex, chances are there's some
functional decomposition to be done.
On Feb 1, 3:23 pm, Peter Ritchie <pe...@peterRitchie.com> wrote:
> I think that's oversimplifies monads slightly... I could take an existing
> code base and simply perform introduce parameter object refactoring on all
> methods and have all "monadic" methods.
> Introducing an application-controlled way of invoking those methods (like a
> bus and calling them "message handlers") and you get only trivial AOP,
> decoupling, and cohesion. The fact that you can now compose handlers
> doesn't presuppose you can realistically get all your cross-functional
> requirements out of your message handlers. Take a 1000 line message
> handler for example.
> I think there's much more to a "monadic" design than just performing
> introduce parameter object refactoring and introducing pipelining. You
> also have to decompose the system to get irreducible message handlers from
> the aspect of the domain. Maybe "monadic" is just a bad choice of words
> for that concept.
> Irreducible, or atomic, domain message handlers (and thus more granular
> SRP) introduce more cohesion and decoupling benefits that help with
> understanding, maintainability, parallelisability, ability to distribute
> work, etc. These are the benefits I see from a message-oriented
> architecture like CQRS.
> So, in effect I'm saying that for a message-oriented architecture it's more
> important to apply good object-oriented design and analysis techniques.
> That could mean DDD, GRASP, Functional-Class Decomposition, etc...
> Cheers -- Peter
> On Wed, Feb 1, 2012 at 8:39 AM, ashic <ashic.mah...@gmail.com> wrote:
> > While decomposition is definitely a very good thing, I was referring
> > to composition of handlers (which are monads - single argument
> > methods). Something like:
> > var someHandler = new SomeCommandHandler().Handle;
> > var loggerWrappedHandler = new LoggingHandler(someHandler).Handle;
> > var transactionalHandler = new
> > TransactionalHandler(loogerWrappedHandler).Handle;
> > In an MVC app for example, the controller can then simply take in an
> > IBus and dispatch commands by bus.Send(command);
> > Cross functional infrastructural requirements are then kept entirely
> > in the composition root and it becomes much easier to support OCP and
> > SRP. AOP, IoC etc. without any weird magic - just one composition
> > root. It's a benefit of using the command pattern rather than CQRS but
> > it is one of those selectable thngies that you get to pick and choose.
> > On Jan 31, 8:30 pm, Peter Ritchie <pe...@peterRitchie.com> wrote:
> > > I'm willing to concede on "segregated storage" and accept that a CQRS
> > > implementation supports segregated storage in that whether or not storage
> > > is actually segregated is a configuration detail.
> > > I think your mention of monadic decomposition is very important. I
> > haven't
> > > seen this explicitly stated before. I think it's very important for
> > > messages, and thus commands and events, to be as "atomic" (e.g. monadic)
> > as
> > > they can be and still have meaning in the domain.
> > > Simplifying things down to the smallest possible tasks offers the
> > greatest
> > > decoupling, greatest cohesion, and the greatest flexibility in how you
> > > schedule and distribute the tasks. Where a task is something that
> > > processes a message.
> > > Cheers -- Peter
> > > On Tue, Jan 31, 2012 at 5:32 AM, ashic <ashic.mah...@gmail.com> wrote:
> > > > @Tom:
> > > > Separate models need not necessarily mean separate data models :)
> > > > @Peter:
> > > > Even if you don't have "segregated storage", handling changes through
> > > > monadic composable handlers can reduce coupling and make adding cross
> > > > functional & infrastructural concerns easier. Having a separate direct
> > > > query interface to the data can also make querying simpler.
> > > > [I'm not saying all CQRS apps should use the same data store, but that
> > > > just because you use the same store doesn't mean you can't do CQRS]