24.9.2006
Sometimes programming means simply: you want your software to do some
job, you write some code which does that job (maybe you do a bit of testing
and debugging, all right), and that's it. This is sometimes fun, and
sometimes it's not, but at least it is straightforward programming.
And then there is what I call indirect programming.
This happens when you use a framework or library in your software, and
you reach the point when you want your software to do some job that is not
a supported standard case in that framework or library. Of course, you have
by now a lot of code that uses that library, and anyway choosing that library
has saved a lot of work so far. So you are not inclined to eliminate the
library from your software, you just devise a little workaround for that
special job that you want it to perform right now. Congratulations, you've
just started indirect programming.
Indirect programming is when you write some code that doesn't actually
do something itself, but is just there to trick some framework into doing
something, typically (as in the example above) something that is not a
standard case from the point of view of that framework.
And since you got along with it this time, at the next occasion when you
are in a similar situation, your inclination to throw out that framework is
even weaker - so you put another little workaround into your software, and
thus you do more indirect programming. And so on.
After a while, this gets frustrating. Nobody likes to do indirect
programming all the time, but I have experienced projects that did little
else from some stage on. Apart from the lack of fun, indirect programming is
dramatically error-prone. Putting in some lines of code that obviously 'don't
do anything' makes it highly probably that at some later time another
developer just 'cleans' them away. Sure, you can leave a comment at that
code, but more often than not this gets out of sync, or is just not
understood by someone else (who does not know the context as well as you
knew it in that very moment when you thought up the workaround).
Of course, from this it does not follow that one should never use
libraries or frameworks in a software project. It is obvious that one
should check that the libraries one uses support all the things one wants
from them; but requirements change, and there is no way to know all of them
in advance. This means that the need for indirect programming cannot be
completely eliminated (and one shouldn't be too paranoid in these matters,
too.)
What can be done, though, is not to underestimate the cost of indirect
programming. Especially that sort of frameworks which promise to 'save
programming work' should be examined closely. I've never seen any one of
those which did not, sooner or later in a project, cause a huge amount of
indirect programming. These frameworks would let you, for instance,
'declaratively' specify your UI, without the need to write one line of code.
Great. But then some requirements emerged for parts of the UI that were not
supported in the framework. Or something simply didn't work as expected. And
a long, exhausting debugging orgy started - merely to find out what actually
happened in the system. And after that (you guessed already) some indirect
programming technique was applied to make it work. In some projects that I
have seen, my suspicion was that the costs of these were even higher than
the costs would have been if the great framework would have been left out of
the game and the whole stuff would have been coded directly. But admittedly,
that were extreme cases, and to be fair, perhaps in many cases such
frameworks do indeed save money (in the form of reduced programming costs).
But they produce bad-quality software and make work on the projects less
attractive - because of the amount of indirect programming that is
involved. So, if the motivation of your development team and the quality of
your software matters to you, you should give that aspect some
consideration.