how to write code (continued…)

Following on from yesterday’s top ten software development rules, let’s begin to expand on them a bit…

1. Every domain class should have a battery of tests for the behavior it is exhibiting (data only classes need no tests)

There’s not much to say here as it’s all been said before by every competent software engineer and his dog. But the stark reality is that testing allows us to write code today that can be more safely modified in the future such that the tests will alert us to any unexpected or unwanted side effects from the modification.

If you write code and don’t bother to write unit tests then you are effectively creating an un-maintainable software legacy. With everything we know about how to be professional in writing high quality software, not writing tests is about as sensible as a Formula 1 driver not wearing a seatbelt during a Grand Prix race.

2. Avoid inheritance unless there really is an *is a* relationship between derived and base

This one could also be recast as: “Favor composition over inheritance”. The upshot of this point is that debugging 3 or more levels of inheritance is just plain hard! For some reason, there is a more than healthy percentage of experienced developers who proactively go looking for the inheritance tool when all too often it’s just not applicable. UI frameworks typically have lots of inheritance going on (i.e. WPF) and this is where lots of inheritance usually makes more sense (if anywhere).

It’s pretty straight forward to determine whether class Dog should be made to derive from class Animal and that is to ask the following question out loud: Is a Dog an Animal?”. The answer is clearly yes! Should Circle class be made to derive from Shape class? Let’s ask that one out loud: Is a Circle a Shape?” Yes!

But of course, these are easy examples to see where an inheritance relationship is highly obvious. But the murkier the class names, the harder it is tell. For example, should WritableDownloadCounter be made to derive from CloneableServerInterpreter or vice-versa? Let’s ask the question: Is a WritableDownloadCounter a CloneableServerInterpreter?”. That doesn’t help. So a good suggestion would be to give the classes good names and then re-ask the “is a” question.

But the classic inheritance fail is seeing two classes with the same method implementations and immediately deciding to create a base class and have the two classes derive from it. No, no, no! How about this for an obvious candidate for inheritance abuse:

public class Dog
{   
    private int age;
    public void Noise() { Console.WriteLine("Woof!");
} 

public class Robot
{    
    private int age;
    public void Noise() { Console.WriteLine("I am Robby the robot!"); }
}
The gung-ho inheritance developer sees two methods that look rather samey then spots the common age field and simply can’t resist creating a base class for them both to inherit from, thus increasing the overall beauty of the class hierarchy by apparently simplifying the implementations of Dog and Robot – not!:
public abstract class Animbot
{
    protected int age;
    public abstract void Noise();
}

public class Dog : Animbot
{   
    public override void Noise() { Console.WriteLine("Woof!");
} 

public class Robot : Animbot
{    
    public override void Noise() { Console.WriteLine("I am Robby the robot!"); }
}

So we’ve introduced a badly named abstract base class called ‘Animbot’ that has an abstract method which anyone deriving from is forced to override and by the magic of inheritance Dog and Robot no longer need to declare their own age field because Animbot takes care of that for them. To be clear, this new class completely sucks and we were actually a lot better off with good old Dog and Robot being classes unto themselves.

‘Animbot’ (or whatever it really is) is a ridiculously awful class name which is clearly failing the “is-a” test: “Is a Dog an Animbot?”. “Is a Robot an Animbot?”. Who knows?! But I’d wage a bet that neither of them are an ‘Animbot’.

But maybe another base class name could have worked out better when asking the “is-a” question such that it would have passed the test? How about ‘Animal’ as the base class name? “Is a Dog an Animal?” Yes, so far so good. “Is a Robot an Animal”. Doh!…

Okay, how about being a bit more generic with the class name….how about ’Object’? “Is a Dog an Object?”. Well maybe to the gung-ho inheritance developer it is, but if you were to ask my Aunt that question about her favorite Yorkshire Terrier called ‘Petey’ she’d probably have to disagree with you!

Aside from that, .NET already has System.Object (as does Java) so we’ll probably end up sticking with ‘Animbot’ for the time being because it’s late and we have to get this code checked in – besides, we can always worry about thinking up a better name once the Stelliferous epoch has come to an end, or better still, we’re only creating a confusing software legacy that some other muppet will have to worry about since by that time, I’ll be on board my 60 foot yacht sipping Pina Coladas surrounded by a bevy of Bond girls clamoring for my class name of the day.

Let’s call it a wrap for this post and carry it on next time…

Advertisements

About aerlian

I am a software engineer
This entry was posted in C#, Software Engineering and tagged , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s