I don’t claim to be an expert in software design, but I think I’ve learned a few things over the years. As I’ve wrestled with a few problems recently, I began to think about the approach that I generally take to the process of design. It’s influenced by books I’ve read, multiple projects that I’ve been involved in, and some of my gut feelings. You may agree or disagree, but I felt it would be good, even just for myself, to write down the tenets that I’ve come to regard as core to my design approach.
1. Step away from the computer
Seriously. I’ve used a lot of modelling tools over the years, from early entity relationship diagram tools, through the birth of UML (I rejoiced when the ‘3 Amigos’ finally decided to unify their notation), through to integrated round-trip engineering tools these days, and whilst they are very clever, and are great for recording and communicating a detailed design, but they are manifestly damaging when it comes to early stage conceptual design. Some people leap right into those tools as soon as they have a new problem to solve, and that scares me. These tools encourage you to think about detail and layout way too early, and lengthen the process of iterative high-level design purely because everything is so formalised. When you’ve put a lot of effort into documenting an embryonic design in detail in one of these tools, you don’t want to lose that effort, so you are less likely to trash it if it starts to look inappropriate. Plus it takes you longer to find that out because you spend too long driving the tool the way it wants to be driven (all those features cry out to be used). You might think that you can be strong enough not to be tempted by that, but even subconsciusly there’s going to be a little voice on your shoulder saying ‘you just spent 3 hours on that, surely you don’t want to toss it all away?’.
Your best conceptual design friend is a stack of paper (preferably recycled or, in my case, the backs of unwanted printouts), a HB pencil and a stout eraser. Oh, and a large paper bin, you’ll need that. There is nothing, absolutely nothing, faster for conceptual design than this, and I seriously doubt there ever will be, until of coruse they invent direct neural downloads. You’ll blast through ideas fast, you can link them up however you like, spatially arrange them, and easily discard them without feeling you’ve wasted too much time. Everything you do is exploration and requires no more effort than it merits.
So, don’t believe the hype from people trying to sell you design tools. Design is about what humans do best – deciding how best to tackle problems given a potentially abstract set of environmental conditions. The only tools you need are those that help you explore that, and the simpler the better. Get complex once you’ve decided on the approach by all means, but do that any earlier and it’s just slowing you down, and make doing the other things in this list harder.
2. Look at any problem from multiple directions
Don’t just think of a feature from the perspective of how you want to use it now; study trends and decide how it might be used in the future, or what else you might use it for given a moderate conceptual twist. You can’t predict everything, but anticipating change and alternate usages will give you a better chance of picking a holistic approach, where your current intended usage is just a facet of a greater, more generalised implementation.
3. Look for patterns
Almost every software engineering problem has been encountered before, in some guise or another. That means other people have already put a lot of thought into approaches (which may or may not be appropriate for your needs). Don’t come up with your own solution before exploring these, at the very least they may influence your eventual solution if you’re in the rare situation where none already exists.
This is one situation where being at the computer may help, if you don’t have a good grasp of a good number of design patterns already, and don’t have a good library on the subject. However, there is no tool that I’m aware of that can suggest a pattern for you, since drawing parallels with other data sets and pattern matching is something humans do very well, but machines very much less so. Also, blind internet searching can lead you astray, ince using patterns without appropriate context can be worse than not using them at all – every pattern comes with a set of parameters and suitability conditions that you really have to have a good grasp of. Your best bet is to read all the time – books like the Gang of Four, online articles etc, and re-read them regularly to keep them in your head so that you’re more likely to spot an appropriate pattern when you see it.
4. Always document your reasons for a design choice
There’s no such thing as a perfect design, every design is a series of compromises based on the goals and constraints in each problem domain. Being explicit about your reasons for choosing one approach over another allows you to evaluate alternative approaches long after your mind has exited ‘the zone’ on this particular issue.
5. Ruthlessly define scope
Knowing where your boundaries are is one of the most important things in design. If a designer can’t tell you where their system ‘ends’, or imply that it does ‘everything’, then they should be very worried. If you can’t define what’s inside, and just as importantly what’s outside your scope, how on earth are you ever going know when you’re finished, or whether a feature belongs in your system or whether it belongs somewhere else? You can’t.
You absolutely must be able to draw a clean, unambiguous box around any system you design. That’s because every system in the world has to interact with other systems, and that box represents the interface points – anything going in or out of that system boundary needs an interface, and that’s one of the most important aspects of the design; many systems will live or die by how well they can be integrated with other systems. If you can’t clearly define what’s ‘inside’ and what’s ‘outside’ that box, you can’t possibly define the line that describes it, which means you can’t define consistent interfaces. What you end up with is a bleeding, feature-creeping system with ad-hoc integration points without any holistic design behind it. If you’ve ever had to integrate with a system that feels like that, you have my sympathies.
6. Plan for change, but realise your limits
We all know that nothing stands still. That means we should try to design things flexibly so that they accept change readily. Using approaches like data-driven design, good abstraction of discrete concepts, dynamically customisable code (e.g. plugins) all help achieve that goal and are nearly always a good thing. But, you have to draw the line somewhere – there will be times when you have to make assumptions. That’s fine, so long as those assumptions are documented, and preferably they sit on your ’scope boundary’ – ie in your original scope definition you said you would allow for ‘x’, and no more (see previous point). Sometimes, you just have to stop somewhere, stick a flag in, and move on to something else.
Why not try to plan for all change? Well, you can’t, and your efforts in this area will yield diminishing returns. Change within a strongly cenceived scope is a good idea, but beyond that scope you should deal with change through refactoring, should you need to. Hopefully your scope is defined clearly enough that you can draw that line in the sand unambiguously (again, see previous point).
7. Don’t be afraid to change your mind
Being wrong is fine, so long as you’re willing to realise and embrace it. Be aware that design is an optimisation process, and is often iterative – you’re trying to find the most appropriate design for the problem at hand, within the time constraints you have available. This means that even your best design may only be a local minimum; there may be other solutions which fit your needs better that are just over the next ‘bump’, you just might not be able to see them yet.
The previous points I’ve made are all in support of this point. Never assume you’ve got the best design yet, because you probably haven’t. Keeping agile in your design process (point 1), being as open-minded as possible (point 2), looking for accepted wisdom (point 3), putting a stake in the ground when you’ve made a particular choice (point 4), and knowing your scope for change (points 5 and 6) will all help you reflect when a potentially better option becomes available.
Maybe that’s given you a little insight into the way I go about design from a high level. Maybe not, or maybe you don’t care
But there it is anyway.









July 9th, 2006 at 10:43 pm
Good read, Steve.
July 9th, 2006 at 10:49 pm
Just what I needed really, my design is terrible. There comes a point in programming (relatively early on) when you realise that you can overcome any programming problem if you approach it correctly and give it some time – however, designing components or even the entire application is something of an art I’ve found. I’ve still yet to get a good book on design to really research it. Patterns are something of a mystery to me still, I’ve played with one or two and found them extremely useful, but I don’t understand them just yet.
I agree on the pen and paper ideal, I’ve found tools useful for design but nothing beats good ol’ paper. Perhaps if you had to publish your designs or hand them to someone else in an understandable format (if you’ve got bad handwriting that is, and seeing as though we’re “geeks” I find it’s rare that I use my hand to do anything other than type sometimes).
The interesting design solutions I’ve come up with usually require some level of dependance. For example, if I was going to write an object reaction system as I had mentioned, I would have to be able to check that I’m in proximity of somewhere thus using SphereSceneQuery. If I really wanted portability of that particular component I obviously wouldn’t be able to use that particular feature on another graphics engine and therefore it would require some insight into making sure it’s cross-platform compliant.
Perhaps being a chess player helps with seeing things from all angles?
July 10th, 2006 at 1:18 am
Steve Streeting on Software Design…
…
July 10th, 2006 at 3:38 am
Good read
July 10th, 2006 at 7:53 am
All your points are good.
I would just make a comment about the first one: it is too focused on one programer. If you need to make a collaborative project from the start, you can think the design on paper. But IMO you need to quickly make some uml to exchange and reach an agreement with the others programers. For that uml is good.
That said you are right that you must not lose your self in overdesign/overdocumentation. Only concentrate on a few (max 10) uml diagram: classes, deployment and a few sequences diagram is enough to make a team work in the same direction.
July 10th, 2006 at 8:17 am
@Steven: I’ve done quite a lot of collaborative design actually (at work the major projects I’ve worked on have had up to 4 designers at once, plus a good number of regular coders on top of that), and my point still stands. If you conceive the design alone then talk about it, take your paper notes into the meeting and scribble them on a whiteboard. If the design is collaborative from the off, use the whiteboard directly. I still say that getting into the UML tool too early is a distraction.
For more detailed design and formal reviews, fine, I agree. My point was that leaping into the UML tool before you’ve got a skeleton conceptual design slows you down, because the most important thing is to quickly evaluate and discard / refine as many ideas as possible, and that applies just as much for colloborative design, since it’s much, much faster to bash through things with colleagues on a whiteboard or scribbling on some shared paper than it is to write up ideas in a UML tool and exchange them.
If you’re distributed remotely the tool can be useful but then you probably still do each conceptual stage locally anyway, since it’s more likely to be a store-and-forward approach than a truly interactive design session.
July 10th, 2006 at 8:49 am
Now I totally agree with you
My mistake: I forgot to explain that I was talking about online project where physical meetings are not possible.
In the oge (not ogre) project, I would love to have such meetings. Without them I use lots of chats but uml diagram are easier when a thousand words are not clear enough.
July 10th, 2006 at 3:15 pm
All good points, but I would add – Express yourself the best way you know how- even with code.
I’m a paper man(and chalk(marker) board man as well) myself, so it’s great to see this under appreciated medium for software design mentioned here.
However, over the past 20 years, there have been times for me where simply writing down thoughts on paper seemed too vague and I couldn’t quite “see” what I was attempting to describe. So, I needed to give it some legs and get out my erector set, my legos, my ball of clay so to speak which for me is just a straight forward, plane jane, bit of programming that gives me a chance to mull over, further shape and thrash around my ideas. I use it as an erasable, disposable canvas so to speak. Artists and musicians do this all the time, they make throw away peices just to help them “feel” their way through a project. I’ve had some neat “ahah” moments doing this where I just couldn’t quite pentrate to that level of thinking on paper. I had to see a few moving parts, a few sprockets and gears, giving it life and breath.
Just my two cents and thanks again for this very well thought out take on software design.
July 10th, 2006 at 8:16 pm
Thanks for the read, all good points. It appears I share your passion for designing using a “stack of paper (preferably recycled or, in my case, the backs of unwanted printouts)” and a pen because that’s what I’ve been doing the last couple of days, and it really works well.
In your next life, when you get the time, you should be writing a book.
July 10th, 2006 at 10:27 pm
I am sure this will be really helpful, design is one of my weak points and the moment. I dont have time to read it now but I will be sure to in the morning. Thanks for taking the time to type it up
.
July 10th, 2006 at 11:39 pm
@DWORD: I absolutely agree! I think Steve is very well spoken, has sound and helpful ideas and could write a great book.
I was a little sad to see he didn’t write the upcoming OGRE book so he could really rake in some profit, but alas he really is too busy.
July 11th, 2006 at 12:21 pm
Thanks chaps
I may eventually write a book of my own, we’ll have to see.