mhinze / ShortBus

In-process mediator with low-friction API
MIT License
210 stars 41 forks source link

ShortBus isn't really about CQRS, it's more an application architecture thing. #15

Closed zachariahyoung closed 10 years ago

zachariahyoung commented 10 years ago

@mhinze Not sure I understand what this means. I'm sure others will have the same issues. Maybe we could include some explanation in the wiki.

Have been thinking of this as CQRS.

mhinze commented 10 years ago

Ok, long rambling answer here. Maybe you can help me make sense of all this. I am trying to describe why we use this and what I think it's good for. Probably not answering your question exactly, and I apologize for that.

Technically commands and queries are separated and so I think that is CQRS.
But really ShortBus is a mediator/aggregator and encourages working with these abstractions:

  1. An operation (commands, queries) (with a name and parameters)
  2. The result of an operation (TResult)
  3. A handler that, given an instance of an operation, produces a result
  4. The mediator, which finds the right handler for an operation, invokes it, and returns the result

ShortBus does this by using dependency injection containers, which allow us to look up handler instances by their type.

This is good for a few things.

  1. Small, focused, handler classes. We can test these guys isolated from the user interface. We can mature them at different rates of change. For example, in one app we start by using ORM, but for one handler we can change the implementation to use a stored procedure without affecting the other handlers. Furthermore, in our apps, handlers abstract a large OO subsystem from the UI. For example, consider a large search screen.

    image

    If we were to implement this procedurally, we would have a very large handler or at least a very large stored procedure. But we can use other design patterns to build this feature independent of any other handler or the user interface. In this design pattern, instead of editing the procedure whenever we want to make a change, we add a class. ShortBus encourages OCP in an application just like messaging encourages OCP in a system.

  2. Small, focused, enumerated operations. I know what my app does, and what parameters it needs to do what it does.
  3. Distinct result types. I know the language my app talks in. It has a set of schemas that the user interface layer translates into the proper format: HTML for web apps or JSON/XML for APIs or whatever. This is also nice because I can, from the UI work with a known schema before its handler has been implemented. Also this is great for UI testing.

Why is it not CQRS as colloquially understood? ShortBus doesn't do anything out of process. It has messaging semantics (queries, commands, handlers) but it doesn't put anything on the wire. A query could put a message in a queue, it could call a database, it could just do some math or something. ShortBus is about the application architecture, not the system architecture. There are also a lot of other things you would need to do to implement CQRS as its usually meant. Prebuilding models, messaging, event sourcing or whatever. That stuff is outside of the domain of ShortBus, although ShortBus is used in applications supported by systems that do use CQRS.

zachariahyoung commented 10 years ago

This really helps. The last statement helped the most. So I would add a little more detail on the mediator pattern.

mhinze commented 10 years ago

9

dvins commented 10 years ago

+1 per @zachariahyoung on the last statement regarding ShortBus has to do with application architecture and structuring logic. I found ShortBus based on @jbogard's recent series on refining ASP.NET MVC controllers on the Los Techies blog. It took a while for it all to sink in, but once it did, and after adopting it I am astounded by how much simpler the key areas of logic have become along with their interaction with the rest of the application .