So, I’ve been thinking to myself about the kinds of posts that I want to make, here, and one of the thoughts that I’ve been rolling around in my head relates to simple design.
I’m a huge believer in the idea of simple design. Especially in the idea that Big Upfront Design doesn’t help a project. Here’s one of my favourite blurbs on this topic, from Kent Beck:
“ When we program, we are always engaged in a struggle to truly see. If we see clearly — what the users want, need, and fear; what our co-workers want, need, and fear; what we ourselves want, need, and fear; and finally what the system wants and needs (damn good thing computers can’t fear!) — we work well and truly. Our systems are simple. Our thoughts are simple. We work without stress, without fear, with joy and love for our task and ourselves.
Visions of objects screw this entire process into the ground. When you already see the illusion of objects, you stop seeing everything that could tell you that you were wrong. The cases where our visions came true only exacerbate the problem, as we make the vision the goal, not the system.
Because envisioning feels good. It brings many of the good feelings that really programming brings, but it can’t crash. So people pursue visions instead of code (lots of design before you code), and visions of visions instead of code (lots of object oriented analysis), and the worst of all are those who pursue visions of visions of visions instead of code (the methodologists).
But here’s the thing. Sometimes, when I’m talking about good design principles, like avoiding package cycles, I wonder: does simple design suggest that I shouldn’t worry about those things? Should I let the packages evolve into whatever state they want to be in?
I think I’ve pretty much convinced myself that there’s a difference between a Big Upfront Design, and a set of design principles. The original C2 Wikihas a page about good design: what makes good design? They talk about some abstract principles, like decoupling and design patterns and “proper” refactoring.
But here’s the thing: some programmers are very familiar with good design principles and some just aren’t. There’s a saying that good judgement comes from experience and experience comes from bad judgement. Some developers will implement a code smellthat will be immediately obvious to other developers. (Take a look at the code smell link, and look at how many design principles that they talk about).
I think that this is one of the reasons that several organizations are seduced by big, design-heavy methodologies (*cough*RUP*cough*). In essence, they want to divide their programmers into two groups: those who can be trusted to make smart decisions and those who can’t. The first group tells the latter group what to do, and the latter group does it.
I have any number of reasons to believe that that strategy doesn’t really work out so well. But if you accept the fact that some people don’t make good design decisions, what can you do about it?
Part of the answer might be to have a good metaphor or architecture seed. Part of the answer is more Pair Programming. And part of the answer might be unit tests designed to discover code smells.