CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Jeremy D. Miller -- The Shade Tree Developer

Under the hood and working with .Net, TDD, Software Design, and Agile Stuff

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. 


Comments

pavan kumar said:

Hi jeremy ,

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

# January 16, 2008 12:33 AM

Jeremy D. Miller said:

Pavan,

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

# January 16, 2008 12:42 AM

Kent Boogaart said:

> 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.

# January 16, 2008 7:34 AM

Jeremy D. Miller said:

@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:  codebetter.com/.../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;)

# January 16, 2008 9:13 AM

Kent Boogaart said:

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.

# January 16, 2008 10:10 AM

Weex said:

> 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".

# January 16, 2008 5:06 PM

Jeremy D. Miller said:

@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.

# January 16, 2008 5:20 PM

pavan kumar said:

Hi jeremy,

   I am trying to build a desktop application , I read about an article on using HMVC "www.javaworld.com/.../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

# January 17, 2008 1:43 AM

Leave a Comment

(required)  
(optional)
(required)  

Enter the numbers above:
Add

About Jeremy D. Miller

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 previously worked as a systems architect building mission critical supply chain software for a Fortune 100 company and learned agile development practices as a .Net consultant at ThoughtWorks, one of the pioneers of agile development. Jeremy is the author of the open source StructureMap (http://structuremap.sourceforge.net) tool for Dependency Injection with .Net and the forthcoming StoryTeller (http://storyteller.tigris.org) tool for supercharged FIT testing in .Net. Jeremy's thoughts on just about everything software related can be found on his weblog "The Shade Tree Developer" at http://codebetter.com/blogs/jeremy.miller, part of the popular CodeBetter site. Jeremy is a Microsoft MVP for C#. Check out Devlicio.us!

This Blog

Syndication

News

All opinions expressed here constitute my (Jeremy D. Miller's) personal opinion, and do not necessarily represent the opinion of any other organization or person, including (but not limited to) my fellow employees, my employer, its clients or their agents.

About Me

"Best Of" Compendium

StructureMap (Dependency Injection for .Net)

StoryTeller (Supercharged Fit)

Build your own Cab

TestDriven

MVP