December 15, 2011

System Architecture - UI Patterns, Repositories, Service Layers - What and how much?

Over the past couple of months, my co-workers and I have been watching a video series on Software Craftsmanship, called Clean Coders, by "Uncle" Bob Martin.

The last video we watched was on System Architecture. In this video Bob Martin talked about how presentation patterns like MVC and MVP are part of "delivery mechanisms" of a system architecture and the that business logic should reside in "Interactors" -- a higher level controller like class. The group I watched the video with related these interactors to services in a service layer. At a recent usergroup meeting I attended, about UI Presentation Patterns (MVC, MVP, MVVM) the speaker said you should favor light controllers (or presenters) and heavier models (models as in -- Db Layer, Repos, Service Layers etc.) -- pretty much same thing as Bob said.
That said, I wanted to know how this applied to a project I'm working on which uses a UI Presentation Pattern Framework called WebformsMVP (blogged about this previously here). Inparticular, I wanted to know:

What is the consensus for system architecture with MVP?



  • Light Presenters with mainly just calls to service layer?

  • Heavier Services with business logic and calls to Repositories?

  • Light Repositories with calls to the database?


So I reached out to the WebFormsMVP GoogleGroup and asked these questions there. Below is a response I got back from one of the users, Alan McBee.



Uncle Bob is right. Light Presenters are best. Following SOLID, I say that the primary (or Single Responsibility) for Presenters are to provide the interaction between the state of the domain model in whatever form that happens to be (whether you use Repository, or some other business layer, or even just LINQ2SQL, just use your best judgment), and the state of the user interface which provides the Views.


The domain model is naturally stateful, or at least its instantaneous state at any point in time is not necessarily dependent on the view. In other words, unless your domain space is entirely ephemeral (like a packet filter in a firewall), then you have statefulness, and frequently that state is persisted. A good domain model has no "awareness" of the nature of its clients. Why? Because we've seen too many times that client interfaces evolve faster than the domain models. Twenty years ago, there were still a lot of MS-DOS interfaces, and client-server was the only model. Since then, we've gone through Visual Basic, and then then Web (CGI, Java, ActiveX), and then we got ASP.NET, and then SOAP (remember B2B?), and now we have WCF, REST, and AJAX with jQuery. Each with different driving forces and best practices. But twenty years ago, there were domain models that are still applicable today (we still have products, customers, orders, employees, addresses, yada-yada). Will there be new client interfaces? If history is a guide, the answer is certainly yes. But the domain models are not tied to those interfaces. Maybe Rich Internet Applications (RIA) will be all the rage in a year or two. Maybe Windows 8 Metro will be the must-have UI. Your architecture should expect that the UI requirements will change faster than your domain model.

What I'm getting at here is that for most enterprise applications, a layered architecture works very well at allowing you to separate concerns, so that your domain model changes only as your fundamental business needs change, but the presentation layer changes only as you change what you hope is the best experience for your customers as possible.


In the Web, state must be artificially maintained across each request. You might use form values, cookies, URL queries, or abstractions over these (like ViewState), or Session state. All of these state management mechanisms require special handling of some kind. And then, of course, there is the actual rendering of the View itself.

UI work can be very difficult to do properly. Partly this is because of the uncontrollable nature of your users. Partly this is because you're frequently working with brand new, incompletely understood technologies. Partly this is because the actual supporting technologies (Windows API, HTTP servers, caching proxies, etc.) are very complicated, and present their own set of challenges when trying to prove your code is correct.

For this reason, it just makes good sense to try to reduce the amount of work you have to do when constructing a user interface. The more effectively you can pre-test your interface, the less work you have to do trying to fix defects.

So -- keep the Presenter light, in order to reduce testing and maintenance work required when you need to alter your user interface, or when you need to support an entirely new user interface mechanism (who knows? Maybe Kinect is going to shake the world!)

Keep the Services heavier (or rather, richer, in the sense that you can aggregate other services into consolidated or special-purpose services), because services (SOA) are widely agreed upon as the most cost-effective way to construct composite applications, and it's very likely that you application will need to interoperate with other services or applications if it's in any kind of growth mode. When you consider your domain model from a service-oriented perspective, it's much easier to create and adapt integration points. You can do all of this with almost complete disregard for the nature of the UI.

I should remark that when I say Services, I am excluding Web Services (whether REST or SOAP). Web Services are interfaces for clients. A Web Service should be (or could be) a shim over your Services.

Keep the Repositories light, I say, because their primary responsibility is to provide domain-specific hierarchical organization to the entities in your data store (a very effective way to enforce relational integrity without depending on a Relational DBMS to manage it). While I have rarely worked on the project that actually needed to change the underlying data store (say, from Oracle to SQL Server), things are getting more interesting here, especially with cloud-based data stores and no-SQL data stores. So, a Repository can be a valuable layer of abstraction over your data layer, and allow you to use the best technology in the data layer, without compromising future choices by making your Services dependent on NHibernate, or Entity Frameworks, or that roll-your-own framework that was built six years ago and nobody understands anymore.

Now, with all that said, I'm going to provide a contradictory point of view.

If your domain model is really focused on a set of pretty rudimentary CRUD operations, you might forego the Services layer altogether, or at least, on those CRUD parts of the model. There really isn't any value (beyond uniformity) in providing a full set of Services which just transport data in or out of the data store.

By the way, I prefer to use the adaptation of the pattern called MVPVM. That is, my architecture has:

(M)odel (basically, the Services layer and/or the Repository)

(V)iew (the ASP.NET page)

(P)resenters (using the WebFormsMvp framework)

(V)iew(M)odel (a data-bindable DTO; this is what the WebFormsMvp framework sets in the .Model property of the View)

The rest of each system is comprised of a data access layer (usually just a code-generated Entity Framework library), the data store itself, proxies to other services, cross-cutting components (access control, logging, instrumentation), etc.

Hope that helps,

->A





I thought Alan's answer was spot-on and confirmed what I had already picked up  and appreciated him taking the time to write that answer in such detail so I wanted to share it with you all. Thanks Alan.



For the full post click here.


No comments:

Post a Comment