SOLID

Single responsibility

The single responsibility principle[Robert C. Martin] describes a way of developing your software, specifically in the object orientated world, what a module should do or 'who the module should effect'.
If we follow the separation of concerns[Dijkstra], which essentially means to break a class or module into 'what it concerns', then the next issue is what do we mean by concerns? Robert C. Martin brings in the notion of the principle being about people.
In the highly modular, large and unbelievably complex software of today at no other time has this principle become so important. I could not put it better than the following from Robert C. Martin:
You want to isolate your modules from the complexities of the organization as a whole, and design your systems such that each module is responsible (responds to) the needs of just that one business function.
This is the reason we do not put SQL in JSPs. This is the reason we do not generate HTML in the modules that compute results.
Gather together the things that change for the same reasons. Separate those things that change for different reasons.

Open/closed

This principle originally comes from Bertrand Meyer who stated: Software entities (classes, modules, functions, etc.) should be open for extension but closed for modification... this now seems a little outdated with the undertanding being that a module should be open for expanding (having new properties, functions...) but closed when management had 'signed off' and the module could no longer be altered.
This seems a little counter-intuitive and is the restrictive Waterfall method.
Robert C. Martin argues : You should be able to extend the behavior of a system without having to modify that system.
He, also, argues that the many coding authors write pluggins for Minecraft, Visual Studio, Eclipse etc and that they have proved that it is possible to write code that can follow the open/closed principle.
A beautiful example, by Robert C. Martin which shows the modern approach, which is to abstract any definites so as to ensure they can be altered without changing any of the existing code.
Therefore, when your team lead says to refactor (then it's too late!) and when you refactor create an abstraction for your current requirements with 'an eye for the future' and ensuring that you could add to you abstraction without changing any of the existing code.

Liskov substitution

The Liskov substitution principle is defined as:
If S is a declared subtype of T, objects of type S should behave as objects of type T are expected to behave, if they are treated as objects of type T.
The Liskov substitution principle takes a little time to understand but in essence a function or method of a module should not do something unexpected.
For example: if a base module with an Add function was implemented without throwing an exception, then all the clients of the base module don't expect an expection to be thrown. But, if I decide it's good practice to throw an expection in my implementation, then I've broken the Liskov principle and the existing clients won't know about my 'perfect' implementation and will not have catered for the exception. The results disasterous the application will break somewhere else and in a large application the trouble-shooting of the problem could take a lot of resources and time. The 'fix' may cause other problems as the developers don't know where the actual problem lies and may refactor existing code, which, well, has now also broken the open/closed closed principle!

Interface segregation

The interface segregation principle is simply:
Clients should not be forced to depend on methods that they do not use.[Robert C. Martin]
I'm as guilty as any developer of writing 'fat interfaces' and it's sometimes not easy to concoct an interface that doesn't become non-cohesive. Martin Fowler brings in the notion of the RoleInterface which quite succintly solves the problem but requires writing interfaces for every role. Robert C. Martin requires multiple inheritence or the use of the Adapter pattern which can turn out quite ugly.
This is one of the most obvious of the SOLID design principles but seems, the hardest to achieve, with no really solution apart from (I suppose) try to keep you interfaces relevant (to the role) and as small as possible.

Dependency injection

The final principle, dependency injection has implications structurally from the open/closed and Liskov substition principles.
From Robert C. Martin ...The structure [open/closed and Liskov substition] that results from rigorous use of these principles can be generalized into a principle all by itself. I call it 'The Dependency Inversion Principle'...
The principle is an effort to prevent 'Bad Design', which are:

  • Rigidity: The inabilty to change the system.
  • Fragility: When a change is made, the system breaks in unexpected places.
  • Immobility: Repeatablity of any part of the application isn't possible without disentangling a mess of code.
To help prevent 'Bad Design' dependency injection was conceived and is defined as:
  • High level modules should not depend upon low level modules. Both should depend upon abstractions.
  • Abstractions should not depend upon details. Details should depend on abstractions.
Robert C. Martin continues in his paper to decribe the reason for the name dependency inversion, it's because Dependency is transistive and we ultimately want the higher level not to be dependent on the lower level and to use a method be it constructor, properties etc to abstract away the lower layer so that it can be changed in the future and as long as the open/closed and Liskov substition principles haven't been violated then the system generally will not be of 'Bad Design'.

Summary

After writing this short article I realised that the HTML formating and background PHP that produce this page have violated most of SOLID. It would take a little effort to correct this and sometimes I find myself in overwhelming pressure from customers to finish a project as quickly as possible. They have no care for what patterns, principles or methods I use, they want they're software system up-and-running as soon as possible. These days it's so easy to copy (ctrl C) and paste (ctrl V) and refactor. I've even been told by some large high-tech banks to copy and paste someones code into whatever I'm working on. Sometimes I argue, that it violates SOLID which is one of the questions they asked me to land this contract but they look at me non-plussed and instruct me to 'get on with it' (I've even been threatened!).
The long and the short of it is, that if customers want good, scalable and stable software then they have to agree to use SOLID and the inherit extra resources and time it takes.

References

wiki
Single responsibility wiki
Single responsibility Robert C. Martin
Dijkstra
Parnas
Open/closed wiki
Open/closed Uncle Bob
Open/closed Robert C. Martin
Liskov wiki
Liskov ppt
Interface segregation principle
Interface segregation Robert C. Martin
Interface segregation David Hayden
Cohesion wiki
RoleInterface Martin Fowler
Dependency inversion wiki
Dependency inversion Robert C. Martin
Dependency inversion Aspiring Craftsman
Robert C. Martin
Bertrand Meyer
Martin Fowler
Barbara Liskov