What I’d Tell Myself About Design If I Were Just Beginning
by Chris Wash on Jul.29, 2009, under Meta/Blog, Software Engineering
The competent programmer is fully aware of the strictly limited size of his (or her) own skull; therefore he (or she) approaches the programming task in full humility, and among other things he (or she) avoids clever tricks like the plague.
–E.W. Dijkstra
Designers are something of an enigma to most people; however, the fruits of their labor are largely understood, well used and appreciated. Design is often considered to be a purely aesthetic matter: a matter of taste, of style, of opinion; we know a good design when it when we see it. But many times we can’t quite put our thumb on why it’s good design, or what makes it well-thought out, or pleasing. Maybe some of us can articulate what it is we like about design, but few connect the dots enough to notice recurring qualities in our favorite designs or think about underlying truths beneath those qualities. Even fewer still have the experience to know when to apply these qualities, within the proper context to produce a good design.
Programmers are equally if not more engimatic to general society. Perhaps on the surface for many different reasons. But, coincidentally developers are designing all the time; could this play a part, perhaps? Is this why we refer to the most experienced of our profession as “architects?” Aren’t we, by way of programming systems and wiring them together, inherently striving for greatness as designers?
Especially when you’re inexperienced, you’re very much focused on learning what it is about a design that you find compelling, agreeable, or pleasing. We value a good design so much that we spend a lot of time studying, talking about and debating what makes a good design. As the narrator (Jack?) in Fight Club admits he had become “a slave to the IKEA nesting instinct,” so too, I find myself in willing servitude of the design pattern instinct at times. More often nowadays I stop and catch myself, and I’d like to think I’m not the only one with this premonition. Too quick are we to whip out our design patterns books (especially right after we’ve finished them) and, as the first order of business, go to town solving problems we don’t have.
Few products today need to ship in shrink wrapped boxes as they once traditionally had to. The connectedness of the Internet, coupled with all of the modern advances in hardware have fundamentally changed the way we look at developing software. “Fast, cheap, good – pick any two” still applies, but fast is faster, cheap is a lot cheaper, and good encompasses much more today than ever before. Software development still lags behind.
The unwise developer makes all design decisions up front, for fear of getting the solution wrong. The enlightened developer creates the closest thing to a working solution now, for fear of getting the solution wrong. The former produces a solution that fits his view of the problem. The later continually adapts his solution to encompass others’ view of the problem. Which is more valuable? The unwise developer wants to be done, and will sacrifice alienating some users. The enlightened developer wants to be correct, and will compromise stability of the design. Why do this? Because inactivity leads to software rot, and we have techniques for dealing with changing designs. What good are our big up-front design skills when the requirements change?
Like Darwin encouraged us to do with our views of biology, we’ve ditched an up-front design model for an evolutionary one. There is increasingly a focus on software as an evolutionary process everywhere, and it’s phrased in many ways: continuous production (Cal Henderson’s explanation the best); the perpetual beta; “no such thing as done“, agility – openness and responsiveness to change. The risk of bloated software has lead us down a path to focus on and seek to create small, modular applications that create “business” value immediately, can be chained together but never grow overly complex. Our design decisions still exist, but they are on a much smaller scale, and with much more concrete drivers and concerns factored in. And we understand that we’re fundamentally in error when we make them out-of-context.
Others have thoroughly dealt with this topic in much greater detail than I can or care to. Neal Ford has written about what Evolutionary Architecture and Emergent Design look like. Martin Fowler has asked, “Is Design Dead?” and answered his own question. I would encourage you to read their thoughts on the matter, as my own conclusions are largely in line with theirs.
That being said, there are some tools that you should look to add to your collection as you go. Any craftsman must learn to master his or her tools. Just having the tool in your toolbox does not necessarily make you a good designer; because they must be used properly, in the proper context. Like Clint Eastwood’s character explains of his toolkit in Gran Turino: each tool has a job, its own context and realm of applicability. Also, resist the urge to apply them every chance you get. Much of good design is about restraint. Try to see them applied correctly, or incorrectly, and talk with others about it. Keep a conversation going; don’t allow your codebase to become stagnant. Continually question, strike the right balance and good designs will emerge and bad designs will improve. Your methodology may have you delivering in sprints, but good design is a marathon.
Here are the basic tools. There is a lot of material out there on these – easy to Google or find on Wikipedia. I am not going to offer any links or speculation, because I think these things should continually be discussed. You should be constantly evolving your own opinions and knowledge of them. They must be used, discussed and understood in order to be mastered.
Overarching Computing Principles – Reduce Complexity
- KISS – Keep it Simple, Stupid.
- DRY – Don’t Repeat Yourself.
- YAGNI – You Ain’t Gonna Need It.
- SOC – Separation of Concerns.
Basic OO Principles
- Inheritence
- Coupling/Cohesion (dependency)
- Encapsulation
- Modularity
- Abstraction
- Polymorphism
SOLID (Advanced) OO Principles
- Single Responsibility Principle
- Open/Closed Principle
- Liskov Substitution Principle
- Interface Segregation Principle
- Dependency Inversion Principle
Emergent Design Techniques
- Test Driven Development
- Continuous Integration
- Refactoring
- Project Automation
- Continuous Production
To borrow a great closing quote from Brian Liles,
Do not seek to follow in the footsteps of the wise. Seek what they sought.
–Matsuo Basho

July 30th, 2009 on 10:03 am
Well thought out, and good summary of the current movement in software development. So what were your final key items that you would want to remember if you lost everything else? I think your final list is good, but I’d also add:
Read everything you can first, and read as much of other people’s code as you can first, and then go back and re-read all of the design books again. Distill down to the essence, and then begin.
Thanks for the post!
July 30th, 2009 on 10:12 am
Enjoyed reading this because while I enjoyed learning the fundamental theory of developing in college there was never enough time to delve in-depth into what’s really important; how you craft your solution. (Like most kids overloaded with work I just did what would get me the good grade.)
I think even though we have all these resources to learn great design I agree it’s something that has to continually be talked about because no one does the same thing the same way all the time and it’s easy to get stuck in something you find works “most” of the time.
I’ll stop before I get too philosophical.
July 30th, 2009 on 12:17 pm
@Mr. Hericus -
Thanks for your comment – As far as the final key items, I guess my point was a little too subtle: it was the post itself, with all of its musings and seemingly tangential concepts. I would want myself to just read this post and take from it what I would. I don’t think I’d necessarily want to read everything I’ve got my hands on because much of it is written from the perspective that BUFD is a given. I’m not so sure I’d want to spend time rereading a lot of that stuff. Definitely the things I’ve linked into the post I’d like to keep (and there are some great links in those links as well) – and I agree that there would be a lot to read. But by and large I’d want to remember to focus on design as an attitude or state of mind, rather than an end goal or title to be acquired.
Thanks again!
July 30th, 2009 on 12:19 pm
@Justin – thanks for your feedback. Design becomes a lot easier when you stop being afraid of getting things wrong and you focus on just trying to make refinements continually. I think it’s a Zen-like state of mind… which is why I like the Basho quote so much at the end. Applies to more than just design, too.
August 2nd, 2009 on 1:00 am
Excellent write up! Now to spread this link to others…