Principles of Good Design as Applied to Software Engineering

Most people know Apple’s iconic designer, Jonathan Ives, but few have heard of another influential designer, Dieter Rams.  Dieter Rams was the chief of design at Braun from 1961 to 1995 and head of design until his retirement in 1998.  Some examples of his work include: 606 Universal Shelving System, the Braun T3 pocket radio, and the Braun T1000 radio. These are considered iconic and many of the new Apple products share more than a passing resemblance to these iconic designs.

Many industrial and user interface designers have been inspired by his work and design principles and I’ve often wondered how his ten principles for good design could be applied to software engineering and programming.  While maybe not intuitively obvious, I believe they can be applied to programming since the principles of design are always the same.  Additionally, one should never stop learning and what better way to learn than to learn something tangential to what you enjoy?  There are always universal lessons and principles that can be adapted and applied elsewhere.

Rams’ Design Principles

Rams’ design principles are simple and straight-forward and are summarized as follows:

Good design:

  • is innovative –The possibilities for innovation are not, by any means, exhausted. Technological development is always offering new opportunities for innovative design. But innovative design always develops in tandem with innovative technology, and can never be an end in itself.
  • makes a product useful –A product is bought to be used. It has to satisfy certain criteria, not only functional, but also psychological and aesthetic. Good design emphasizes the usefulness of a product whilst disregarding anything that could possibly detract from it.
  • is aesthetic –The aesthetic quality of a product is integral to its usefulness because products are used every day and have an effect on people and their well-being. Only well-executed objects can be beautiful.
  • makes a product understandable –It clarifies the product’s structure. Better still, it can make the product clearly express its function by making use of the user’s intuition. At best, it is self-explanatory.
  • is unobtrusive –Products fulfilling a purpose are like tools. They are neither decorative objects nor works of art. Their design should therefore be both neutral and restrained, to leave room for the user’s self-expression.
  • is honest –It does not make a product more innovative, powerful or valuable than it really is. It does not attempt to manipulate the consumer with promises that cannot be kept.
  • is durable –It avoids being fashionable and therefore never appears antiquated. Unlike fashionable design, it lasts many years – even in today’s throwaway society.
  • is thorough to the last detail –Nothing must be arbitrary or left to chance. Care and accuracy in the design process show respect towards the consumer.
  • is concerned with the environment –Design makes an important contribution to the preservation of the environment. It conserves resources and minimizes physical and visual pollution throughout the lifecycle of the product.
  • is as little design as possible –Less, but better – because it concentrates on the essential aspects, and the products are not burdened with non-essentials. Back to purity, back to simplicity.

 As Applied to Software Engineering…

Looking at the ten design principles, I’m sure you’re already seeing parallels between them and good software engineering.  We’ll go down the list and examine the meaning of each statement in the context of software engineering.

First, good software engineering is innovative.  At first glance, this might seem to support the idea of using the newest and freshest technology available.  However, looking at the rest of the rule, it specifies innovative technology can never be an end in itself.  It means, use the appropriate job for the tool and eschew the idea of using the newest technology if it doesn’t fit your problem.  Using an older library in a new way can be more innovative than just using the newest technology.

Secondly, good software engineering makes a product useful.  In the case of the software engineer, this is about easy-to-understand code (User Interface concerns fall more under UX/UI people although coding is involved there too).  This falls inline with many of the principles put forward by Clean Code by Bob Martin.

Good software engineering is aesthetic.  The design of the program (or programs) is clean and simple, like the codebase, it is easily understandable, contains enough abstractions to make sense and can be easily modified to encompass new requirements.  This is a tough point to understand, it’s hard to know when the proper amount of abstraction has been reached or know what is easily understood by others.  A few point to think about are, is the design simple?  Are you using queues instead of actors, data instead of syntax, and polymorphism instead of inheritance, switching, or matching?  Have you pulled apart the design to the base components?  Can you easily describe each part of the system?  Can you extend the design by simply removing one or two components and replace them with two or three new ones?

It makes a product understandable.  A follow on to the second and third points, the design and codebase of the program can be grokked by a new developer with little effort.  This isn’t to say it is going to be some work to look through the codebase, but it should be obvious how all the modules interact.  As a software developer, you should aim for simplicity — and note: simplicity does not mean easy :).

Good software engineering is unobtrusive.  Again, another principle of Clean Code, the codebase and design does exactly what it needs to do, no more no less, yet has the ability to be modified and integrated within another project easily and simply.  This leads to question of “how do we know the system can be modified easily and simply?”  If it isn’t, how do we fix that? And, does it mean a programmer new to the project can understand the code?  Unfortunately, this is a very interesting problem and deserves an article all to itself, but let me touch on this quickly.  In my opinion, a system can be modified easily when there are distinct breaks in modules in the code defined by interfaces that allow for good unit testing of each module proving the system is not overly coupled.

It should be honest.  Write and design simple to understand and modify code.  Consider everyone who is going to be working in the codebase, everyone should be able to understand, extend, and fix bugs within the code and adjust the architecture.  I’m not advocating a cowboy coder to come in and do a large refactor (e.g. rewrite) because in their mind it is cleaner, but again, it should be at the right abstraction at all points.  It also relates to the idea of unobtrusiveness with knowing when code is easily modifiable.

It is durable.  It uses the best tool for the job at hand; advocating code reuse and proven projects versus reinventing the wheel.  It means eschewing technologies not completely tested for your situation, opting instead for proven technologies and methodologies.  It means extending proven technologies where needed and using ideas from the bleeding edge, to make a quality product meant to last.

Thorough to the last detail.  The software’s design is meant for stability and ease of extension. The code base is well thought out and easy to understand.  The unit tests, functional tests, and integration tests express all (or as close to all) issues that can occur at the each abstraction layer.  There is sufficient documentation to understand, deploy, and modify the software.

Is concerned with the (computing) environment.  There are no memory leaks (yes, you can still have them in managed memory languages!), the algorithms are as efficient as possible for their purpose (run time vs. memory) and care is taken not to use too many resources.  The code itself is clean, straight-forward, and easy to understand.  This does not mean to go prematurely optimize and read all the papers on new, hot data structures, but it means to make good rational choice that can be explained and understood as a starting point.  As learn more about the problem and have integration testing and testing on the environment, you can begin to focus on the areas of code that need to optimized and understood better for a faster or more elegant solution.

Is as little design as possible.  As has been brought up in earlier points, the design focuses on the specifications, not the “what could happen” or “wouldn’t be cool if…” questions.  The problem is solved and designed in an elegant and easy-to-undersand way.  The code reflects this by being easy to read, understand, and modify.  You can think of this as, not being overly complicated when it comes to designing classes and methods.  Don’t use an enormous amount of variables unless you need them.

Conclusion

Good design principles can be applied anywhere design is used.  The definitions that Rams’ used were obviously questions he asked himself about his products, but it illustrates a point not laid out in his principles of good design:  you must constantly question yourself, your process, and of course, your design and implementation.

Additional Notes

I noticed multiple people have written about Rams’ design principles as they apply to software as well, you can read their articles here, here.  A wonderful talk about simplicity in design by Rich Hickey can be watched here (you really should watch it).

Additionally, I stayed away from a lot of questions that can come up. I know I didn’t touch on the idea of the right solution versus the correct solution which I’ve talked about a little before.  Also, I didn’t talk about what happens if you have conflicts between teammates on if you believe your implementation is good and they don’t, or even if your idea for the design of the software is different than someone else on your team.  These are all topics I’d love to talk about but they really deserve their own posts where we can delve into them in detail.

If you like, dislike, or have anything to say about the article, let me know in the comments below!

Modifying CSS in the LightWord theme for WordPress

The theme that I am currently using on my website, LightWord, is generally very nice and I love it.  However, there are a few issues with it, luckily, LightWord offers a nice way to correct some of the formatting issues without actually having to update the theme itself through the LightWord Settings page.

To access the LightWord Settings page, go to the Appearance -> LightWord Settings choice on the left side menu in the WordPress admin dashboard.

In this page, scroll down to the Custom CSS settings text box.  At this text box you can enter any additional CSS and it will be inserted into every page on your blog.  I’ve used this to fix a few issues that I have with LightWord.  First, I wanted my blog title to appear in a different color.  I changed this, with the following bit of CSS:

h1#logo,h1#logo a{color:#FF6600;}

Secondly, I wanted a different background; which was solved with this snippet:

body {background:url(‘wp-content/themes/k3290370.jpg’) repeat;}

Lastly, the drop down menu background was too small for some of the titles it was displaying so it would cause them to overflow.  I did a quick change that expanded the size of the menu drop down background, like this:

#front_menu ul {width:300px;}

Of course, you can override all the CSS you want within this text box, so if you wanted to change the color of links or whatever, you can do it right here without modifying the actual LightWord theme.  In addition to the Custom CSS, the settings page also allows you to add in additional scripts, headers, and footers.

Information Architecture for the World Wide Web

I’m finally finishing up my reading on user experience and web-based technologies with this book: Information Architecture for the World Wide Web 3rd Edition by  Morville and Rosenfeld.  It also happens to be the longest of the previous usability and web-design books I read, of course, this is due to the fact here they’re discussing more than just user experience but many intricacies of large-scale web site design.  The book is divided into six sections: Introducing Information Architecture, Basic Principles of Information Architecture, Process and Methodology, Information Architecture in Practice, Information Architecture in the Organization, and Case Studies.  As you can guess, the book is pretty hefty and weighs in at a good 504 pages, including appendices and an index.

The Introducing Information Architecture section gives a quick history of information architecture from tablets and scrolls to libraries to websites and why information architecture is important.  Next, it describes why information architects are needed and how it is practiced in the real world.  The last chapter in the section outlines how users search for information and how to determine the user’s information needs and information seeking behaviors.

Principles of Information Architecture contains six chapters and covers the basics of information architecture.  These include: organization systems, labeling systems, navigation systems, search systems and thesauri, controlled vocabularies and metadata.  Each of these basics is covered fairly well giving the reader insights into which ones are best for which type of websites and when to completely ignore an idea because it doesn’t make sense given beginning parameters.

Part 3, Process and Methodology is only three chapters but describes how to successfully integrate information architecture into the web development process.  It begins with the research and research methods then moves into how to convert the research into a strategy.  This includes using metaphors, scenarios and diagrams along with project plans, presentations and a strategy report in order to sell others on integrating information architecture.  The final chapter focuses on design and documentation.  This includes: using diagrams, developing blueprints and wireframes, mapping the site’s information, creating models and controlled vocabularies and getting buy-in from other members of the web design team.

Information Architecture in Practice delves into the educational, ethical, team building aspects of information architecture and helpful software.  The chapter on education gives a list of schools that have substantial IA coursework in addition to discussing how important formal education is to hiring companies (hint: you’ll need it).  The chapter on ethics touches on some cases where ethics come into play when you might not even think about it.  For instance, Amazon’s search engine at one time would say ‘Did you mean adoption?’ when someone typed ‘abortion’ into the search box.  As you can guess, this caused a little bit of a stir.  Finally, they take on the idea of how to staff an information architecture team as a thought experiment.  What are the pros and cons of having an in-house staff versus consultants?  How many people would you need?  What would be their roles?  The final chapter of the section covers tools and software needed to build websites or helping analyze, categorize and integrating search into a website among other things.  It also gives a list of questions one should ask about the software to determine if it is really needed for the project.

The fifth section is Information Architecture in the Organization which discusses how to pitch the idea of information architecture to clients, how to demonstrate information architecture’s ability to positively impact a company’s bottom line and finally, how to setup an information architecture  framework to support a company for the long haul.  If you want to get information architecture into a company, these are probably the most important chapters.  The truth is, you’re always selling no matter what you’re doing so you might as well learn how to sell information architecture.  These chapters describe the types of reactions you can get and how to respond to negative reactions to the idea of starting up using information architecture.

Case Studies is the final section of the book and it looks at two different information architecture projects and discusses their best practices and lessons learned through the projects.

In my opinion the first two sections Introducing Information Architecture and Basic Principles of Information Architecture are must reads.  Process and Methodology is something you should skim in order to figure out how to integrate it into your design process and the other sections are sections you should jump to if you have a question that you see a definite answer for from the table of contents.  I’d give this book a solid buy if you’re going to be redesigning or designing websites with large amounts of content or want to know about a small but growing field that is firmly entrenched in Library Sciences and Computer Science / Engineering.

Apple’s Snow Leopard Upgrade Packaging

A few days ago I went to Campus Computers to get the newest version of OS X, Snow Leopard.  The upgrade comes in this neat little CD sized cardboard container with a cute picture of a snow leopard hanging out in the snow (of course) and some nice lettering specifying what exactly this CD is.  Now, you open up this nice little cardboard box from the top and there is another cardboard box inside that has a little tab on it so it is easier for you to extract it from the larger box.  As you pull the box within the box out, it has the typical nice Apple lettering telling you it was designed in Cupertino especially for you.  And as you continue to pull the box out, all of its contents magically fall out all over the place because this box within a box isn’t a box at all, but a cardboard fold out around the OS X upgrade disc inside its own little CD slip cover.  The entire time I installing the upgrade I’m thinking, Apple is known for their great design and great aesthetics, yet they totally dropped the ball on this.  How hard would it have been to use one of the many previously designed CD or DVD cases and put everything into that?  It’d save materials and wouldn’t be near as annoying to open.

Usability, not just websites

After my last two posts (excluding PairIt! and the installation of a fire extinguisher in a 911), you’re probably seeing a theme of usability on the web emerging.  Now I’m going to expand it some more discussing design in general since there is only so much one can say about web-site usability (although I’m sure tons of books can be written about it all stating the same thing: K.I.S.S.).  The definitive book on design according to many people is The Design of Everyday Things by Donald A. Norman.

If you’ve ever seen a door that you can’t figure out how to open, a coffee machine you don’t know how to use, or shower controls that make no sense – it isn’t you that has failed, it is the designer.  Design is a problem and everyone is affected.  For instance, in my SUV, the radio is unusable unless you take your eyes off the road and stare at all the identically sized buttons and look at the words or icon on them.  Why aren’t there indentions or bumps on frequently used buttons to give your fingers something to search for without looking?  Why is every button the same size?  An even better example is the iPod versus every other MP3 player out there.  The iPod just works, you can pick it up and within seconds have the device playing music, searching through its library and in general know how to use it.  This isn’t to say there are still issues with it (there are), but the design of the iPod is simple, sleek and intuitive.  It appeals to us and simple to pick up and use with no instructions.

The Design of Everyday Things discusses the aspects of designing an object from the human perspective.  The first chapter gives an overview of the book, touching on the idea of conceptual models and how the designer views it versus the user.  If the models are the same, the user will have an easy time working the device, if they are different, the user can have a complete disconnect and become frustrated by the device.  There is also discussion on bad design versus good design on objects such as doors, radios and vehicle controls.  Chapter two focuses on the psychology of everyday actions.  For instance, many people blame themselves when they cannot make an item work correctly, when in actuality it is the design of the item who didn’t spend enough time making it clear on how the item is to be used.  It then delves into the seven stages of an action when one decides to do something.  The next chapter focuses on knowledge in the head and knowledge in the world.  Knowledge in the head is knowledge that is learned through repetition whereas knowledge in the world is gleaned from the information gathered by our senses.  Knowledge that is in the world is much more helpful than knowledge in our heads since if it is in the world there is a very good chance anyone can look at the object and determine very quickly how to use the object.  After this, the author discusses the ideas of how to help clear up problems that are often found in design.  Many issues can be resolved by examining constraints such as: physical, semantic, cultural  or logical.  He then goes on to describe the problem with switches; specifically, light switches.  Many people can’t intuitively look at a set of light switches and know what switch controls which light.  It takes time to play with all the switches to determine which one works which light.  He continues on to describe how switches can make more sense by mapping them logically to an already known bit of information.  In a house, the switches could be placed on a floorplan of the house which is recessed into a wall where the user can toggle a switch corresponding to the given room within the house.  However, there are problems since there is no standardization for these types of switches so implementing this design would be very difficult.  Another aspect is feedback, if the user can flip a switch but then has no feedback how does the user know something has actually happened?  No feedback and they’ll think it is broken, too much feedback and they’ll become annoyed.  Chapter five discusses how to handle and prevent errors within design; it involves putting as much knowledge into the physical world as possible, using constraints and providing feedback at all steps.  The sixth chapter, called ‘The Design Challenge,’ discusses the issues that face designers today — from designers not realizing they are the average user to creeping featurism, where adding more features destroys the usability of the device.  The last chapter ties the previous chapters together: the main concepts behind user-centeric design, which can be summed up in two rules.  First, the user can figure out what to do, and secondly, the user can tell what is going on (of course, he does go more in-depth).

Even though The Design of Everyday Things was written in 1988, the ideas discussed within the book are still fresh and can obviously be applied to many more subjects than just physical objects (just look at my previous posts about Don’t Make Me Think and web design topics).  Even if you aren’t in a purely design job, it is definitely worth knowing so when you see a bad design you will know why and perhaps you’ll know how to make it better (then make a company, sell the product, and become a millionaire in the process).

Web Site Usability – Continued

I just received another wonderful package from Amazon.com today and already read through one of the books: Defensive Design for the Web.  Defensive Design lays out and illustrates 40 guidelines on how to make a website more user friendly for those times when it isn’t (i.e. errors).  Many of the guidelines seemed to be more common sense to me, but as Voltaire said “Common sense is not so common.”  So it is nice to see these guidelines gathered up in a nice book (even if you could derive them from Don’t Make Me Think and Nielsen’s ten design heuristics).

A few of my favorite guidelines are:

  • Give an error message that is noticeable at a glance
  • Always identify errors the same way
  • Be polite
  • Provide hints or accept all typical formats in forms
  • Successfully redirect near-miss URLs
  • Make it fast, not cute
  • Anticipate common errors and provide relevant results

At the end of the book are two nice sections.  One on a contingency design test and one on a contingency design plan to help rate and then work toward improving your sites ability to handle errors that can occur.

My biggest knock against the book is that it gives lots of guidelines but doesn’t go into detail as to how you would integrate these ideas into an existing website.  Granted, there are so many different systems (homebrewed, WordPress, Drupal, etc.) that it would be almost impossible to do for all of them, but some pointers on using Javascript or to the appropriate book or website would have been nice to see.

As a design principle I think handling errors is something everyone should think about be it website design or programs.  However, in school and elsewhere a premium is put on removing bugs from the code / site and nothing is stressed on how to handle errors when they occur while the system is running.  I don’t want to go all Joel on Software and trash schools for not teaching their students this and other needed skills (there just isn’t enough time to teach students everything about programming); but handling errors gracefully and not leaving the system in an inconsistent state is an important aspect that is often overlooked.