Sponsored By Aspose - File Format APIs for .NET

Aspose are the market leader of .NET APIs for file business formats – natively work with DOCX, XLSX, PPT, PDF, MSG, MPP, images formats and many more!

Command pattern architecture, or “How to do it a little at a time”

In the comments of a recent post, some people pointed out some questionable practices:

  • Modifying the data access when I should be modifying the business model
  • Using a NoSQL data store when a relational one would be more appropriate for slicing and dicing data
  • Changing the business model to accommodate the UI

Will ignore the second point for now. I’ve covered part of the concern already anyway.

For the other two, it’s worth explaining the architecture that I think Google Web Toolkit encourages.

Both points mention “business model” and I’ve probably called it that on occasion as well. I’ve never liked using the term because I don’t think I’ve worked on a project that’s done any form of DDD except use repositories. My domain is usually anemic because there isn’t a lot of business logic in a CRUD app. Unless you count the many forms of GetFullName I’ve written on a customer object.

But now I’m in an app that has real business logic. “Find next available appointment”, for example. Or better yet, “find optimal appointment time” for the ominous “smart scheduling” feature. Seems like a good candidate for a rich domain model. Except that our “domain” is still all DTOs.

I’m fine with this because it works for our architecture. In a more traditional .NET web app, I would probably define a proper domain model with behaviours and such. On the front end, I’d diligently translate between it and screen-specific DTOs or JSON objects or what-have-you.

We’re using GWT. It’s *all* JSON. And it’s not even JSON we control. (We could control it but we choose not to and use the built-in GWT RPC translation.) Every single action is an AJAX call launched from a button, or a link, or a drag and drop. Nothing is screen-specific because presenting a single screen is too big a concept. Instead, we replace individual pieces of it as necessary and make individual requests for the corresponding data for those pieces.

So we’ve adopted an architecture based around what I have been calling (possibly erroneously, so you may want to look it up) the command pattern. This sounds like a grand architectural decision from a big software mucky-much but really, this architecture is nigh impossible to avoid with GWT applications. The implementation is courtesy of gwt-platform, which also handles our MVP structure as well.

Here is a 998-word picture of the process:

 

image

 

Notice there are no domain objects anywhere. That’s because it’s my diagram and I’ve specifically doctored it so that there are no domain objects.

I jest, slightly. There are no domain objects because they aren’t interesting. All the real magic happens in the “Process command” step. This is where we examine the data we’ve been given, do some stuff like save to a data store or calculate a person’s likelihood of arrest before the age of 18 or some other piece of logic befitting our “domain”.

The “data we’ve been given” is the command, which is a fancy word for a specialized DTO. For example, if we want to search for a suitable liquor store, we create a FindClient command and populate the SearchText proper—…whoops, this is Java. I mean we call the setSearchText method. The server matches, through dependency injection, the FindLiquorStore command with the FindLiquorStoreHandler and executes it.

After doing whatever magic needs to be done, we create a result, which is another specialized DTO. It has a getResults method which returns a list of LiquorStore “domain” objects.

With this architecture, the domain objects are little more than property bags. All the real work is done in handlers. To summarize the objects used in our “find liquor store” example:

FindLiquorStore Command object. Class name helps determine which handler to run. Property accessors store relevant data needed to execute the command
FindLiquorStoreHandler Handler that examines the data within the command and does whatever needs to be done with it. Also creates a result object and returns it.
FindLiquorStoreResult Contains any data that the caller might be interested in after processing the command; in this case, a list of LiquorStore objects
LiquorStore An “domain” object in the sense that it is called something that a business person might recognize

Seems a lot of infrastructure but it’s not so far removed from MVC applications where a controller action takes parameters from a query string (or form), process it, then sends a model back to the view. The difference is we don’t do it at the page level with a model that contains a bunch of lookup data as well as the one piece of info we care about (notwithstanding some interesting work in this area).

This is more in line with the types of apps I’m building more often even using MVC. That is, the page loads with very little actual information on it and each section takes care of its own data. One section might load the client data, another the alcohol consumption stats for the staff, and another the customer satisfaction charts. Each of these would entail a separate AJAX call to a controller action that would likely return a JsonResult (or even more likely, a custom Json result so that I can avoid the serialization issues inherent with the native MVC JsonResult object).

This probably doesn’t necessarily obviate the need for a full-fledged domain model complete with all the behaviours and other keywords that I have no business pretending I know anything about. You can translate between DTOs and domain objects very easily these days. But given that the sole access to the application is through commands, I’m more inclined to leave everything as DTOs and have the handlers contain all our business logic.

Kyle the Commandeered

This entry was posted in ASP.NET MVC, GWT. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://kyle.baley.org Kyle Baley

    Demetrius,

    I think what you describe is closer to what people like Udi Dahan and Greg Young have been espousing for some time. I can’t comment intelligently on the idea but I attended Udi’s course and believe it has some significant advantages in the right circumstances. For my part, although this doesn’t go as far as you suggest, it *is* how GWT encourages devs to write code. It’s not without it’s tradeoffs but all in all, it’s a very clean way to code.

  • Demetrius Middleton

    I will say though, my way of thinking makes testing harder. As if you want to truly test what happens if one entity performs an action you either need to, have a service layer or some other place where you can directly force certain things to happen in sequence, or your test themselves become “harder” because you have to acurately set the appropriate listeners / events for each individual test you perform under each context.

    However, I feel there is a better way. When testing, you really don’t need to test all the consequences of what you perform (or the consequences of raising an event). Within a test, you really don’t care what else is listening and responding to your event. You just care about raising the appropriate events from the correct handlers. If you also have tested the other handlers within that domain, and have tested that the correct entities are listening for the correct events, then you have effectively tested whether or not the correct “sequence” of events have occurred. That way, you don’t tie your tests to the full behavior of all the other entities and their responsibilites. You are adhering to the SRP and only doing your action and raising the appropriate events.

    If the correct sequence of responses to your events don’t occur in production, then your other entities need listeners added / tested so that they respond to the originating event appropriately.

  • Demetrius Middleton

    That was really long. But in short, in the real world IMHO, in the Person1.LeaveBathroom method, we don’t directly call Person2.Leave(WithMe) method.

    It’s more like:
    Person1.ImReadyToExitBathroomEvent
    Person1.ReadyToExitBathroomHandler
    -Person1.ExitBathroomCommand
    -Person1.RaiseBathroomExitedCommand
    – Person1.FindPerson2Command
    – if no FoundPerson2Event is received but Person2.Handled(ISawPerson1.RaiseBathroomExitedCommand)

    then Person2.RaiseTellPerson1LetsLeave or if Context.Person2IsOutsideAndISeeHIm
    and then Person2.Leave(GoToPerson1Outside) and so on and so forth.

    Does this make sense to anyone? Am I complicating things too much or am I way off (if so why). I’m still learning but this is what actually makes sense to me. Commands – CommandHandlers – Other entities and / or our context listening for any events that can occur within that particular context. Other entities raising events that each entity or context can listen for.

  • Demetrius Middleton

    The thing is, while commands as you describe are “close” to how we think about things I think the community / you / I / and others that are trying to find a better way are still missing something when we create solutions as you describe. When we do something in the real world we do perform a command, and something (a handler) compares what we want to do to our environment and the laws of that environment and either we are able to actually perform what we want to do or we get an error or are prevented because something else in this context does not allow the operation we intend to perform. So, our command object is now the context. Good! Then if the operation is allowed, the business logic in the operation is executed (ie. Person.BrushTeeth or do something else). Now this is where I think thing I am starting to disagree with the community. Not only do we Person.BrushTeeth, we try to lump all of the other things that *should* occur if we Person.BrushTeeth in either the Service.BrushTeeth(Person) method or the Person.BrushTeeth method or we issue a Context.PersonBrushedTeeth command that is then handled by the handler for Person.BrushTeeth and stuff all of the logic surround what should happen to other objects in that same operation. The problem is, we are directly determining what else should happen to other objects and our context within that handler or service method. This is not the real world!

    This ties all the other things that should happen and pre-determines what should happen. But, if we have a rich domain model or an anemic one with the ability to do many different things depending on whether something else occured, then if Person.BrushedTeeth Event and if AnotherPerson.IsWaitingForPersonOneToBrushTeethSoTheyCanLeaveTogether and if AnotherPerson.IsWaitingToUseTheBathroom then we then go and create one gigantic method that executes that logic. I am starting to feel that this is wrong.

    What I feel we need to start doing, is have Person.BrushTeeth or Context.HandleCommand(PersonBrushTeeth) fire an Event when Person.GoesToBrushesTeeth and Person.FinishesBrushingTeeth and all other objects and our contest that are listening for that event then go and have the handlers that respond to those events go and do something. So now, Instead of:
    LiquorStore: FindLiquorStore -> FindLiquorStoreHandler -> FindLiquorStoreResult

    I think we should have:

    Person, LiquorStore, Context:
    Person.FindLiquorStoreCommand -> Person.FindLiquorStoreHandler.FireLiquorStoreFoundEvent -> Person.LiquorStoreFoundHandler.DecideToEnterLiquorStore -> Person.RaiseEnterdLiquorStoreEvent AND Context.AlertOtherListenersThatPersonFoundLiquorStoreEvent and Context.AlertOtherListenersThatPersonEnteredLiquorStoreEvent

    Then all other entities within that context (where context could be the entity framework’s dbcontext, or a session in HHib, or the service layer which is basically a context); all other enties listening for any events that they care about handle those events and do what they do and / or fire other events … and the cycle continues.

    This allows REAL Behavior. The problem is, it is a divergence from the normal way of thinking where we think in sequences but the sequence we think of is not always what should or actually will happen. Things don’t happen in sequence in the real world. The things that we think should happen or that we observe happening do indeed, generally, happen in a sequence. But in the real world were entities really do have rich behavior in each context, other things happen that we do not observe, can’t plan, and we can’t evaluate within our context. They happen within a different context, or commandhandler, on there own.

    When we go to the bathroom, and if another person is waiting for me to finish so I can give him a ride, in our context (commandhandler for finishing using the bathroom) in the real world we dont call OtherPerson.TellThatI’mReadyToLeave, we might let them know we are finished then say lets leave. Instead, we do something like Me.Context.RaiseIFinishedUsingBathroomEvent and Me.Context.RaiseImReadyToLeave(WithPerson2) Event. And then:
    Person2.HandlePerson1ReadyToLeaveEvent
    Person2.RaisePerson1LetsGoEvent
    Person1.HandleLetsGo(Person1)


    Person1.StartLeavingCommand and Person2.StartLeavingCommand

    and so on and so forth.

    Your “FindLiquorStoreResult”, IMHO, should not be an actual result. As a result of “FindLiquorStoreHandler”, a result is not directly determined. What should happen is other events happen or are raised from that handler and responded to by the person and anything else that is listening in our context. That way, we dont directly determine what the responses / actions of the other entities are, we do what we really do and raise another event from our handler and allow other entities to respond to those events on their own. So we dont have “FindLiquorStoreResult”. We have RaiseLiquorStoreFoundEvent and EnterLiquorStoreCommand and PersonEnteredLiquorStoreEvent within our context (service for some or dbcontext for entity framework people) any entity or our context that is listening for those Events has their own handler where they execute their own business logic as a result of those events. And if they want they can raise whatever events they wish.
    The benefit of this is we go from a procedural / transaction script model, to very rich behavior where any number of other entities that have registered to listen for that command within our context / service / dbcontext do whatever they want to do or may already be programmed to do on their own.

    To me, that’s how the real world works.

  • hassan rogers

    I have a large cluster of computers that were given to me by my last employer, I’m a software engineer that loves new projects, I have a total of 25 servers that are about 2 years old, i would love to start a non-profit, or link the servers up for some type of project, also im running ubuntu, im tired of windows,,,,looking for any help or new ideas,,,

    hassanrogers@tmo.blackberry.net

    alimsabree@gmail.com

  • http://codebetter.com/members/kylebaley/default.aspx Kyle Baley

    @Dan

    This is handled by gwt and gwt-platform. When we launch the command, we indicate what type of Result we are expecting back. For example:

    dispatcher.execute( new GetWineList( ), new ActionCallback( ) {
    @Override public void onSuccess( GetWineListResult ) { … }
    @Override public void onFailure( Throwable cause ) { … }
    } );

  • Dan Jensen

    My company has recently come to an architecture very similar to this for commands, but we couldn’t see how to use it for queries because the return types are always different. How do you handle this? We’re using c#, so maybe this is a difference that the GWT allows you? I’m not familiar with it.

  • http://www.geekswithblogs.net/optikal Dylan Smith

    Sounds like the Transaction Script pattern to me: http://takacsot.freeblog.hu/Files/martinfowler/transactionScript.html