Chances are, if you are using test driven development, or regularly dabble with OOP design, you have implemented one or more of the SOLID principles, possibly without even knowing it. The SOLID principles are by no means a new concept, but it’s gaining traction within the PHP community. If you have a look at the Zend Framework v2.0 or Symfony 2 projects, you will see many of the principles applied.
The SOLID principles are:
- S – Single Responsibility Principle
- O – Open/Closed Principle
- L – Liskov Substitution Principle
- I – Interface Segregation Principle
- D – Dependency Inversion Principle
I’ve found a strong correlation between the SOLID principles and a practice called Object Calisthenics, an idea from Jeff Bay detailed in the book, The ThoughtWorks Anthology. Some of the rules in Object Calisthenics compliment the SOLID principles very well, I will refer to the rules when this is the case. In short, without going in too much detail, here are the 9 rules of Object Calisthenics:
- Use only one level of indentation per method
- Don’t use the else keyword
- Wrap all primitives and strings
- Use only one dot per line
- Don’t abbreviate
- Keep all entities small
- Don’t use any classes with more than two instance variables
- Use first-class collections
- Don’t use any getters/setters/properties
The SOLID principles focus on Dependency Management. I’m sure as developers, we’ve all been victims of projects with poor dependency management – changing code in one part of the system breaks code in another part; Re-using code is difficult or impossible; Classes and methods are huge and often it’s hard to tell what they’re supposed to be doing. The SOLID principles are ways to reduce the likelihood of this of happening. Unlike design patterns which guide you to a solution, the SOLID principles can be used as a guide to prevent problems.
In this article, I will cover the first of the SOLID principles, the Single Responsibility Principle – “A class should have one, and only one, reason to change”. This is basically the same as “cohesion”, or writing classes with “high cohesion”. So, why is this important? If a class has more than one responsibility, there is more than one reason for it to change. This leads to very volatile classes which of course could affect any other classes that depend on it. See also Object Calisthenics, rules 6 and 7.
It is often easy to spot classes that fail this principle as they often contain words like “Manager”, or “Handler”. When implementing SRP, classes become more specific and focussed and the class names reflect the single responsibility of the class, e.g. EmployeePayrolCalculator.
So how do you go about refactoring your code to implement this principle? Begin by implementing the principle in your methods – refactor your methods to 5-7 lines, one block of indentation and a single responsibility per method (see rule 1 and 2 of Object Calisthenics). Once you have refactored your methods, ask yourself how many reasons does your class have to change? If the database schema changes, does it affect your class? And if the business rules change? How about a user interface change? If you establish more than one reason for change, refactor the class into two or more classes until you are happy that all your classes only have one responsibility.
In the next article – The Open Closed Principle.