Archive for category best practice

I Have a Dream

The usual suspects

Whenever I’m presenting anything, I try to start off showing the “Top 20 replies from a programmer when their programs doesn’t work”. In case you’ve never seen it, here it is:

  1. It works on my machine.
  2. Where were you when the program blew up?
  3. Why do you want to do it that way?
  4. You can’t use that version on your system.
  5. Even though it doesn’t work, how does it feel?
  6. Did you check for a virus on your system?
  7. Somebody must have changed my code.
  8. It works, but it hasn’t been tested.
  9. THIS can’t be the source of THAT.
  10. I can’t test everything!
  11. It’s just some unlucky coincidence.
  12. You must have the wrong version.
  13. I haven’t touched that module in weeks!
  14. There is something funky in your data.
  15. What did you type in wrong to get it to crash?
  16. It must be a hardware problem.
  17. How is that possible?
  18. It worked yesterday.
  19. It’s never done that before.
  20. That’s weird…

I’m not quite sure who wrote it originally, but I was given a paper copy several years ago. I must admit I had a good laugh at the time, as I could relate to most of the replies.

So whenever I’m presenting this list, there’s a giggle and a great deal of nodding and smiling going on in the audience. Then I go on to present something that will alleviate one or more items in this list.

But it’s not a laughing matter! It’s the sad state of our beloved profession we’re laughing at. It’s not supposed to be like this.

The Dream

When I’m presenting the list in 10 years from now, there’s not a giggle. Not a smile. Just silent shame of times past or loud laughter at good ol’ days. Hopefully no one doesn’t even recognize the items on the list.

I might have a different kind of list. But not this one. We have made progress.

What to do next

So I propose this list as the metric for how mature your development organization is. Same rules apply as in the wtf code review metric. Less is better. Drop the Joel test. Drop the Nokia test. Drop test X. Use this. Now!

The worst part of this is that most of these are solved problems. Test Driven Development, Continuous Integration, and Pair Programming have existed a decade. Their poorer, but still useful cousins, Unit Testing, Automatic Builds, and Code Reviews have been around the block even longer. Iterative and Incremental development, Miniature Milestones, and Review and Adapt has been grown ups for a while as well.

So there is no excuse. The answers are at your doorstep. But it takes discipline. And time.

But you’re not alone. I’m off trying to do my part. Our mission is clear. Will you do yours?

No Comments

Get those Guards up

I often find code which have several nested conditionals like this:

public void FunctionWithoutGuardClauses(Person person)

{

    if (person != null)

    {

        if (person.Phone != null)

        {

            person.Phone.Call();

        }

        else

        {

            throw new ArgumentNullException();

        }

    }

    else

    {

        throw new ArgumentNullException();

    }

}knight4

According to Steve McConnell in Code Complete 2 it is just fine with regards to putting the most probable clause first. But it is also an anti-pattern in this case; arrow code. With even more nesting it gets worse, and it starts to get nightmarish to follow the possible execution paths.

Oh, and see how I blatantly disregard the Law of Demeter!

Introducing Guard Clauses

A guard clause is a conditional which constitutes our first line of defence in our methods. It can break control flow in an elegant matter, so the only thing left to follow is the valid execution path.

There is also nothing wrong with more than one return path in our methods, as long as it is as clean as it gets with guard clauses. Atwood seems to think so as well, so I’m really home safe here ;-p

So lets see how the above code can be refactored with guard clauses:

public void FunctionWithGuardClauses(Person person)

{

    if (person == null || person.Phone == null)

        throw new ArgumentNullException();

 

    person.Phone.Call();

}

So what are you waiting for, get those guards up and tear those nested nightmares apart!

No Comments

.Net Collection<T> vs. List<T>

Recently, we have gotten a couple of “fresh out of school” employees, and here the other day we went through the code of one of our applications and explained how it was built (at least how was supposed to be or “do as I tell you, don’t do as I do”).

Our O/R-mapper returns a generic Collection<T> when it is asked for a list / collection of some objects, and is consistent in doing so. The question however, was why that wasn’t a List<T>.

I had to admit I hadn’t dug into the material properly, so the question kindof got left there in open air. My bad excuse was of course I had been mostly doing managment stuff lately, and so was my companion presenter as well.

So to make a not so long story short, I had to dig into the collections that is found in .NET, and I explain them to myself for later reference, beginning with the aforementioned Collection<T> and List<T>.

The difference

Just to sum it up, Collection<T> is made for extensibility and List<T> is made for performance. See this and this from the FxCop guys.

For a full blown explanation, a great reference is also found here.

Use List<T> for all your heavy lifting internally, and expose a Collection<T> in your public API.

4 Comments

Allways qualify your insert statements

An absolute rule for your database insert scripts and stored procedures should be to qualify all field names.

An example could be the following schema:

image

Where you would have a script saying:

INSERT INTO FAMILY VALUES ('Bob','Dolly','Bill')



Then, you could see the disaster inserting a new field named Girlfriend in between You and your Mom (in more than one way :-) ).

Then you have a schema like this:

image

Suddenly after your next insert your Girlfriend is your Mom, and your Dad is your Mom!

Well, the one solution to rectify this mess is of course guiding your values into the correct fields like this:

INSERT INTO FAMILY (You,Girlfriend,Mom,Dad)  

VALUES ('Bob','Julia','Dolly','Bill')



The rationale is then as follows:

  • This will assure that if you have changed the schema ie. moved or inserted new fields, the script will not fail or most importantly it will not insert data in the wrong fields.
  • It will fail if you have removed or replaced fields which assures that you will not get corrupted data from these changes either.

No Comments