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.