This blog contains reflections and thoughts on my work as a software engineer

onsdag den 18. juni 2008

The infamous Save() method

We (a collegue and myself) had a little infight a few days ago during a pairprogramming session - I advocated for having all Save() methods being void and parameterless whereas he didn't see any problems in having them returning objects and/or taking input parameters at will.

I couldn't at that time argue my case except that I saw this as a violation of the SoC (Separation of Concerns) principle - and why force the consumer to handle a return value if the consumer doesn't need to have one? The discussion grew a little ugly at some point but yesterday just before leaving the office we talked it over again.

It turned out that my collegue's experienced with TDD for various reasons has not been overly positive - having to figure TDD out for yourself without having some sort of experienced mentor inhouse will lead to frustration in 95% of all cases once you try to use TDD in a real-world scenario. We argued about having a signature of Save() methods in general and I understood my own reservations when we discussed what would happen once the signature of the Save() method changed because we i.e. wanted to introduce a new parameter in a call to Save() - example:

public void Save(string a, string b, int c)
{ ... }

was to be extended with:

public void Save(string a, string b, int c, List d)
{ ... }

What happened in his mind was that the compiler would burp on all places where the Save(a, b, c) was used so you had to change the code of your tests in all places.

What happened in my mind was that you had to change all working tests using the infamous Save() method because you changed a single signature of a method. This is bad because

1: The time spent maintaining your tests should be kept at a minimum
2: You could be mislead to work around changes in your model to avoid having to alter your tests to reflect that change - and THAT should ring the alarmbell.

1: Having simple method signatures should be a goal in itself to avoid breaking the code of your tests when you want to introduce new functionality and parameters which needs to be carried around in your application.

2: Do use objects to carry around parameters for you. Less code is needed and the readability of your code is much higher. Having i.e. an object carrying 10 primitives around your model is much more extensible than having to extend every class with a property for param #11.

You should not be afraid of having "dead" objects in your model and view which can only contain data. They are keeping the numbers of properties and overloaded methods in your application to a minimum :o)

Related articles:

TDD antipatterns (I don't agree to every one of these but it is a good checklist)

This guy suggests best-practises for API design:
How to design good API's

Ingen kommentarer: