Tuesday, August 25, 2009

Design vs. Structure

In many conversations about development, words like design and structure are thrown around.  It is important then when discussing software development to understand the differences between the two.

According to Merriam-Webster, design is

a particular purpose held in view by an individual or group... deliberate purposive planning

The definition of structure is

something arranged in a definite pattern of organization... manner of construction

The difference is that a design is about purpose while structure is about organization.  Code that is structured but has no purpose for it's structure may as well not be structured at all.  There is no cohesion, no single responsibilities, and no reason for a class to exist if it exists for structure alone.  When we set out to structure our code, we should have a design purpose in mind. 

Another way of saying this is "form follows function".  Determine the function and the form will follow.  Determine the design and the structure will follow.

Monday, August 24, 2009

Member Variables are not Global Variables

It is widely accepted that global variables, in almost any context, are a bad practice. But there is a common practice that leads to code that is harder to maintain - the use of member variables for passing information between functions for a particular set of functionality. This is a subtle way of creating global variables in that they are "global" between functions.

As an example, let's look at the code below. For this example, we're going to assume that "memberVariable" is not used anywhere else but "DoA()" and "DoB()".

private bool memberVariable = false;

public void MainFunction()
{
DoA();
DoB();
}

private void DoA()
{
// do some stuff

if(something)
memberVariable = true;
else
memberVariable = false;

// maybe do something else
}

private void DoB()
{
// do some stuff

if(memberVariable)
DoOneThing();
else
DoAnother();

// do more stuff
}



Member variables are used for maintaining the state of the particular object. But as can be seen in this case, "memberVariable" does not contain state. It contains a flag that is particular to the logic of "MainFunction()". This is a bad practice because it is very hard to know what "DoB()" is going to do without also examining "DoA()". If this were expanded further and the class had many functions, it would be difficult to know who uses "memberVariable" how and why.

There are a number of ways to refactor this code to change the use of "memberVariable". DoB() could take memberVariable as a parameter or retrieve it's value by calling another function. Even though there are different ways to alleviate the problem, the idea is the same. Functions should be autonomous and not require other functions being executed in order to work properly. And even if a "global" variable is only global to two private functions, it's still global.

Wednesday, August 19, 2009

Don't Arbitrarily Reference the Base Class

 

All too often I have seen developers referencing properties and methods of the base class directly. Instead of calling “this.SomePropertyOrMethod()” or just “SomePropertyOrMethod()” they call “base.SomePropertyOrMethod()”. This has a number of drawbacks.

1) It implies that a class knows something specific about the parent.

2) It is now difficult to override the method in this class or a class that inherits from the current class. The base version of the method will always be called even if the method is overridden.

3) This defeats the purpose of object oriented programming. Calling the base class directly is akin to calling the same method on a utility class. The only difference is that the base class might be looking at the current class’s state. It’s just messy.

4) This is a code smell that makes me think of the Base Bean anti-pattern. “A class should not inherit from another class simply because the parent class contains functionality needed in the subclass.”

Now there are definitely times when this is necessary and that is why the keyword exists in the first place. If I’m overriding Page.OnLoad, I should call base.OnLoad at some point. If I override List<>.Add, I better call base.Add() to add the item to the list.

But just because you can do something doesn’t mean that you should. And this keyword is no different. Most cases of base.SomePropertyOrMethod() should be replaced with this.SomePropertyOrMethod().

Tuesday, August 11, 2009

Maintenance Cost and C# Auto Properties

 

Auto properties in C# provide a simple way to implement a property on a class without explicitly creating the field that the property accessors (get and set) will work on.  There have been many discussions on whether or not auto properties are good, their advantages, and their disadvantages.  Looked at from a code-maintenance perspective, an auto property is much better.

When maintaining code, one big problem is making sure that the code you’re maintaining isn’t doing anything tricky that will make it difficult to modify or fix.  This is one of the reasons why SRP and DRY are so important.  If there’s only one place that does something and that place is only responsible for the one thing that it does, a code maintainer’s life is very joyful.  When this is not the case, a small change or fix may have detrimental repercussions.

With this in mind, there is a maintenance cost to not using auto properties.  If there’s a field hidden under your property, as a maintainer of your code, I now have to check all uses of the field as well as all uses of the property.  With an auto property, the property is the only thing that needs to be investigated.

When explicitly creating a field for a property it is important to consider the costs of doing so.  In addition, it’s important to ask if this field is really necessary.  Can all your methods access the property instead?  If so, why even have this extra level of misdirection.  Chances are YAGNI plays a big part here.