Search This Blog

Wednesday, July 9, 2008

Selfish Development

I think one of the main reasons we, as developers, start programming is to express ourselves creatively. It's the creative process that keeps us coming back for more: There is nothing more rewarding than distilling down a seemingly complex problem to a simple solution. This doesn't need to happen in the code first. The reward usually happens much earlier during the discussion about the problem with your team members (fellow developers, analysts, customers etc).

Of course this is true in any field. Oliver Wendell Holmes Jr. (1841 -1935) Once said "I wouldn't give a fig for the simplicity on this side of complexity; I would give my right arm for the simplicity on the far side of complexity". If he was talking about software development, I believe he would be saying that it's not enough to solve the problem. We need to solve problems in ways that other people can understand and use.

As a developer this means writing code that's explicit about your intent. In Bob Martin's words, "The name of a variable, function or class should answer all the big questions. It should tell you why it exists, what it does and how it's used". Eric Meyer sees it as trying to tell as much truth about your intent as possible. You can't tell the whole truth, due to the nature of abstraction, but you must try. Doing so will help you avoid the over abstraction syndrome that plagues source code (Over abstraction occurs when important information is abstracted away too early, requiring the reader to divert down a side path to understand the solution). I'll talk more on this in a coming post as it requires a discussion of encapsulation and cohesion.

So what does this have to do with selfish development? Put simply it is this - If you are worth your money as a developer, your code will be read many times and there's a cost to reading and understanding code. So good code is easy to read and understand. If its easy to read and understand then its more than likely easy to extend. It also needs to be correct in a manner that can be proven when required. This provides confidence to you and those who will use or maintain the code in future. So it needs automated tests and excellent (not good) coverage. With this in mind, team members should avoid writing dirty, untested code under the premise of - "I just need to get something out. We can come back and clean it up later"; or my favorite, "I'll get it working and you can make it pretty". What's actually being said is, "I'm too lazy to do a proper job but I want to enjoy being creative. You can deal with my stuff once it works (do maintenance). Oh and don't ask me to explain how it works. I'm not good at explaining things".

It's of no difference if you're a team of one or many; Pairing or flying solo; It's not done until it works, is testable and understandable.

One of the "tells" of this process is someone who wants to provide a solution in a technology before they understand or have defined the problem (bottom-up programmers): The implementation nuts, who are crazy about the latest api or library out there. It's like a person who needs to hang a picture on the wall. Straight away s/he runs out, grabs a nail and a hammer and starts banging.  Unfortunately, the picture must be hung in a specific area and a reinforced steel girder occupies that area. Our friend keeps banging away, saying "hang on, I've almost got it" ... you can see where this is going.

The alternative is to talk about the problem; Code by intention; top-down; Write the class or function that answers "Wouldn't it be cool if I had an object that did..." and worry about the implementation afterward. While your at it, you might as well test using Test Driven Development (TDD). Doing so requires you to understand the problem you need to solve before you try to solve it with the detail (take a squiz at testing with mocks, interfaces and abstracts). It also allows you to concentrate on defining the problem in an abstract easy to understand way before getting into the noisy detail of exactly what you will use to provide the solution.

My personal experience is that a well defined, high level solution to a problem, written in the conceptual layer, leads to less coupling in your system allowing you to dangle implementation details off you abstractions, one at a time. For complex systems, it's much easier to understand a small bit of implementation detail, trusting that the system is correctly communicating among its components to solve the greater problem, than to think of everything at once (the details and how its going to communicate with other parts of the system).

I've worked with people who have criticized other developers because they talk about the problem too much before putting something down. Personally, I like these guys, they use the best computer, our brains, which are largely configured to quickly compile and optimise language, before proceeding to the more expensive writing of code. Refactoring helps but is no match for an open discussion about the problem and how to simplify it among people.

One further comment: I was careful in my post to use developer and programmer in specific places. I believe a programmer is someone who knows how to solve a problem with a given language or api without regard for the true elegance required in a well designed system that is very easy to understand and change. A developer is something again. S/he is someone who is considerate to the users of the code base, customers and other developers. In doing so, they seek clarity of intent and elegance in design of a maintainable system. They have values (I'll rant about this in a future post), principles and tested practices. They can justify their values and principles and constantly test their practices. aahhh, this is getting a little to zen.

Stepping down from my high horse: Before I was a developer, I was a programmer. I've been guilty of everything I've spoken of in the negative. I try to improve the readabilty of my code, with every line I write, leaving in a better state than I found it. My success varies, but over time I'm improving ... I have a long way to go. I would appreciate your comment.