InfoQ

InfoQ

News

My Bookmarks

Login or Register to enable bookmarks for unlimited time.

The content has been bookmarked!

There was an error bookmarking this content! Please retry.

"Good Design" Means ...?

Posted by Mike Bria on Jan 29, 2009

Sections
Process & Practices,
Architecture & Design,
Development
Topics
Agile ,
Object Oriented Design ,
Java ,
Design ,
.NET ,
Ruby
Tags
Design Guideline ,
Refactoring ,
Legacy Code ,
Buzzwords ,
Productivity

It's not news that at the heart of successful software projects (and, frankly, fulfilling software careers) is good design. Also not news is that defining what "good design" really means has been at the heart of an infinite array of debates, papers, talks, books, discussions, and more for ages. To help, J.B. Rainsberger and Scott Bellware offer some advice to follow until that one true definition comes along.

Recently, well-respected Agilist and TDD-thought-leader J.B. Rainsberger was commenting on how over the years he has "witnessed a number of attempts to develop a complete, constructive definition of good design". His primary observation and personal revelation:

Some people lament the lack of a complete, constructive definition of good design. I don’t, and today I finally articulated why I don’t think we particular need to worry about this.

He continues with a disclaimer that he doesn't disagree having a "clear test for a design's 'goodness'" would be a useful thing (with examples as to why), but then expands on why he's not terribly concerned that we may not yet have [in this editor's words] "that one true way". He points to his experience, to what he thinks we do have to help us optimize our chances of ending up with a "good design":

In the past ten years I have learned some incredibly useful things about design:
  • When programmers write design tests, they tend to find more of their own defects more quickly, which reduces the overall cost of realizing their design.
  • When programmers duplicate code, defect rates increase, and when they reduce duplication, defect rates decrease.
  • When programmers first start to change unfamiliar code, they tend to start by clarifying unclear names in the code: variable names, method names, class names. This practice helps them change code more safely and less expensively.
I have learned these things through my own practice, through pairing with others, and through observing other programmers at work. I find it more significant to note that even with only these three observations, we have improved the value of software design considerably.

J.B. closes with a thought about what he often uses to identify a good design, "I get by with the Miller Test: I know it when I see it."

Interestingly, one of the key themes in what J.B. is saying has to do with an idea that for a design to be good, it should "look good" to someone new to it; (paraphrased) "..unfamiliar code? Clarify names so you can better understand it..", "I know it when I see it". Not to stretch J.B.'s message beyond what he means, but some might take this to imply that a good design will at a minimum be one which is "easily learned", and idea written about recently by Scott Bellware. In his words:

The essence of "good design" is it's ability to be absorbed by a human mind. Design is "good" when it can be easily-learned.
...
Good design is about knowledge. We wrap it up in all kinds of terminology, but in the end it's about making smallish bits of software that are easy to understand on their own, and that fit together exquisitely to make things bigger than themselves, and that can still be as easily understood.

Bellware goes quite deeply into how the term "testability" relates to the idea of good design, but not necessarily in the way it is often used. He stresses that code's "testability" is not about "whether it can be tested", but rather if it "is [currently being] easily tested", and that "testing" is all about learning:

Remember, testing is about making observations, and observations are about learning.
...
If it's hard to set up an object in order to learn what it does and whether it does it right, then you've probably got a poorly-designed object. This suggests that you can use test code to prove that you've got the right design. And this is what testability means.
...
No matter how good I become in object-oriented design, the only proof that a design is good is [example/test] code that proves concretely that I have achieved the highest level of ease of setting up an object for use.

So, as J.B. points out, unambiguously defining "good design" may just be one of those golden carrots; it's always one step in front of us, no matter how many steps we take forward. But also as he highlights, and as Bellware seems to suggest, there are tools we have right at our disposal today to help guide us towards designs that keep us productive and keep us happy, enjoying our day jobs as programmers. What do you think?

  • This article is part of a featured topic series on Agile

Related Sponsor

In today’s hyper-competitive world, later may be too late to adopt Agile development and this Roadmap for Success will help you get started. Download "Agile Development: A Manager's Roadmap for Success" now!

Designing is all about Learning by C. Keith Ray Posted
Re: Designing is all about Learning by Mike Bria Posted
Designing is also about clearly communicating ideas by Michael Cohen Posted
Design principles by Anders Sjöberg Posted
Re: Design principles by J. B. Rainsberger Posted
Minimizing dependencies by Jesper Nordenberg Posted
It is easy to persuaded by good design by Zhang Joey Posted
Universal properties by Hermann Schmidt Posted
And, oh yes, please do reference also THIS nugget by Jim Shore by Mike Bria Posted
  1. Back to top

    Designing is all about Learning

    by C. Keith Ray

    I don't have a link handy where some luminary says that designing is, at heart, about learning, but I agree with that idea. And here we agree that a good software design is - among other things - better when it is easy to learn.

    I think we can conclude that one of the ways we can design code is by test-driving it -- tests help us learn where our design needs to go, and when writing a programmer-test becomes hard, that is a signal that we can learn from.

  2. Back to top

    Designing is also about clearly communicating ideas

    by Michael Cohen

    "Design" is one of those concepts that will always be impossible for everyone to come to consensus on what it is. However, I believe that while it is important for someone to learn from a "good" design, the complementary point of a design is to clearly communicate ideas. Without clear communication learning becomes a real challenge.

    Any design that is in some way incomplete, vague or ambiguous can quickly lead to a break down in communication, and, as an outcome, allows for poor quality in implementation, maintenance and tests. This is why it is so important that software developers and architects not only have the technical chops but also have training to clearly communicate complicated ideas both in verbal and written form.

    Clearly communicating design is no easy task for any sizable system, but it should be seen as a primary goal for any project to become truly successful.

  3. Back to top

    Design principles

    by Anders Sjöberg

    To me, Robert C Martin summons up what good design is (www.objectmentor.com/resources/articles/Princip...).

    From the conclusions;
    "... structure of classes and packages that keeps the software application flexible, robust, reusable, and developable."

  4. Back to top

    Re: Designing is all about Learning

    by Mike Bria

    Well said, my friend C. Keith.

    As for your second assertion (pun intended) about learning from the tests (what I personally like to call "listening to your tests"), the post by Scott Bellware also stresses that point. Albeit, he does appear to go to great lengths not to explicitly say "test-drive" or "TDD", which I did find interesting. ;-)

    Cheerios
    MB

  5. Back to top

    Re: Design principles

    by J. B. Rainsberger

    Yes, but those are properties of good design, and not guidelines for achieving those properties. The Four Elements of Simple Design are guidelines for achieving those properties and, in my mind, sufficient for most current purposes.

  6. Back to top

    Minimizing dependencies

    by Jesper Nordenberg

    I've found that a common property of most good designs is that they minimize dependencies. This is a property which is quite easy to measure and to strive for.

  7. Back to top

    It is easy to persuaded by good design

    by Zhang Joey

    I believe in the statement that good design is a design easy to learn. In addition, when I make a design, I like to challenge and also ask others to challenge it from different perspective, if I find it's easy to persuade myself and other challengers, it is very probably a good design.

  8. Back to top

    Universal properties

    by Hermann Schmidt

    A concrete design's quality cannot be measured with "hard facts" if the requirements are not taken into account. I can create the most beautiful design, alas, it does the wrong thing altogether. It's beautiful, but bad nevertheless.

    My universal properties of good design are (from the top of my head):

    - names and terms wisely chosen

    - provokes very few misunderstandings

    - easy to communicate

    - concepts are clearly separated by concerns and not wildly interconnected

    - often, symmetry and beauty of shape (Gestalt) are indications of good design. For example, you can very often identify code that stinks only by its shape, without exactly knowing what it does.

    Good design has a lot to do with aesthetics. Not measurable, of course. That's where experience comes in. "I know it when I see it" fits here nicely.

  9. Back to top

    And, oh yes, please do reference also THIS nugget by Jim Shore

    by Mike Bria

    Jim's take:

    jamesshore.com/Articles/Quality-With-a-Name.html

    Well worth a print out, read, and posting on the team room wall.

Educational Content

New-age Transactional Systems - Not Your Grandpa's OLTP

John Hugg discusses high volume transaction processing applications with high and low frequency profiles, and how VoltDB can be used for that purpose.

Cool Code

Kevlin Henney examines code samples to see what can be learned from them starting from the premise that one won’t write great code unless he knows how to read it.

Collaboration: At the Extremities of Extreme

Jason Ayers share the observations he made watching a team of developers collaborating in real time on the same code base, pushing XP, pair programming and continuous integration to their extremes.

Yesod Web Framework

Michael Snoyman presents Yesod, a web framework written in Haskell and containing a web server, templating, ORM, libraries (templating, gravatar, etc.).

Transactions without Transactions

Richard Kreuter and Kyle Banker on how to avoid classical RDBMS transactional systems by using compensation mechanisms, transactional messaging or transactional procedures.

Attila Szegedi on JVM and GC Performance Tuning at Twitter

Attila Szegedi talks about performance tuning Java and Scala programs at Twitter: how to approach GC problems, the importance of asynchronous I/O, when to use MySQL/Cassandra/Redis, and much more.

10 tips on how to prevent business value risk

One category of risk that project teams need to ensure they address is business value failure – delivering a product that fails to provide value for the business investor.

Interview: Software Systems Architecture: Working With Stakeholders Using Viewpoints and Perspectives

InfoQ spoke to the authors of Software Systems Architecture on a couple of new topics, the System Context viewpoint and Agile, which have been added to the second edition.