Diamond cutting

Thursday 29 April 2004This is over 20 years old. Be careful.

I was talking with a fellow software engineer the other day about the process of designing software, and we got around to the diamond cutter analogy.

A diamond cutter (so I am told) takes a raw lump of diamond and has to cut it in just the right way to make a properly cut finished diamond. With large diamonds, the first cut is crucial, and can be an all-or-nothing proposition. Strike the diamond properly, and it is worth millions. Strike it wrong, and you have a pile of cheap industrial chips. There are stories of diamond cutters staring at rough diamonds for weeks trying to discern the right place and angle to strike.

Sometimes software design is like that. How should a pile of functionality be divided into modules and classes? What’s the right separation of concerns? Which patterns will provide the best leverage over the forces of chaos? As with diamond cutting, the best answer may not be immediately obvious. Make the first cut incorrectly, and you could be struggling hard against a ragged grain for the whole rest of the project. Strike it right, and you could have a smooth, strong, easily-implemented interface.

When designing software, sometimes we have to mull a problem over, examine it from every angle. Simply starting out and figuring you’ll hack your way through it may leave you with an unmanageable mess. Next time you’re in this position, try letting it sit. The proper grain may become apparent to you over time. You may end up with a beautiful diamond instead.

Comments

[gravatar]
I agree that there are critical decisions that can affect a project fundamentally. I also agree that many problems should be considered carefully before starting to write code. (When my daughter asks me, "How can you sit and type all day?" I say that my job isn't to type, it is to think.)

But having said that, I think most design problems are amenable to an agile approach. Think about what might work and try it. Refactor when you have a better idea or when the requirements change. Keep growing the design.

Really, the thinking and coding work best when taken together. If you try to think your way through the design without writing code you lack the on-the-ground knowledge you get from coding. If you just start writing code with the sole goal of getting something that seems to work, you are hacking in the worst sense of the word. But if you consider each addition to the code carefully and keep the code clean at all times you will end up with a thing of beauty - well-designed code that is superbly suited to the task at hand.
[gravatar]
Letting it sit is certainly a good suggestion, and not just at the beginning of a project. Whenever an unforseen snag or tough problem is encountered, it really helps to step back an do something away from the keyboard (I find running or biking particularly useful).



The questions I have are how long to you wait before pressing forward, and if nothing comes, what do you do? Start coding, and bulldoze through problems? Change requirements (assuming enough flexibility in the project)?



Nat

[gravatar]
The cool thing about software is that (provided you have version control) you can always go back and try again.

I used to stare at problems for days - my managers wouldn't let me go for weeks - looking for the perfect angle; lately I'm more inclined to think about it for a bit, and then strike a blow, even if the solutiopn isn't obvious.
[gravatar]
The other part of the problem is that the users know at the beginning what they want: either a ring or a drill bit. A lot of times in software engineering, the users, in the middle of the project, either change their mind from wanting a ring to wanting a drill bit... or even worse, wanting a ring that doubles as a drill bit...
[gravatar]
The user is always going to change his mind. Part of the fun of advanced engineering is anticipating the changes: making it easy when the user undoubtedly changes his mind.

I tend to use both the "let the problem percolate in the back" style and the "do it twice" strategy. I'm always throwing tests together just to see something spin in the beginning, but tend to blow of the current primary line and plug away at other parts while letting a solution to a problem bake. Luckily I work at home, far away from any type of management, so they can't see what methods I use to achieve success--only the results.

"Its a desert topping, and a floor wax."

"Its written in C++ AND Perl."

Add a comment:

Ignore this:
Leave this empty:
Name is required. Either email or web are required. Email won't be displayed and I won't spam you. Your web site won't be indexed by search engines.
Don't put anything here:
Leave this empty:
Comment text is Markdown.