Teaching good software design

Three years ago, I was asked by one of our teams to give advice on how they should write a parser for a structured file format. Just having read up on SAX again, I recommended that they looked into designing it as a push parser. A push parser works by the design that the parser generates events each times it reads parts of the input. These events are sent to an event handler, which then builds up the internal object structure or whatever the program needs. A push parser is a very object-oriented approach to parsing.

About a year ago, I took over the reigns, as it were, on this project. The strategy I had recommended had resulted in a horrible design. After having spent a total of a few weeks to fix issues with it, I finally gave up and rewrote it as a simple procedural parser. The rewrite took me three days plus about a day of fixing some edge case bugs. The resulting code was a tenth the size of the push parser.

This leads to my dilemma: As a senior professional, what should I do when I’m asked to give advice on software design?

Object-oriented programming holds the promise that technical people not involved in a project can understand the code in the project by understanding the structure. In my experience, this often leads to the disease of architecturitis.

Architecturitis is the state of a program where important-seeming elements of the system are needlessly separated out from the rest, either as objects, or as distributed components. The result is that the program as a whole is less coherent. In order to understand what the program actually does, a programmer will have to understand many separate pieces with lots of plumbing between them.

My temptation in order to avoid architecturitis is to say “just do what seems best to you”. This answer is also a non-starter. This sort of advice is useful for people who have lots of experience, but haven’t learned to trust themselves yet. But to those who feel lost at sea, something more substantial is needed.

For the longest time, I thought that testing was the way to go. But writing good tests is really hard, and it’s a skill that doesn’t come natural to developers. Without the sufficient understanding and experience with testing, the advice to “start by writing the tests” will just result in developers not doing anything at all, or, perhaps worse, write tests that make the program harder to change.

“Write tests first” is no magic bullet. But unlike the path of “architecturitis”, I know what to look for and point out in good tests. And I know how to practice getting better. Practice, then is key to learning. Hardly ground shaking. But in the software profession, we set aside very little time to practice. “Learn on the job” is supposed to be the only form of practice.

Writing good code is a long path, and the practice of writing tests first provides a set of goal posts along this path.

About Johannes Brodwall

Johannes is Principal Software Engineer in SopraSteria. In his spare time he likes to coach teams and developers on better coding, collaboration, planning and product understanding.
This entry was posted in Software Development. Bookmark the permalink.
  • Being new to the term I had a good laugh; you just nailed it. It seems somewhat related to aesthetiritis, where a programmer (probably one new to, and sold on, Ruby on Rails) is so obsessed with making his code “beautiful” that it becomes totally ungraspable.

  • Being new to the term I had a good laugh; you just nailed it. It seems somewhat related to aesthetiritis, where a programmer (probably one new to, and sold on, Ruby on Rails) is so obsessed with making his code “beautiful” that it becomes totally ungraspable.

  • Eivind

    There are a lot of deseases out there, for example architecturitis, analysis paralysis and big design up-front, just to mention a three. And why not add object-orientation itself to the list? It is much like eating and drinking, it may give you a lot of pleasure, but abused, it often results in a lot of pain. But that doesn't mean that we should stop doing it, does it?

    I think a keyword you mention here is “needlessly”. I use to teach that if you don't possess the modelling and abstraction capacity required for doing good object-orientation, you'd better stick to the plain, old, structured way of thinkink. At least, that gives you something that is working in the short term, although perhaps not as modifyable in the future. Object-orientation and architectures are good for managing changes. At the same time, changeability implies complexity, so they ought to be kept at a minimum. In fact, we may make everything changeable, at the price of making is so complex that it is not changeable any more. That, may be, is a good definition of architecturitis.

  • Eivind

    There are a lot of deseases out there, for example architecturitis, analysis paralysis and big design up-front, just to mention a three. And why not add object-orientation itself to the list? It is much like eating and drinking, it may give you a lot of pleasure, but abused, it often results in a lot of pain. But that doesn’t mean that we should stop doing it, does it?

    I think a keyword you mention here is “needlessly”. I use to teach that if you don’t possess the modelling and abstraction capacity required for doing good object-orientation, you’d better stick to the plain, old, structured way of thinkink. At least, that gives you something that is working in the short term, although perhaps not as modifyable in the future. Object-orientation and architectures are good for managing changes. At the same time, changeability implies complexity, so they ought to be kept at a minimum. In fact, we may make everything changeable, at the price of making is so complex that it is not changeable any more. That, may be, is a good definition of architecturitis.

  • Hi, Eivind

    Thanks for another insightful comment. As you say: We shouldn't stop doing object-orientation. My experience is that I should only stop recommending that others choose object-oriented solutions when asked for my input.

    Trying to force people to use object-orientation (or testing for that matter) without proper understanding is probably not a good idea. With teaching tests, at least I know what to point to as good examples that won't lead people astray. With OO… not so much.

  • Hi, Eivind

    Thanks for another insightful comment. As you say: We shouldn’t stop doing object-orientation. My experience is that I should only stop recommending that others choose object-oriented solutions when asked for my input.

    Trying to force people to use object-orientation (or testing for that matter) without proper understanding is probably not a good idea. With teaching tests, at least I know what to point to as good examples that won’t lead people astray. With OO… not so much.

  • Trond Arve

    One piece of advice that might be useful in most situations is to start learning about your problem domain. Writing tests is a way to start learning. Working with examples you have to think about how your solution is to be designed and used by clients. Of course there are many more ways to learn, like drawing models on a whiteboard, discussing the problem with others or just start hacking. I tend to prefer tests, but I appreciate that testing requires experience and can be a hard path to follow. In any case, giving general advice when you I know the problem well enough often fails.

  • Trond Arve

    A typo at the end, sorry: In any case, giving general advice when I don't know the problem well enough often fails.

  • Trond Arve

    One piece of advice that might be useful in most situations is to start learning about your problem domain. Writing tests is a way to start learning. Working with examples you have to think about how your solution is to be designed and used by clients. Of course there are many more ways to learn, like drawing models on a whiteboard, discussing the problem with others or just start hacking. I tend to prefer tests, but I appreciate that testing requires experience and can be a hard path to follow. In any case, giving general advice when you I know the problem well enough often fails.

  • Trond Arve

    A typo at the end, sorry: In any case, giving general advice when I don’t know the problem well enough often fails.

  • Designing usable software is difficult, and teaching others how to do it is worse! Although useful methodologies exist, it is not possible to teach someone simply “how to do it”. To be capable of doing more than producing Microsoft clones, student designers need a broader approach to the task, one that has important attitudinal, aesthetic and creative components.

  • Designing usable software is difficult, and teaching others how to do it is worse! Although useful methodologies exist, it is not possible to teach someone simply “how to do it”. To be capable of doing more than producing Microsoft clones, student designers need a broader approach to the task, one that has important attitudinal, aesthetic and creative components.