Build your own CAB: It’s mostly fundamental

Yesterday I was part of a lot of conversations about building composite desktop applications.  The people in attendance are building a myriad array of large desktop clients and they’re facing some substantial challenges.  Offhand, I remember hearing:

  • The desire to reuse business logic between user interfaces
  • Wanting to share UI workflow between different screens
  • The ability to have multiple teams working in parallel on different elements of the same application
  • Extensibility was a big deal
  • Keeping business logic out of the UI screens
  • Keeping data access out of the UI screens.  Yes, even in the year 2008, this still happens.
  • Preventing ourselves from getting too tightly bound to a particular presentation technology.  This is a hot button topic for me because I’ve decided to forgo WPF for the first couple releases, but it’s obvious that we’ll go that way at some point in about a year.
  • Consistency in design
  • Object with more than one responsibility

A lot of these challenges can be addressed by the design patterns that I’ve been writing about in the “Build your own CAB.”  I’m obviously a big fan of Design Patterns, but throughout the day I’ve been struck by how most of these problems are really solved by applying the fundamentals of software design.  If you had never, ever heard of the Model View Presenter patterns, but followed the core OOP design fundamentals like separating concerns, you’d be generally be fine.  I’ve seen some comprehensive lists lately of what a developer needs to know, and what to study.  The lists were intimidating, and that might be wrong.  We need to stress design fundamentals first before we even think of trying to explain Dependency Injection or Model View Presenter patterns.

Let’s look at the list again and connect it to :

  • The desire to reuse business logic between user interfaces.  The business logic is a concern all by itself.  It should be in a totally different set of classes that have no connection to the UI at all.  Problem solved.
  • Wanting to share UI workflow between different screens.  Recognize that there’s some duplication in the system.  If you see a basic workflow reoccurring, find a way to pull out the part of the workflows that are consistent.  Don’t repeat yourself.  One of the best pieces of design advice I’ve ever read is that one of the best things you can do to improve a design is to simply remove duplication.  The simple act of isolating commonality will push you in the direction of better cohesion and coupling property.
  • The ability to have multiple teams working in parallel on different elements of the same application.  This is a little more complicated, but still within the realm of design fundamentals.  The best way to pull this off is to make each screen (model/view/presenter and whatever the presenter needs) have as little coupling to the rest of the application as possible.  One way or another the presenter and view need to know as little as possible about the application shell and vice versa.  The Open/Closed Principle comes into play here.  You want to be able to extend the application (Open for extension) by writing all new code in the new screen by the other teams, with little modification to the application shell code (closed for modification). 
  • Extensibility was a big deal.  See above.
  • Keeping business logic out of the UI screens.  Separation of concerns
  • Keeping data access out of the UI screens.  Separation of concerns 
  • Preventing ourselves from getting too tightly bound to a particular presentation technology.  The way to beat this is to slice the view as thin as possible.  You separate the behavioral logic of the screen away from the actual view.  Follow Jeremy’s First Law of TDD:  Isolate the Ugly. 
  • Consistency in design.  This is as much or more about teamwork and soft issues like collective ownership.  I say this is mostly a people problem.
  • Object with more than one responsibility.  Single Responsibility Principle.  One class, one responsibility. 

About Jeremy Miller

Jeremy is the Chief Software Architect at Dovetail Software, the coolest ISV in Austin. Jeremy began his IT career writing "Shadow IT" applications to automate his engineering documentation, then wandered into software development because it looked like more fun. Jeremy is the author of the open source StructureMap tool for Dependency Injection with .Net, StoryTeller for supercharged acceptance testing in .Net, and one of the principal developers behind FubuMVC. Jeremy's thoughts on all things software can be found at The Shade Tree Developer at http://codebetter.com/jeremymiller.
This entry was posted in Build your own CAB. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • pavan kumar

    Hi jeremy,
    I am trying to build a desktop application , I read about an article on using HMVC “http://www.javaworld.com/javaworld/jw-07-2000/jw-0721-hmvc.html” , but there seem to be many issues which the article has not addressed.
    Can u throw some light on this pattern and suggest suitable alternatives

  • http://codebetter.com/blogs/jeremy.miller Jeremy D. Miller

    @Weex,

    “reason to change” is a great heuristic for identifying responsibilities. I wouldn’t say it’s completely a science, but you can at least see the big things. Another heuristic is to ask yourself is if everything in the class is directly traceable to the class name. That doesn’t count if your class name is too general like “InvoiceManager” because that could mean anything.

  • Weex

    > Object with more than one responsibility. Single Responsibility Principle. One class, one responsibility.

    How would you define a responsibility? How do you know that a class has one\many responsibility(ies)?

    I remember someone “defining” it as “reason to change”.

  • http://kentb.blogspot.com Kent Boogaart

    I hear you on Winforms data binding. It works well in the simple case and doesn’t prevent a good design. In the more involved cases, it repeatedly falls short in one way or another: not supported, not supported well enough, inconsistent etcetera.

    But I also think that advocates of passive view are generally reacting to past experiences with poor binding infrastructure such as in Winforms more than anything else.

    Data binding in WPF is fantastic. And I wouldn’t say supporting it in your business layer causes pollution, since you’re only providing implementations of INotifyPropertyChanged and INotifyCollectionChanged – both in the System.ComponentModel namespace, and both very non-UI centric. With Winforms though, I’d agree. Putting UI concepts imposed by the IBindingList interface (AllowEdit, AllowNew etcetera) into your business layer feels icky at best.

    So – for me at least – WPF data binding is a boon and should not be shunned because of past experience with other UI platforms. However, my current project is Winforms so I will definitely check out your microcontroller solution.

    Thanks man.

  • http://codebetter.com/blogs/jeremy.miller Jeremy D. Miller

    @Kent,

    “What about supporting data binding from your business layer collections? For example, Winforms requires IBindingList whilst WPF requires INotifyCollectionChanged. Neither works with the other. Therefore, to do this your business layer must take a “dependency” on one or the other.”

    I’ve got a very simple answer to that one. Not gonna do it. The WinForms data binding is *extremely* problematic, so I’m not going to use it. I had significant success last year with this strategy here: http://codebetter.com/blogs/jeremy.miller/archive/2007/10/21/build-your-own-cab-15-microcontrollers.aspx

    We’re going to rebuild the MicroControllers data binding in C# 3.0 at http://shadetree.tigris.org and use that for screen synchronization. One of the design goals is to eliminate all need to pollute my Model classes with any data binding support stuff. My gamble is that I can easily adapt the tooling to WPF later with just a slightly different set of MicroControllers for the new WPF controls.

    You can now start calling me crazy;)

  • http://kentb.blogspot.com Kent Boogaart

    > Preventing ourselves from getting too tightly bound to a particular presentation technology. The way to beat this is to slice the view as thin as possible

    What about supporting data binding from your business layer collections? For example, Winforms requires IBindingList whilst WPF requires INotifyCollectionChanged. Neither works with the other. Therefore, to do this your business layer must take a “dependency” on one or the other.

  • http://codebetter.com/blogs/jeremy.miller Jeremy D. Miller

    Pavan,

    Can you be more specific? What are you asking for?

  • pavan kumar

    Hi jeremy ,
    Can u please explain how to make use of the Heirarchial MVC Pattern to design desktop apps….

  • pavan kumar

    Hi jeremy ,
    Can u please explain how to make use of the Heirarchial MVC Pattern to design desktop apps….