Single Responsibility Principle

There should never be more than one reason for a class or method to change.  Every component of code should perform a single well defined task.

If a component has more then one responsibility then those responsibilities become coupled and you can’t change one without impacting the other.  This will lead to fragile software that breaks in unexpected ways when you change it.

This is one of the hardest things to do as we naturally combine responsibilities.  A large amount of your design effort will be to identify and then separate responsibilities.

What is a responsibility? A responsibility is also known as a purpose.  For each component, ask yourself what is the specific purpose of this component? This is actually a question you will keep needing to ask yourself as you revisit existing components.  Code changes and evolves over time and what used to have a single purpose might now have multiple purposes and need refactoring.

Here are some benefits to following this principle

  • Reduced code Complexity,
  • Clearer code,
  • Increased readability of your code,
  • reduced Coupling,
  • Code is easier to change and evolve

For example: If your component (class/function) can be forced to changed through both business rule change and a data model change then you have identified a component that needs to be separated into two components.  One that changes as business rules change but is not impacted by data model changes and one that changes as the data model changes but is not impacted by business rule changes.


Principle of Least Astonishment

The basis of this principle is that the most usable systems are those that least often leave users astonished.  Or to put it another way the result of performing an operation should be obvious, predictable, and consistent based on basic clues like the name of the operation.

When two elements of an interface (user or api) conflict with each other or are ambiguous, the behaviour should be the one that will least astonish/surprise the user (or programmer using the api).   From an coding point of view, code should surprise the reader as little as possible.

This behaviour is not necessarily the behaviour that is obvious from knowing the inner workings of the software.

To achieve this:

  • follow standard conventions
  • code should do what the comments and name suggest (or even better, be self describing)
  • use sensible defaults
  • potentially surprising side effects should be avoided (would the side effect be surprising to the user?).  This includes avoiding unexpected side effects in your methods and classes.
  • keep an eye out for things hat might be easily misunderstood

Remember that users will come to your software with expectations an they will develop new expectations as they use your application.  Your challenge is to try and meet those expectations without surprising the users.

This quote from Steve Smith applies to all interfaces, a programmer is a user of your API.

The best user interfaces ensure that the user is always able to find what they need where they expect it, and when they issue commands they do what the user meant for them to do.


Write Code For The Maintainer

Maintenance is by far the most expensive phase of any project.  The best return on investment is any work done to reduce the ongoing maintenance cost of your software.

The best quote I’ve found for this is from

Always code as if the person who ends up maintaining your code is a violent psychopath who knows where you live.

from the same page an alternative quote

Always code and comment in such a way that if someone a few notches junior picks up the code, they will take pleasure in reading and learning from it

Remember that while you will know what you are doing when writing the software, it is the next guy who needs the helping hand.

Maintainability of code is a very subjective opinion, 3 people can look at the same code and think it is very maintainable or bloated or cryptic.  Each opinion being a valid one.

Verbose code is not more maintainable.  You want succinct code that is clear and easy to read.  It takes time to read and understand the extra lines of code.  Each extra line is another potential source of bugs.  So less is more.

At the other end of the spectrum don’t shrink the code down to the point that it becomes obfuscated.

Which is easier to read?

(someVar ? doSomethingA() : doSomethingB())


if( someVar ) {
} else {

A little bit of verbosity does help with the readability of your code from a maintenance point of view.  You want to tread the line in the middle where your code is a pleasure to read.

Comments – if your comments are simply narrating the code don’t bother putting them in.  The best value comments are those which explain why your code does what it does – they explain the rationale behind what you are doing.

Maintainability doesn’t mean obvious and basic.  Assume that the person maintaining your code will be just as smart as you.  Just write your code as you would want it if you were going to maintain it.

An interesting bit of trivia, Hungarian notation violates the “Once and Only Once” principle by recording the type of the variable in the declaration and in the variable name – the type of a variable can change and if you don’t line up the name again you can end up with “String iNotAnIntAnyMore” somewhere in your code.


Open/Closed Principle

The entities within your software (classes, functions, etc.) should be open for extension (and parameterisation), but closed for modification.  Extension in this context means adding/changing behaviour.

You should structure your application so that you can add new functionality with minimal changes to existing code.  Interfaces are your friend along with the Single Responsibility principle.

If the entities within your software only do one thing you will move towards achieving true Open/Closed nirvana.  Each of your classes should implement a cohesive set of related functions.  If you find functionality within a class that does not fit the name of the class consider moving it to another class.

If you are creating abstractions, don’t let the consumer of your abstraction depend on anything but the public contract you provide for the abstraction.

Two things to watch out for that indicate you aren’t following the Open/Closed Principle are:

  • A class that uses another class and embeds knowledge about the internal workings of its dependency (making assumptions about what is returned from methods).
  • A class that uses an abstraction has to downcast to a specific subclass in one section.

Think of Open/Closed as a direction rather than as an end goal of your design.  As you head down this path constantly check that you are still meeting the other principles such as KISS and YAGNI.

There is a caveat in that the more a class is used the more the Open/Closed principle applies.

The more a class is reused in the code base, the more stable it becomes.  As a class becomes more stable it becomes safer to depend on it leading to it being used more.  The more a class is reused throughout the codebase, the more important it becomes that the class adheres to the Open/Closed Principle so that small changes don’t have large impacts across the codebase.  Libraries, component based software, frameworks and APIs get lots of value from having classes adhere to the Open/Closed Principle.


Don’t Make Me Think

This is primarily to do with the readability of your solution.  Another developer should be able to easily understand the solution by reading the source code.  If they can’t understand the solution with a minimum of effort then there is most probably a call for more simplicity in the solution.

Here are some pointers to help improve readability:

  • Use comments where appropriate.
  • Don’t use hard to understand tricks.
  • Do give methods, variables, and constants meaningful names.
  • Follow a consistent coding standard (here is a blog about the Microsoft internal coding standards and a reference for the java coding standards)
  • If your unit tests are readable then your code will most probably be readable to.
  • Separate out your implementation details from your domain logic.
  • Use abstractions only when necessary (YAGNI and KISS)

Alberto Gutierrez has a good idea for a 5 minute readability test in his blog on how to write readable code

The 5 minutes explanation test.

Apart from using the previous 4 tips and some other guidelines you may think appropriate to create readable code, I like to pass the 5 minutes explanation test to my code to know how readable it is.

  1. Grab a fellow programmer who spares some time to review your code
  2. Walk him through your code, just a high level introduction.
  3. Ask him if he understood your code.

After following these steps you can evaluate how readable your code is based on how much it took you to explain it. I call it the 5 minutes explanation test because as a rule of thumb if it takes more than 5 minutes for the other programmer to have a high level idea of the design, assume that the code is not readable.


Do the simplest thing that could possibly work

I think the title has it, but to reiterate always ask yourself this question from Kent Beck:

What is the simplest thing that could possibly work?

When thinking of simplest think of the minimal solution needed to achieve the result.  Nothing fancy, just the bare minimum needed to achieve the task at hand or pass the unit test you have just written.  You aren’t looking for the quickest way you are looking for the simplest results.

The two words that seem to cause the most discussion are “simple” and “possible”  as they are open to interpretation.  “Simple” means different things for a developer buried in the problem space compared to a developer who is starting on the project today.  “Possible” will mean different things depending on the developer working on the solution and their comfort level with different solutions.

Also once you have implemented your simple solution you will need to then do appropriate refactoring along the lines of the other principles.

Some of the benefits of always doing the simplest things first

  • You get a result faster
  • It is easier to test your code
  • Refactoring is easier and faster to perform
  • It is easier to communicate your work to others
  • The ongoing maintenance cost of your code will be less

Here is a quote from Manuel Vidaurre which sums up the recursive nature of doing the simple thing first:

Another way to see this is if you did simple things first and those did not work well, then you should do the simplest thing in the rest of more complicated ones, and like this recursively to the infinitum…

Complex problems from renovations to building a rocket all start with small simple steps.  Programs are the same.  You may have a complex problem to solve, but you can solve that complex problem by breaking it into smaller, less complex, more manageable pieces.


You Aren’t Going To Need It (YAGNI)

This is from extreme programming – don’t add functionality until you need it.  Resist the urge to add things that you might need in the future.  Only implement things when you actually need them, never when you are only foreseeing the need for them.

Usually if you start adding things you don’t need at this point in time it is a sign that your focus has drifted from the actual problem you are trying to solve.

Remember that your time is a precious resource, to add the unnecessary feature you are going to need to take time away from the functionality that you need to be implementing.

This directly impacts the quality of your solution, increases code bloat, makes refactoring harder, and can in some cases restrict your ability to implement a necessary feature in the future.

From a testing point of view, until a feature is actually needed it is difficult to define what it should do and how it should be tested.  It might not even be needed at all or the actual feature needed might be completely different to what you implemented.

Then you have the worst case, adding the new feature leads to thinking of more new features that should be added, which are then added, creating a snowball effect also referred to as creeping featurism.

One of the benefits of only implementing new features when you need them is that your code remains simpler and simpler code is easier to maintain and refactor.

Remember that if you need to implement the feature in the future, provided you are following the appropriate practices, it should be just as easy to add it in the future when it is needed as it would be to add it now when it isn’t needed.


Keep It Simple, Stupid! K.I.S.S.

This principle is self descriptive.  As a software developer, reducing complexity and providing the simplest solution should always be a key goal.  Simple code is easier to test, faster to write, has fewer bugs and is generally easier to modify and understand.

This principle can be found represented in other statements throughout history:

  • Occam’s Razor: “simpler explanations are, other things being equal, generally better than more complex ones”
  • Albert Einstein: “everything should be made as simple as possible, but no simpler”
  • Leonardo Da Vinci: “Simplicity is the ultimate sophistication”
  • Antoine de Saint-Exupery: “It seems that perfection is reached not when there is nothing left to add, but when there is nothing left to take away”

Some examples of KISS not being followed in Software development are

  • Instruction Creep: This occurs when instructions increase over time in both size and number until they are unmanageable.  An example of this is a class file which is 5000 lines long or a single method which is 500 lines long but only started out at 30 lines of code.
  • Function Creep: Occurs when parts of the software designed for a specific purpose end up serving another purpose for which that code was never intended to perform.
  • Feature Creep: The ongoing addition of new features to a product that go beyond the basic function of the product resulting in over-complication.

How can you keep your software simple? Break problems down into the smallest possible pieces and then develop those pieces.  If you find yourself writing lots of exception cases when implementing a piece then probably you need to break that piece down further still.

Here are some things you might notice happening if you apply KISS to your day to day coding

  • Your code quality will be higher
  • You will be solving problems faster
  • Complex problems will be solved in fewer lines of code.
  • Your code should be easier to maintain
  • It will be easier for others to pick up your code and understand exactly what it does.

To start applying KISS to your day to day development, here are some steps that you can take

  • Break each task down into smaller tasks no more than 1 days effort, ideally a half day.
  • Take each problem and break it down into smaller problems.
  • Method size should be at most 30 to 40 lines.  Each method should be solving a single small problem (only have one purpose).
  • If a method contains many conditions refactor those out into smaller methods.
  • Each class should only have a single responsibility (this is its own principle).  Look at each method in a class and ask yourself “does it belong in this class? or should it be in its own class?”
  • First solve the problem and then implement the solution.  If you need to play with code to come up with a solution that is fine – writing unit test is a good way to think through a problem with the “how would I test this?” question.
  • Learn to love deleting code and refactoring.  You will send a lot of time refactoring while distilling your solution down to the simplest possible solution.

For more information on the benefits of KISS and ways to include it in your day to day development Richy Gerard has publish an interesting article on


Abstraction Principle

This principle goes with the DRY principle.  Within the application, each piece of functionality should be implemented in only in a single place.  Where similar functions are performed by disparate pieces of code it is better to have a single implementation and abstract out the differences.  The DRY principle is actually a generalisation of the Abstraction Principle.

Abstraction is the suppression of detail and a focus on concept.  The emphasis is placed on what an object is or does rather than the implementation.  This makes abstraction the primary means for managing complexity in large programs.

One of caveats of using Abstractions is do not introduce an abstraction unless you are going to use it more than once.  Do the simplest thing first.

One thing I have picked up from designing API’s that applies to abstractions in general is that you won’t iron out the majority of the issues with your abstraction until you have used it in anger in at least three different scenarios.

A common way to achieve reuse of an abstraction is to parameterise the implementation making use of interfaces to allow you to apply the abstraction to different implementations.

To explain Abstraction in one sentence just remember it allows you to answer “how is this done” with “I don’t care”.

Well this is a topic I will need to come back and redo once I’ve gotten better at getting past the 250 word barrier on my blog posts.  It has been a challenge stretching this topic past 250 words and in the end I only got there by talking about how hard it was to stretch the topic to 250 words. 😉

Hopefully the topic I chose tomorrow isn’t as hard to get past 250 words with. 🙂


DRY – Don’t Repeat Yourself

Also known as Duplication Is Evil (DIE)

This is the basis of all good programming, if you find yourself repeating code or concepts it is time to think about creating a new abstraction.

How does duplicate code come into existance?

Here are some ways that spring to mind:

  • Copy and paste.  The developer is on a tight deadline and needs xyz functionality in the new widget and its already in an existing widget.  The fast path to the result is copy and paste. Sometimes with a TODO to come back later and clean it up.
  • Easy and Fast.  It isn’t intellectually taxing to identify code that already does what you want, copy it, alter it slightly to suit the situation and then move onto the next task.  Duplicating existing code is the path of least resistance.
  • Didn’t realise the functionality already existed.  This could be two developers working on different features or one developer not realising they implemented the feature already several months back.
  • Boilerplate. Some frameworks and APIs, both in house and third party, require boilerplate code to be repeatedly re-written for each use of the framework/API.  This also falls under Copy and Paste.
  • Identical Concept – slightly different implementation.  Instead of enhancing the original implementation to cater for more scenarios a duplicate but slightly different implementation is created.

I am sure that there are a lot of other reasons and justifications for duplicating code – if you can think of some feel free to add them in the comments.

What are the down sides of code duplication? Each line of duplicated code is an increase in technical debt through code size, ongoing maintenance cost, and an increase in the complexity of the software.

For example: the same bug might exist in a method that has been duplicated 3 times.  Three different developers fix the bug in slightly different ways introducing three different side effects.

On of the easiest ways to improve the quality of code and ease of maintenance is to refactor out duplicate code.

The challenge though is detecting the duplicate code.  A couple of tools which can do this for you are

There are many more tools out there – a quick Google search will turn up other alternative tools.

If you have an automated build process build the tooling into your process and regularly review the reports it generates.  Make it a point to regularly go through and clean up duplicated code.  Even if you don’t have an automated build process you can manually run the tools across your code base at regular intervals to highlight duplicate code that can be cleaned up.

You get bonus points if you catch the duplicate code as you are working on new features, fixing defects, or reviewing another developer’s code.  As these are some of the least expensive times to find the duplicate code.