I’m sure I’m not the first to have thought of this, I probably read it somewhere a long time ago.
But it occured to me the other day that much of good software design lies in figuring out the simplest possible way to achieve your task in code. Even when what you want to accomplish is complex, your task is to figure out a simple software architecture to accomplish it.
In fact, that applies to user interface design too. And perhaps to the field of ‘design‘ in general.
It’s part of what makes computer programming an ‘art’. It’s definitely something I get better at the more experience writing software I have (and the more exposure to well-written software — I think it’s very important that a computer programmer’s self-education include working with well-designed code by someone else. One key experience I had in developing this kind of design intuition/skill was working with Apple (nee NeXT) WebObjects).
One the reasons that figuring out a simple implementation is important is it’s the only way to get maintainable, extendible, more or less bug free code. (Yes, simple means ‘extendible’ — simple doesn’t mean stupid, it means an elegant answer to a complex flexible use case. Beautiful code.) Sure, unit tests are important for bug free too, but your unit tests are going to be a nightmare if your code is a bunch of spaghetti. Well designed (meaning simple) code means simple unit tests too.
I used to think my job as a programmer was to implement whatever the customer asked for. If it could be described algorithmically, it could hypothetically be turned into a computer program, and I thought my job was to turn any requirements into an algorithm, and get it implemented. I knew I was a good enough programmer to implement anything if I could describe it algorithmically.
But lately, I’ve started saying ‘no’ when I can’t figure out a simple way to implement it. A giant tree of complicated if/else logic fitted precisely to various classes of bizarre edge cases we run into (especially in our library data!) is not simple. It’s going to be a nightmare to maintain, no future programmers are going to understand what it does, even I’m not going to understand what it does. Sometimes you just have to say no, while I can do that, doing it the only way I can think of to do it will not serve the long-term interests of anyone who wants this code to continue to work.
But of course, the better you get at software design, the better you get at figuring out simple solutions. Sometimes something I initially say ‘no’ to, later an answer pops into my head, oh that’s a nice solution to that problem, I can do that!
And, ps, that is the point of “design patterns.” To give you a cookbook of simple solutions to complex problems. So you don’t have to be a code guru to find the simple solutions, and to help you become a code guru by learning the patterns beyond the patterns (meta-patterns! Which are still mostly an intuitive thing). When people (ab)use “design patterns” to make what should be simple complex instead (certain parts of Java community, I’m looking at you), they give them a bad name. WebObjects is full of well-used design patterns. So is Rails.