There’s one thing about software development that puzzles me more than anything else: talent. Some people just have it. They can crank out code and solve staggering problems, but they also have another ability which makes a huge difference. They know good design when they see it. They can tell very quickly whether a piece of code was developed thoughtfully or haphazardly; whether it’s trustworthy code or something that is ready to slide down the entropy well and deserves a good kick on the way down. They just know.
Maybe talent isn’t the right word. Maybe the right word is experience. Very experienced developers have this uncanny sense of design, but not all of them. I really don’t know whether it is learned through intense experience or fostered by innate ability but there definitely is something to it.
A long time ago, I read a book called Drawing On The Right Side of the Brain by Betty Edwards. The premise of the book is that artists see the world differently. They see things in a way which lends itself to the creation of art, and if you can mimic their mode of perception you can become more artistic.
One of the exercises in the book is to take a picture of someone’s face, turn it upside down, and then draw it. Amazingly this works very well. You are able to concentrate on curves and angles and see a face purely as shapes and textures. But, when the picture is right side up, we see it as a face and we confuse what we know about faces with what we actually see. It’s as if we have an internal monologue that goes “Oh, face. Faces are ovals; I’ll draw an oval. Hair is long and stringy; I’ll draw some lines.” But, when we get into that perceptual mode, the result is often cartoon-ish.
When I read Drawing On The Right Side of the Brain, I wondered whether there is something analogous that happens in software. Maybe very experienced designers just see things differently.
I was reminded of all of this a few years ago when another book came out, Blink by Malcolm Gladwell. In it, he argues that a lot of our cognition happens instantaneously and somewhat unconsciously. We can see this in the decision process (or lack thereof) used by experts. Often they just sort of know the answer, but they aren't quite sure how they arrived at it.
Experts can, of course, be wrong but I think that there is value in seeing things the way that an expert in a field might see them, and that if we accept the premise that arriving at better solutions is a function of being able to see them, then we have an opportunity to move design learning into a different direction. Maybe we can teach design sense or at least, design appreciation by bombarding people with examples.. here's a good snippet of code.. here's a bad one.. here's a good one.. here's a bad one.. Example after example until people grok the essence of good code.
I don't have any illusions that this sort of thing could be anything near a complete education. Some lessons have to be hard-won. Design is a deep skill, and there's no substitute for writing code and living with it for years. But, I have run into too many people who just really haven't encountered enough good code. They don't know what it looks like and they don't know why a particular piece of code is good or bad.
Next week at Agile2007, Emmanuel Gaillot and I will be hosting a workshop entitled Design Sense. We've gathered a large number of example code snippets. In the workshop, we are going to grade them and discuss them so we can learn more about what people see as good in design.. what they cue in upon. We're also interested in how much agreement there is in the community about goodness in design. If all goes well, the workshop could be the first step toward a teaching initiative that is focused on the use of these perceptual examples.

Comments (10)
For me, I've always found that there is a similarity between the elegance of code and the elegance of mathematical proofs. A good proof for most theorems, as commonly found in any textbook, gets right to point without sacrificing any of the details. It is as complicated as it needs to be -- to be rigorous -- but no more. The same is true of good code. Everything in the code fits for a reason. The 'steps' that need to be together, are together.
You need little documentation to explain either the overview or the detail. Even if you miss some of the specifics, you can quickly grasp the concepts. Nothing is fancy, and nothing is clever. But neither is it repetitive nor redundant. It solves the problem, and quite possibly many more variations in the same domain.
If the code is ugly and painful to read, then I know it is always worth spending the time to correct it as early as possible. It will save time later. Elegance isn't really optional.
Paul.
Posted by Paul W Homer | August 8, 2007 5:06 PM
Thank you for putting your view. I have not read the book and probably it might not have arrived in India. I have been following about the launch of this for long time thru Petzold's blog.
I am a programmer and have been doing this for around six years now. All the time I spent working on the legacy code, some written very beautifully some very badly. I was frustrated with this task, but now consider this as a skill hard to come. I will be happy reading you all there.
Regards,
Om
Posted by Om | August 9, 2007 6:25 AM
This is indeed something that I have been struggling with. The problem is, how to explain to your boss that the code someone has written is bad, 'because it has code smell all over'. He'd say that if it works, it works, and if I can't convince him with some facts and figures then leave it as it is.
So if there's this sixth sense, then how do you communicate it, you need to convince others, and if they lack that sense, you still need some good arguments. So you say: "Don't declare that variable six pages up from where you use it" or "Don't create methods that span multiple pages of code" instead of "Dude, this code is sh*t! Why? Because!"
Posted by Mike | August 9, 2007 9:33 AM
@Paul --
Check out the delightful Edsger W. Dijkstra Archives, maintained by the University of Texas. As one of the foremost computer scientists of his generation, Dijkstra argued that programming is more a branch of mathematics than engineering.
The archive is largely a collection of his handwritten notes to colleagues, which range from elegant geometrical proofs to a rant on a trip to Harvard Law school. One of my favorites is his withering Answers to questions from students of Software Engineering.
Posted by od1 | August 9, 2007 9:55 AM
I've seen plenty of code that is a pain in the butt to read, but is really reliable. I've also seen some that looks great and is well documented, but doesn't do what it was supposed to do and a few minutes of testing would have revealed that.
Beautiful sculptures that break easily, and ugly stumps you can sit on for 30 years. What can we say about those two situations?
Posted by Darcy Baston | August 9, 2007 10:10 AM
Recently when trying to explain to some non-coder friends what it is I do and why I enjoy staring at thousands of lines of code every day I explained it as a creative process. There are many coders who are phenomenal engineers or mathematicians. I am not one of them. I'm one of the rare breed who are also artists and designers (I have worked professionally in graphics, layout and design as well as programming). I'm not saying I know how to design great code, but I've written code for nearly 20 years and as a bit of an artist I can detect the creative side of coding and I get the tingles when I see a particularly elegant solution. I think there is definitely an artistic side to it and perhaps this is what drives "design sense."
Posted by Patrick Hogan | August 9, 2007 10:38 AM
I instantly related to this article right up to the point that you mentioned a class at an Agile seminar of all things. I don't think it is possible to combine the two.
Posted by Chris | August 9, 2007 4:00 PM
@od1 --
Thanks for the reference, I had seen some of Dykstra's writing, but not the complete Archives. I liked EWD1305 (Answers to questions ...), but I found EWD1304 The end of Computing Science to be fascinating and right in line with much of my older writings such as Software Development. I particularly like where he said "We simply do not know yet the limits of disentanglement. We do not know yet whether intrinsic intricacy can be distinguished from accidental intricacy." He was clearly a man ahead of his time.
Paul.
Posted by Paul W Homer | August 10, 2007 1:56 PM
Blink. Well, there's some of that. But Newton is said to have complained about how long it takes to come up with a new idea - even if it's 'obvious'.
It's is an interesting exercise to attempt to enumerate the important skills for creating good software. And i don't know of anyone who has a credible list.
One skill that seems to be needed is one i call 'trailing'. From Boy Scouts. Tracking is the art of following someone or something. Trailing is the art of leaving clues for someone else to follow. Mind, the goal is to make it easy to be tracked. It can be as simple as having someone follow your car. If the light turns red at the wrong time, you slow or stop to let them catch up. Not everyone does. To do trailing, you need to be able to guess how someone else will behave. To do that, you have to have a good model.
For software, you need a good model for how the computer is going to work. For me, machine language is often easier than BASIC or Java, because there are fewer unknowns. I recall that C was nebulous until i looked to see the PDP-11 assembly that the compiler produced. Then the exact semantics of the compiler became obvious. Later, the ISO standard was published... But the point is that you can write your code, you can test it to death - even use code coverage and lots of corner cases, and later find that it still doesn't work as intended - it works as written. We still don't have a DWIM instruction (Do What I Mean).
I've worked with people who are mathematically oriented. They produce good results, but differ from mine. I've worked with people who debug their creations into existence - again with good (even stunning) results. And i have a bent towards getting all the details right for production delivery. These three approaches seem to require non-overlapping skill sets. This suggests that one may produce a list of sufficient skills, but not a list of necessary skills.
I've had the opportunity to work with very good programmers who come at it from these different angles. The good news is that sufficient skills need not all reside in the same body. It may be more efficient if they are, but the job can get done if they aren't.
Unfortunately, even if lists of skills are generated, industry has show remarkable reluctance to test for them. There seems to be a determined avoidance to learning how. Even if there are simple ideas that are easy to implement, as in Fred Brook's book, industry seems bent on ignoring it. What to do about that? Start your own company? Set yourself up as God and rule the world?
Posted by Stephen Uitti | August 10, 2007 2:49 PM
Michael
Design is a funny thing; it can be taught, but only if the subject is receptive to it. Sometimes the subject molds to it like clay into a press; sometimes it's like making a grayscale photocopy of a color image: it appears close in detail, but the spirit is missing.
Good designers (and I immodestly count myself in that category, and in the "good driver" and "handsome" category as well) have two inherent traits which make them malleable:
First, they have a creative nature. Like an artist picking a color, they choose an implementation which makes a statement: this is elegant and correct. Poor designers only care THAT it works, like kids picking up the closest crayon. Crayons of all colors draw lines, right?
Secondly, they must have a good sense of engineering. When confronted with alternatives, they must be able to select the "best" option, even when options do not have many differences to discriminate with. What defines "best" is where the good designers shine: What will happen in the future? What can cause this to break? Is this design simple and straightforward to use? Poor designers write "stream of consciousness" code, whereas good designers craft code to answer questions no one has thought to ask yet.
Strangely enough, these traits are true of almost any technical design, not just computer science. I was originally trained as a mechanical engineer, and it was obvious even in school who the good designers were. When designing, for example, a transmission, the poor designers would turn in a design containing shafts with gears welded to them. Good designers would have shafts with shoulders increasing in diameter toward the center of the shaft for the gears to butt against with snap rings securing a set of keyed gears. The good design produced the same main goal of power transmission, but added increased shaft stiffness, more accurate gear locating, an option for disassembly, a sensible point of failure for overloading, only one possible way to correctly assemble the set, etc... - when exposed to the same inputs at school, the good group already expressed the je ne sais pas which adds the extra essential element of design.
Put another way, the traits of good designers are private, static, and const - a certain unseeable something that will always exist in them, but is only expressed through the public interfaces of their design.
Posted by Matt Bramlage | September 2, 2007 7:37 PM