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

Do you even need to Build your own CAB?

There's yet another (worthy) discussion going on in the altdotnet list about whether or not to choose CAB, another framework, or roll your own framework for a given desktop client (I'm saying desktop client here because I'm thinking of the superset of either WinForms or WPF regardless if they're "smart" clients).  Maybe first, we need to answer the question "do I need a framework at all?"  When I tell people that I don't recommend the CAB a common response is a fear that it'll take too long to write their own framework.  I think your first course of action is to determine what you really need and go from there.

This quote from Steven Mitcham set me off a little bit (emphasis mine):

Speaking from a position of having to support a hand-built framework that was not engineered with the best practices, you need to be certain that your project management and/or customer is going to support the overhead of a constant stream of "It wasn't really designed for that, so we'll have to make this breaking change" type interactions, if you aren't going to go with an established framework.

Let's think about this for a second.  What's the root cause for answering with "the framework wasn't really designed for that" to the question "can we do this simple seeming thing in this screen?"   In my experience this scenario plays out because you're using an abstraction that's optimized for too specific of a scenario.  The usual cause is falling victim to architect hubris and framework fool's gold by trying to create an uber-abstraction too early.  Other times it's caused by trying to reuse an existing framework that's optimized for different usages than what you have on your plate.  When you build an abstraction that tries to do almost everything for you, you can generally only do the things that the abstraction means for you to do.  You've made yourself faster in the specific case, but probably slower for every other single scenario.  If a framework tries to be more flexible and accommodate more cases, it probably strays into being too abstract and too generalized.  When you find yourself spending too much time with artificial concerns like WorkItem's and ModuleItems and whatnot, are you really getting anything out of the abstraction?  There is power in abstractions when they fit and there is pain when they don't.

I don't care for some specific elements of the CAB (ObjectBuilder, the event aggregation approach, the Module bootstrapping is clumsy IMHO), but the biggest issue for me in choosing NOT to use the CAB is that it wasn't designed specifically for my application.  It's built for generic scenarios.  Least common denominator approaches and structures.  My contention all along has been that I can gain more value from creating the abstractions in the application that fit my needs.  That being said, you need to be very careful with these abstractions to be something that does add value.  For best results, you need to avoid leaky abstractions and wait until the last responsible moment.  If you try to build a framework before doing the application, use an existing framework like the CAB, or use somebody's software factory*, you are automatically choosing an abstraction early.  You might be breaking on a decision before the Last Responsible Moment.  Your chances of screwing up are much higher than they would be if you were responsibly harvesting abstractions as the application needs to remove duplication.  If you have to wrap your design around a tool, the bar for using that tool is far higher than it would be for a simple library like log4net.

My advice?  Use frameworks very, very cautiously.  I don't, haven't, and won't, build my own CAB because I don't think there's any one or even a few abstractions that are generally applicable across applications.  I don't need everything in one app, and each app is different in crucial details. 

Keep the complexity to a bare minimum.  Using or building any framework automatically accelerates you to the inherent complexity of the framework.   Make every abstraction in your system earn its right to exist.

It's far more valuable to learn the patterns, including the "why' behind the pattern, and build your own structure to support the exact needs of your application.  Go look at other people's frameworks, but don't assume that it'll work for you right off the bat.

 

* I'm getting very interested in using microgeneration, ReSharper/CodeRush templates, and more IDE automation to improve productivity.  That part of Software Factories looks cool.  My fear is that Software Factories are being used to dress up BDUF in more attractive clothing.  Worse to me is the fallacy that you'll be able to create a good design with crappy developers by using a tool to constrain the developers.  I think the success of software factories is going to be ultimately dictated by how easy it is to customize and evolve the factory -- which seems to fly in the face of the software factory goal of industrializing software development. 



Comments

Lucas said:

He's saying he won't build some generic reusable framework, but rather will use the same design concepts tailored to each application and it's needs instead (which is what the whole Build Your Own CAB series is all about).

# January 9, 2008 9:29 PM

project management software » Blog Archive » Do you even need to Build your own CAB? said:

Pingback from  project management software  » Blog Archive   » Do you even need to Build your own CAB?

# January 9, 2008 10:23 PM

Steve said:

You have touched upon a major flaw of the Guidance Automation libraries that all of the P&P stuff is built upon.  The libraries themselves are designed to be extremely flexible and customizable via XML config files; however, they use versioning techniques to stop you from using a factory whose xml definition file has been changed.  Obviously they do this for security reasons since a factory can do basically anything an add-in can do, but it renders their automation toolkit basically unusable, since you have to recompile the entire factory if you make a mistake in the xml file.  

Other than that I love the GAX, once you get up to speed it is way easier than writing your own add-ins for VS (or resharper plugins for that matter).  Fortunately you can easily fix the aforementioned behavior with cecil or reflexil =)

# January 9, 2008 11:12 PM

Jeremy D. Miller said:

@Ben,

A terrible choice of name that I'd take back given the chance.  If you want to pick on me, you might notice that very, very little of the series so far actually overlaps with CAB.

# January 10, 2008 1:12 AM

Martijn Boland said:

"My fear is that Software Factories are being used to dress up BDUF in more attractive clothing.  Worse to me is the fallacy that you'll be able to create a good design with crappy developers by using a tool to constrain the developers."

Oh, this is so true! Last year, I've been on several contracts where people (especially management) claimed to have a solid development process because they have a 'software factory'.

The sad thing is that I'd prefer CAB any time over those crappy 'factories' that dumb down entire development teams ('well, some guru/architect said we all should work this way, so we just do it this way'). But hey, management is happy and they get a lot of revenue out of additional features or changes because it takes ages to implement these.

# January 10, 2008 6:11 AM

Kent Boogaart said:

If you throw a Java developer into .NET coding they are not instantly productive. The more .NET work they do, the more they will understand the platform and its limitations. They can then make better decisions about when .NET is the right platform to use and when it isn't.

The same is true of CAB. It's not perfect. It has limitations. But it *can* save a lot of time if you understand it and know how and where to apply it.

Oh, and it's not really a framework - it's guidance in code form. Therefore, you can use it as a starting point / reference for your own framework, if that's what you want to do.

# January 10, 2008 6:49 AM

Steven Mitcham said:

Actually I agree with what you are saying.  I was a pretty new .NET developer when I participated in designing this framework.

The issue here was that for my company, we do a lot of development that is in fact re-usable to a large degree so a framework made sense.

The architectural problems evolved when we realized that we did not properly separate the layers.  Issues that I have been recognizing and fixing in a large part because of your series on CAB-like development and other posters as well.

My point in the e-mail chain was to make note that when you are a part of a large organization that anything you write that looks like a framework, can and will be appropriated for use for things far beyond it's original intent.

Once such a thing is created it continually falls to you to 'fix' issues that come up because someone new is using your code in ways that they weren't intended.  I mentioned Program Management, because a lot of times the developers in such situations (like mine) are not in full control for better or worse.

# January 10, 2008 1:24 PM

Derrick said:

Jeremy, I have to argue with you on reusable abstractions.  And I do so in hopes that you won't continue to polarize many readers on the idea.  With the numerous posts you've made, building your own CAB can sound horribly daunting but it really all boils down to a handful of classes that can be written in a couple of days.  The majority of your posts on the subject are superfluous to the core concept.

In every "Build your own CAB" application that you've written, have you not used Model-View-Presenter?  Or are you cautious that your next project won't necessarily use MVP?  Have you not had commands?  I know your command infrastructure has evolved but I'm willing to bet you at least had an ICommand with the Execute() method in each version and something like an ICommandFactory to build your command objects.  I think parts of your own winform framework CAN be pulled out into a generic library that you bring with you to every project.  I agree with you that you should not create a MyCAB.dll (analagous to the real CAB.dll) and never feel the need to write framework code again, but I think you can create a MyCABBase.dll which defines interfaces (IApplicationController, IPresenter, IView, IShell, ICommand, etc) along with abstract classes to get the really generic plumbing out of your application projects.  Extend these base classes (if even necessary) in your specific applications and have the benefits of a custom molded framework with the peace of mind that your efforts are reuseable.

The problem I see with rolling a new solution with every application is that you can easily begin to blur the separation of concerns between various components.  Forcing yourself to abstract out your generic reusable interfaces/base classes can result in a much cleaner design.

# January 11, 2008 10:13 AM

Jeremy D. Miller said:

@Derrick,

First, thanks for the thoughtful comment.  

I'm not saying that abstractions are bad so much as urging extreme caution in their usage across applications and projects.  Especially if it's an abstraction that wasn't harvested from your project.  Reuse within a project and reuse across different projects are two very different things.  I think I'm mostly arguing that you'll be more efficient by creating your own abstractions to suit your application rather than trying to wrap the application around a generalized abstraction from an existing framework like CAB.

"In every "Build your own CAB" application that you've written, have you not used Model-View-Presenter?"

Yes I have, but the details have been very different from app to app.  The patterns reoccur, but the details do not.  That's been my major point about encouraging people away from the CAB and SCSF.

"Have you not had commands?  I know your command infrastructure has evolved but I'm willing to bet you at least had an ICommand with the Execute() method in each version"

Of course.  But even the shape of the ICommand has actually changed a little bit between apps.  The pattern is always there, but the details vary.  And those little app specific details can make a lot of difference in terms of efficiency and productivity.

"I think you can create a MyCABBase.dll which defines interfaces (IApplicationController, IPresenter, IView, IShell, ICommand, etc) along with abstract classes to get the really generic plumbing out of your application projects."

Again, I don't think there's quite as much potential reuse in there as you think.  In my experience, the shape of those interfaces varies widely between systems.  And the part that is perfectly reusable is simplistic.  My main contention that I'm not backing off of is that knowledge of the patterns is far more important to the community at large than having resuable frameworks.  

"Forcing yourself to abstract out your generic reusable interfaces/base classes can result in a much cleaner design."

Agreed, but that's orthogonal to the decision to use CAB or go your own way.

# January 11, 2008 10:54 AM

Derrick said:

To each their own.  I've found a common generic interface structure that works well for me.  I think the main point I wanted to get across is this whole “build your own CAB” thing is coming across as way too complex for the average joe.  I think it’s actually the name.  “Build your own CAB” makes it sound like developers need to rewrite the entire CAB which is the opposite of you’re intent.  And when you then say you rewrite it again and again, I can envision people spinning their heads.  

# January 11, 2008 11:45 AM

Jeremy D. Miller said:

“Build your own CAB” makes it sound like developers need to rewrite the entire CAB which is the opposite of you’re intent

As I said above, I made a mistake on the name.  It does sound a little better than "Just things you do when you build a desktop app"

# January 11, 2008 11:50 AM

Jeremy D. Miller said:

Of course, it's also each to his own.  *I* think the CAB is too complex for what it does.

# January 11, 2008 11:56 AM

Glenn Block said:

There are some abstractiions that do prove to be reusable across a large set of projects. Virtually milions of projects have been built utilizing the base contruct UserControl or Control. The thing to be wary of is when those abstractions are too prescriptive thus imposing "false" limitations and restricting the design. This is what I believed happened in many cases with CAB due to it's tight coupling, which is ironic since it was designed to give you a loosely coupled application.

# January 12, 2008 4:09 AM

いま話題の女性芸能人とは? said:

YOU プロフィール検索 動画検索 画像検索

# January 12, 2008 4:33 AM

hubris said:

Pingback from  hubris

# January 13, 2008 1:35 AM

Ben said:

I get what you're saying now.  Thanks!

# January 17, 2008 2:49 PM

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