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

Downcasting is a Code Smell

Before you go any farther, a Code Smell simply implies that there *might* be something wrong with your code and that you *definitely* need to evaluate your code. 

 

Downcasting, in my opinion, is a code smell.  Specifically, I think code like this below is smelly: 

        public void Filter(IFilter filter, object[] targets)

        {

            if (filter is StringValueFilter)

            {

                StringValueFilter stringValueFilter = (StringValueFilter) filter;

                // call a specific member on the StringValueFilter

            }

        }

There's a couple different problems that the downcasting smell might be exposing:

  • Your abstraction is leaky and needs to be refactored or eliminated.  In the case above, everything should be accomplished through the IFilter interface.
  • You've violated Tell, Don't Ask, which is another way of saying that you're not properly encapsulating functionality.  Encapsulation is important for a couple reasons.  First, encapsulation makes code easier to use because there is less stuff necessary to know or do to make it work.  Secondly, poor encapsulation can greatly increase duplication throughout your code base.

To avoid downcasting, you might take a look at:

  • The Information Expert pattern from Craig Larman, or
  • Use Double Dispatch.  Double Dispatch used to feel really odd to me, but I've used it in a couple places in the last year where it has streamlined quite a bit of hacky if/then logic.


Comments

ScottBellware said:

Dude!  I didn't realize that you were leaving Austin for New York to get the opportunity to maintain headless VB 6 code.  Heck, you coulda come to work for me maintaining our legacy apps.  Har-har-har!

Just kidding.  Keep up the good fight.  The rebel would be diminished without people like you.

# December 26, 2006 8:53 PM

Jeremy D. Miller said:

Scott,

The code that may or may not have inspired this post wasn't VB.  I don' t know why you automatically assumed that bad code was from VB6 developers;)

It's still better than the "legacy" code Steve and I wrestled with in Austin.

# December 27, 2006 6:54 AM

Travis said:

Jeremy, could you rewrite that code the "correct" way?  I'm really just curious.

# December 27, 2006 8:32 AM

Jeremy D. Miller said:

Travis,

That was a pretty off the cuff example, but let's try.  All you really want to do is have that Filter(IFilter) method work by calling a member on the abstracted IFilter interface instance that is being passed in.  It might be something like IFilter.Matches(target) returning a boolean, or with double dispatch it would be something like filter.Filter(this);

I've got an idea for a post to demonstrate a Visitor pattern that would demonstrate double dispatch.

Two years ago I wrote a business rules engine that worked on data in DataSet's.  I had an IFilter interface that could test conditions on the rows coming in to the engine.  Some of the IFilter's could just declaratively use little sql snippets for the condition, while others had to programmatically check each DataRow.  A few did both.  I simply made the rules processor class strictly use the IFilter interface to add SQL snippets and then later to test the DataRow's programmatically without knowing or caring how each IFilter instance worked.

# December 27, 2006 8:42 AM

Jason Haley said:

# January 1, 2007 1:15 PM

Jeremy D. Miller -- The Shade Tree Developer said:

I'm a big believer in learning the fundamentals of coding and design. To me, things like design patterns

# September 28, 2007 9:28 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