Thursday, September 28, 2006 - Posts

Smart Client Factory, not your grandmother's old P and P

Until 2 weeks ago, it had been about 8 months since I had an opportunity to look at any offerings from the Patterns & Practices group. My how things can change in 8 months! Back at the beginning of the year I gave the Composite UI Application Block (CAB) Smart Client framework a first look. It is quite an impressive framework for building Windows forms Smart Clients. But, it is one of those things that needs more then a first look to really come to grips with it. A quick Google search on "CAB Complexity" will give you a good idea; here are a few good links: DevHawk (from 11/2005)  "However, I can't shake the feeling of how complex this stuff is", Sam Gentile's - CAB Smart Clients in an Agile world part 1 while discussing his initial thoughts "...Yet CAB’s seeming complexity had overwhelmed me..." Additionally, right on the P & P CAB home on gotdotnet in the overview section it clearly says "Ever wondered what would the architecture and design of a complex UI would look like?" I guess they weren't kidding! I remember back when I first read this I had said to myself "man, I've seen enough complex UI architectures, what I really want to see is a simple one! But, I digress...

Once you come to grips with CAB, it is a pretty impressive framework, and even if you don't have an opportunity to put it to use right away, there is some well written code and UI architecture guidance that can be learned by giving this thing some time. The overall design is based upon 3 major goals: 1) dynamically loading application modules at run time, 2) separation of development concerns, 3) achieving code re-use by providing common techniques for loose coupling modularity. I'm not sure I'm sold on the success of all 3 goals, but I'll talk more about that below. There is however, an awful lot about CAB that I like: The Event Broker Pub/Sub approach, Object Builder and its injection magic using "service dependency" attributes and the modularity in general like the UIExtensionSites for allowing modules to add their own stuff to toolbars, menu, etc. Additionally the guidance that developed around the use of WebService agents, proxies, commands and implementing asynchronous background calls with specified timeout was precious. This is just a fraction of stuff that comes immediately to mind.

Now jump to the present time (remember CAB was released around 12/05) and suddenly we have 3 Software Factories (
Smart Client Software Factory, Mobile Client Software Factory, and the latest Web Service Software Factory all available to assist, guide and generate baseline framework code for us! Man a lot has been happening at the Patterns and Practice group this year. So far, I've only had time to dig into the Smart Client Software Factory, and again it is quite impressive. If you have already used CAB, I guess you can look at The Smart Client Software Factory as a big integrated wrapper and guidance package around CAB. Besides for CAB, it integrates the Enterprise Library (Caching, Exception Handling, Logging, etc.), Guidance Automation Toolkit and Guidance Automation Extensions (enabling framework generation and code automation and recipies), as well as a couple of sample applications to demonstrate Smart Client approaches. Wow, some good stuff. I've slept little over the past two weeks feeling like a kid in a candy store since I started digging back into the P&P offerings. Besides for architecting solutions and writing code myself, I love reading and learning about other people's approaches to solving the same problems I've worked toward solving myself. You end up solidifying some of your approaches (and feeling good about seeing others doing things the same) and yet questing other approaches (some yours some theirs), and in the end grow from the experience.

Despite all this goodness, I have to admit that I initially put down CAB at the beginning of the year, frustrated not by the complexity, but by of all things, some of the guidance around business logic and lack of domain logic. And, as I've been digging into CAB again now, under the new covers of the Software Factory, I've found myself a number of times feeling this same difference of opinion on business logic. Difference of opinion are to be expected. It is a given. It's just that I'm so passionate myself about domain specific business logic encapsulation that it's a tough elephant in the corner to ignore when reading through all the great documentation, help files and demos. I mean there is so much there, so much great thought given to complex problems, how can domain business logic be so missing? Maybe its me? A quick search on CAB Business Logic doesn't turn up much of relevance.

My problem is twofold, 1 part difference of option on the term "business logic", which comes through loud and clear bullet point after bullet point in documentation, and second is a bit of difference of option on architecture associated with domain business logic.

First, lets look at the difference of opinion on the definition of "business logic". All of the CAB documentation seems to consider UI specific design, namely web forms, win forms, a Windows TextBox or a mobile control drop down, etc. all part of "business logic" and I don't. This is really ironic too, seeing as it is clearly stated again and again that one of the core tenets of CAB and the Smart Client Factory is to separate UI concerns from business concerns. However, it seems that they only really consider the job of creating the outer shell of a Smart Client application (main work space, toolbars, status bar, menu, etc) to be real UI, and all other application UI like stuff (forms, controls, etc.) to be "business logic". I'm sorry but I find myself scratching my head in WTF fashion when I read this over and over throughout CAB docs, blogs, help files, etc. For an example, look under the section entitled "Benefits" and "Separation of Concerns" in the
Overview of the Composite UI Application Block  and you come across this little nugget: "Applications built with the Composite UI Application Block have a design that delineates the difference between writing shell logic (requiring expertise in Windows Forms, user controls, and appearance and behavior), infrastructure components (built only once per application or re-used from other applications), and business logic (the user interfaces, logic, entities, and service agents of the specific application). "

OK, you might think I'm taking this one little inclusion of "user interfaces" with business logic a bit overboard, but this common rational and description of "business logic" is embedded over and over in quite a lot of CAB reference material. The problem is that one of the goals of CAB is to allow modular design, where each module is like a tiny application that is plugged into an overall shell application, and each of the modules added all up represents the business logic of the overall application. Now, in defense of CAB documentation, I don't believe I stumbled over anything that explicitly said that you shouldn't take things a step further and extract the real Domain specific business logic and business behavior (read no UI) out into yet another septate assembly and then reference that in your module assembly, but then again it never seems to be suggested either, and to me this is just enterprise architecture 101. Instead, everything about CAB suggest that all "business logic" exist in the module assembly. Keep in mind that this module assembly is designed specifically with a given Smart Client Shell in mind that it will be loaded into, and the module assembly contains all the UI forms and controls, etc., etc. etc. Once again, in CAB defense, all of the documentation and the CAB framework in general is built around the idea that the pieces of the module will be built using good UI separation of concern Modal View Presenter patterns. But it takes a little more then a separate "presenter" class or supervising controller architecture alone for me to feel like we are ready to start talking about coding domain specific business logic yet. At best, when we are in the very UI world of views, presenters and supervising controllers we are talking about wiring up specific UI use cases to well defined Domain Use Cases, but we definely shouldn't be talking about actually encapsulating and coding this Domain Business should we?

And this is where we come into my second difference of opinion, and this is really just plain old architecture difference of opinion and different architects are going see this from different perspectives, but I'm unfortunately talking about a Business Object versus Business Entity difference of opinion. Everything coming out of the P&P factories seem to all take the business entity approach. This type of architecture generally involves light weight classes, really just exposing property getter and setters, taking the shape of pieces of domain data, being acted upon in pipeline like fashion and cross cut by vertical aspects like security. However, generally the entities themselves encapsulate no behavior, but just data. Behavior exists in supervising controllers, and presenters, and helpers but is separate from the "entity". This is definely an architecture direction that is growing more and more in popularity. Like all architectural direction however, it has its place and can often be a wise choice, but it is not the only one and isn't always the best choice.

The problem is that this behavior free entity approach works fine in most small demo applications, but once you really get into building true line of business applications, the business logic starts leaking out everywhere. Lets assume you have an entity that represents the data associated with applying for a loan. And lets suppose that you have a field called ApplicationDate and a field called RequestedFirstPaymentDate, and lets suppose that the Domain you are working in has a rule that says the Requested First Payment Date must be greater then 30 days but less then 45 days from the Application Date. Following a CAB recipe where would you put this logic? In the presenter? In a WorkItem? In the loan service? Well in my opinion the answer is "None of the above!" It doesn't even belong in the CAB module to begin with. The CAB is all about UI as in "Composite UI Application Block" This domain specific logic belongs in a separate Domain Object and project! The only thing the module's presenters or controllers should be responsible for doing is wiring up to the Domain Object's exposed interface for acknowledging this business rule. But definely the rule should not belong in the module. What if you also build a Mobile application using the Mobile Software Factory, and you also want to expose a loan processing web service to some third party resellers. Do you code this same business rule in each respective application. I hope not.

The CAB Smart Client application is dynamically modular by design, and can be expanded nicely over time in true loosely coupled like fashion, but each module that it loads is specifically built for that particular Smart Client application. In other words, the modules are UI specific. They are built knowing that their shell application is a windows application so that they can display maybe a windows forms or a windows user control when acted upon. And they should be built with the goal of solving that particular UI application use case. They need to know that there is a menu in the shell called "MySmartClientAppMenu" (or enter name here) so that they can add commands to the menu. The modules are not designed to be used in multiple places; i.e. I would not re-use a windows SmartClient CAB module in a web application, or within a web service being built to expose the same "Business Logic" to other applications. So, these modules have no real right or place to contain "business logic".

Overall, I am amazed by what I have seen with the Software Factory, including CAB, the GAT/GAX and general guidance. It is great, great stuf. Additionally, despite the fact that there is no real guidance toward this "practice and pattern" there is nothing actually stopping me from building a great Smart Client Application, using CAB just as it is, and taking advantage of GAT/GAX, while at the same time creating separate Domain libraries for business logic. As a matter of fact, I think I will : - )