Principles of Software Design

This entry is part 1 of 8 in the series Design Principles

Software should be well designed, right? What then is well designed software? I’d say it’s much easier to spot badly designed software, than to postulate what constitutes well designed software. Nevertheless, I’m going to give it a try. I’ll also try to provide illustrative examples and justifications for my arguments.

However, I think we all can agree that the answer to what constitutes good design depends heavily on the context and purpose the software is developed for.

Are we tasked with building a service without a user interface, a web or desktop application, a game or an operating system, a smart-phone app, or an embedded system? Will it be stand-alone or part of a larger system? Will it be single user or multiuser, a commercial product or an in-house solution, will it run unattended, is it life-critical? Will it handle 100 KB or 100 TB of data per day? What is the cost of failures? How much data loss is acceptable? How much downtime is acceptable? What are the performance goals?

Design decisions that would be considered “good” (or “good enough”) for one kind of system, might be detrimental to another.

Target software

So let’s define what target software I’m considering in this discussion of “good design”.

I’m most familiar designing or reviewing software in what we can call the “medium to large” scale, where the systems are comprised of several interacting components, such as desktop or web applications, web and windows services, and relational databases, loosely connected together in order to form a whole cohesive system.

My experience is that most systems have very few, if any, constraints that are really really hard, which must never be broken. This means in practice that nothing will be life critical, and the cost of failure is not overwhelming. A small amount of downtime may also be acceptable by the users. We are probably not dealing with data sets of hundreds of terabytes, and are not handling extremely sensitive or secret information.

The principles I want to discuss may also not be equally valid for very large scale systems such as MMORPGs, or the very small hobbyist scale such as the Sudoku solver you write for fun, but will in my opinion still be applicable to a rather wide range of enterprise or business software, from single user desktop applications, to web sites with tens of thousands of users, or business critical information processing services running as windows services or internet-facing web services.

The principles

Now let’s get closer to the actual design discussions, shall we?

Experience have taught me a few things about software design, and I think that there are a number of desirable properties that we’d like our system to have. The following lists some of the most important ones:

  • Functional – able to provide the required functionality.
  • Testable – so we can ensure the system does what we want it do to.
  • Robust – able to handle and recover from failures.
  • Monitorable – the status of the system can be observed from the outside while it is running.
  • Deployable – easy to move from the development environment to the production environment.
  • Scaleable – able to gracefully handle a growing amount of data and users.
  • Adaptable – able to handle changes in the requirements or run-time environment.
  • Efficient – able to make the most out of the available computing resources.
  • Elegant – attains perfection not when there’s no more to add, but when there’s no more to remove.

My plan is to expand on the characteristics of these individual design properties in a series of future posts. I could probably expand on this list, but these are the really important ones, and we have to start somewhere, don’t we? If I come up with more desirable properties, I’ll have to come back to them later, or I’ll never get started. This is a blog, not a book, after all.

Feedback from users or by observation is invaluable for the evaluation of a design (be it your own, or any design you know and understand well). Negative feedback on the design is a powerful motivator to design something better next time. Positive feedback helps reinforce the good decisions made, and we are likely to try to re-use good ideas the next time around.

Series NavigationA Question of Scale >>

Leave a Reply

Close Menu