Looking at SOLID – Explained
It’s probably safe to assume that if you’re looking at this article, you have some understanding of what SOLID is. That’s my hope anyway, since this article is aimed at presenting the principles of SOLID in simple terms, to those that need to consolidate their understanding.
Each of the principles is reassuringly accompanied by PHP code examples, so that those who have no love for standalone text can also participate. Anyway, enough babbling, let’s jump right in.
Acronym | Meaning | Benefits |
---|---|---|
SRP | Single Responsibility Principle | Ensures classes are small, focused & simple. Improves maintainability & testability. |
OCP | Open/Closed Principle |
Single Responsibility Principle.
Fundamentally, the single responsibility principle is simple, stating that each class should have a single concern. The name itself almost explains the concept entirely, but it also raises some questions.
Sure, each class should have a single responsibility, but what exactly is a responsibility? How do we define it? Well, the champion of the phrase, Robert Martin, kindly provides us with an explanation, defining a responsibility as a reason to change a class.
Things that change for the same reasons, should be grouped together. Things that change for different reasons, should be separate…
This makes perfect sense really. A system grouping code by the reason of change certainly sounds more maintainable that one that does not, since it allows changes to separate pieces of functionality to be made independent of the rest of the application.
As an example, let’s say you have a class with many responsibilities and you need to make a particular amendment. You make the necessary changes & anticipating that it will impact a particular part of the application, you test that part. All looks well & you move on with your day. However, unbeknownst to you, another part of the application was dependent on the code, and has blown up completely. Doh.
Having maintained legacy applications myself, I can quite easily imagine such a scenario.
Let’s look at an example which will illustrate the point.
class Contact { protected $forename; protected $surname; protected $address1; protected $city; protected $country; protected function getName() { return $this->forename . $this->surname; } protected function validate() { if (strlen($this->forename) < 2) { return false; } return true; } }
There are two reasons a developer may want to change this class. The first being a change to how contacts are modeled, for example adding a new field (middle name, address2 etc). The second being a change to what is considered a valid contact, for example, using the code above, we may decide that a forename has to contain a minimum of 4 characters.
I can quite easily imagine two scenarios which could make use of this class. One being form processing, whereby the user fills out a form, submits the data, aft which point the data runs through the validate method. Another being simple information display, such as a list.
Imagine one day that we decide to change the validation, whilst doing so we mindlessly add some PHP that causes a fatal error (developers making mistakes? Unlikely I know). Anywhere making use of the class will now be broken and this raises the question, ‘why should the list be broken?’. After-all it’s not even making use of the validation logic. If the validation logic were separate, sure the form processing would still be gimped, but at least the list would be happily chugging along.
Let’s look at how we can separate these concerns.
class Contact { protected $forename; protected $surname; protected $address1; protected $city; protected $country; protected function getName() { return $this->forename . $this->surname; } } class ContactValidator { protected function validate(Contact $contact) { if (strlen($contact->forename) < 2) { return false; } return true; } }
Now, the contact class has a single responsibility – modeling contacts. The validation class also has a single responsibility – checking the validity of a contact. As well as avoiding maintenance problems (as described previously), this also makes our code more extensible. In this case, we now have the ability to define new validators should we ever need them.
I mentioned, Robert Martin earlier – remember, the fellow who came up with the phrase!? Well, here he is talking about the single responsiblity principle for a good 40 minutes. If you feel like you need to know more, what better place to start.
Open-Closed Principle.
The name ‘open-closed principle’ is slightly more cryptic than the previous example, and is also harder to grasp. In fact it’s probably one of the most misunderstood of the SOLID principles, so I’ll endeavor to explain it as clearly as possible. If I fail, do feel free to punish me with an abusive comment or two.
I guess a concise definition of the principle is a good enough starting point, and what better place for such a definition than Wikipedia.
software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification
And there we have it. Your software entities should be open for extension, but closed for modification. It’s safe to say that this is still somewhat ambiguous, so allow me to add my two-cents. In my opinion, OCP can be summed up in two points:
- A class should only ever be altered when its main function is being changed. If a new feature is being added, it should be done in such a a way that the original class is not modified. And more importantly, your programming style should enforce or at least encourage this.
- The public interface of a class should not be changed at all.
I’ll expand on these two points, but I’d first like to highlight the similarity between the first point and the Single responsibility principle. Stating that a class should only ever change when its main function changes heavily implies that the class should only have one responsibility. The difference, I believe, is the focus on how the new functionality should be added. Anyway, I guess my point is this, if you write code that adheres to the SRP, then there’s a good chance that it adheres to the OCP too. In the occasions that this is not true, then following SRP, will at least make it easier to adhere to OCP.
As mentioned earlier, I’d like to expand on the 2 points mentioned above. Let’s start with the first, and take a look and some code that does not adhere to OCP and then take a look at how we can improve it.
- class interface should not be changed (closed for modification), but it should still be possible to add additional functionality – programming against an interface.
- closely linked with srp, ‘gameplayer’ example from http://programmers.stackexchange.com/questions/43242/do-you-leverage-the-benefits-of-the-open-closed-principle
REferences:
=https://www.youtube.com/watch?v=KHBrDWIKW8Q
#http://en.wikipedia.org/wiki/Single_responsibility_principle
#http://russellallen.info/post/2011/09/08/The-Rules-Part-1-Single-Responsibility-Principle.aspx
#
#http://programmers.stackexchange.com/questions/43242/do-you-leverage-the-benefits-of-the-open-closed-principle
#http://programmers.stackexchange.com/questions/178488/lsp-vs-ocp-liskov-substitution-vs-open-close
#http://codeblog.jonskeet.uk/2013/03/15/the-open-closed-principle-in-review/
The post SOLID explained in simple terms with PHP examples. appeared first on Weebtutorials.