Dave Chestnutt: SparklingCode and CodeGaffes

Writing better code; for fun and profit

  Home  |   Contact  |   Syndication    |   Login
  18 Posts | 1 Stories | 51 Comments | 21 Trackbacks

News

Tag Cloud


Article Categories

Archives

Post Categories

Monday, January 16, 2006 #

One of the benefits of object oriented design, is that some problems show up during compile-time instead of at run-time.  And you know that run-time issues always show up at the worst possible time, like at a customer site.
 
This CodeGaffe happens when a programmer writes code that "enforces" something with comments, or Assertions.  Have you ever seen a method defined in a base class with a comment or Assertion telling you to override it?  Of course, if the subclass doesn't override it, you can be certain the method will be called at an inopportune time. This is a simple misunderstanding of an object oriented feature because there is a way to make the language work for you to force the subclass author to override the method.
 
So what's this CodeGaffe look like?

 
    public class TableBase
    {
        public virtual int CountLines()
        {
            Debug.Assert(false, "override me");  // *** Don't do this
            return 0;
        }
    }
 
    public class MyTableSubclass : TableBase  // subclass
    {
    }
 
    public static void Main(string[] args)        // here is code to use it
    {
        MyTableSubclass table = new MyTableSubclass ();
        Console.WriteLine(table.CountLines());  // prints 0 after assert
    }


 
See the problem?  As the original author of TableBase, you want to make sure people who write subclasses implement their own CountLines method.  But if they forget to override it, they won't know until the method is called at runtime.   Possibly at a customer site, but more likely during testing.  
 
Instead, define your base class this way:

 
    public abstract class TableBase           // *** Do use "abstract"
    {
        public abstract int CountLines();     // *** Do use "abstract"
    }
 
    public class MyTableSubclass : TableBase  // now this won't compile
    {
    }

 

Now, if someone extends your class, they'll find out at compile-time -- that's about as immediate as you can get without standing behind them, watching over their shoulder as they code.  And fixing the subclass at this time is trivial because the error points to the actual problem: a missing definition for CountLines.

 


 

    public abstract class TableBase
    {
        public abstract int CountLines(); // *** "abstract" forces your intent
    }
   

    public class MyTableSubclass : TableBase
    {
        public override int CountLines() // the new method definition
        {
            return 1;
        }
    }

 

    public static void Main(string[] args) // here is code to use it
    {
        MyTableSubclass table = new MyTableSubclass ();
        Console.WriteLine(table.CountLines());  // outputs "1", as it should 
    }
       


 

The moral?  If you find yourself creating (or maintaining) a method with comments or assertions telling people to override it -- make the method abstract.  And you'll enforce your intention.

 

Technorati tags: ,


In my company, I've been able to join various projects over the years.  As a result, I'm usually modifying or adding to legacy code.  Of course, in reality, all code is legacy code after about a week.
 
In looking at code (written by others as well as myself) I sometimes see bad coding practices.  These are always obvious in hindsight. 
 
In the spirit of blogging, I'm going to share these as CodeGaffes.   Look to understand the reason why these are bad, as well as how to fix or avoid them.  In a sense, these are like design patterns, only in miniature.  By and large, they apply to all three languages, C#, Java, and C++.
 
Hopefully you can be amused (as you recognize them) or instructed (by avoiding them).
 
I am certainly not the first (nor the last) to point out these coding problems.  You can find them mentioned elsewhere in blogs and books, I'm just pulling some of them together.
 
Feel free to add comments, whether you agree or not.  And, of course, we all love to hear war stories where you've seen the effects of such gaffes. 
 
Sparkling code - this is what you strive for.  Stuff to be proud of.

See recent posts: http://geekswithblogs/dchestnutt
 
Technorati tags: ,