Tuesday 3 February 2009

Perhaps, Perhaps, Perhaps

Pop quiz: To you, what's the most important aspect of writing maintainable code?

Using the right language?
Writing unit tests?
Mercilessly refactoring?
Applying design patterns?

All are important, but in my eye the most important aspects are coupling and cohesion. And yes, I know technically that's two things but they're so tightly coupled (haha!) that really you can count them as one.

If you don't know what either of these are, I suggest you look it up on Wikipedia (and pick up a book or two on writing software). Go on, we'll wait for you. And we promise not to snigger as you leave.

...

Achieving a state of loose coupling and high cohesion is simple really:

  1. If you're writing a method, ensure that it's contributing directly to the goal of the class and think very carefully about what your class is supposed to be doing

  2. Ensure your class only ever does one thing

  3. Work to interfaces, not implementations

Ok, ok, so it's not easy otherwise we wouldn't need to be having this conversation, but that's an article for another day.

Alot of code I've seen, and even been guilty of writing in the past doesn't adhere to these principles and over time turns into a Big Ball of Mud, which if you take a conceptual view of how the system fits together might look something like this...





That's right, just a big box with you having no idea about what's going on. Every piece of code knows about everything other piece of code and it may as well be a behemoth piece of procedural code all stored in the main method accessing global data.

I'm probably being unfair and putting forward an extreme example. This is alot closer to reality....






A system with a massive amount of dependency, and very representative of what you'll typically see in alot of codebases.

What we really want to see is a collection of small, independent pieces of code all working together to replace the “Master Control Program” above...




Hmm, much nicer. And believe it or not, it's achievable.

"But why is this important", I hear you cry?

One word:
Maintenance.

The thing that every developer hates, but every developer has to do*. Writing code is easy. Writing code that you can come back to 6 months later and instantly figure out what was going on in your head is a lot more difficult. What does that 1600 line method actually do? How does it do it? Why does it invoke the Foobatron and send the results through a tea strainer? Highly cohesive, loosely coupled code helps you with this. Even if you can figure it out, how about the next poor schmo who has to come and work with your code? How about when you need to start getting some data from an FTP site instead of directly from disk. It's going to be alot easier when all you need to do is provide a new implementation of a FileRetriever and exchange the dependency than it is to delve in at line 459 of the “readFileParseDataAndUpload” method.

Given a choice between debugging a one million line method or a five line method, which would you choose?

* if you never have to do this, please drop me a line about where I can send you my cv!