Simple PHP Guide to S.O.L.I.D Design Principles
15 minsS.O.L.I.D is a coding standard that all PHP developers should be familiar with when undertaking Magento module development. It was introduced over a decade ago by Robert C Martin (Uncle Bob) and is used across the object-oriented design spectrum. Why use these principles I hear you ask? When applied properly it makes your code more extendable, logical and easier to read.
I’m going to try and keep this as jargon-free as possible so it’s easy for beginners to understand. Let’s go through each principle one by one:
S: Single Responsibility Principle
Each class should have one responsibility and one responsibility only. This means that all the methods and properties should all work towards the same goal.
Lets take the following simple class as an example of how this principle may be violated:
This may be fine for printing information to the frontend but what about if you need to get that information in JSON or as an array? You use classes or interfaces with defined roles, thus separating the business logic from the presentation layer:
We then may have an interface for retail customers that must return the data as a string.
We may have the trade interface to return this data as an array:
O: Open-closed Principle
In a nutshell your classes should be extendable without actually changing the contents of the class you’re extending. Here’s a very basic example of how this principle can be violated if we had to introduce another customer type:
The way around this would be to use interfaces as in the previous principle:
L: Liskov Substitution Principle
This principle basically specifies that child classes should be suitable for their parent classes. This means it will adhere to the principles and functionality of the class it extends.
The instrument class may behave as an abstract and could be implemented in the following ways:
I: Interface Segregation Principle
This principle is probably the simplest in terms of theory. A client should not be forced to use interfaces that it doesn’t need. Here’s an example of violation of this principle:
The Trumpet class has autoTune() and plugIn() forced upon it - I’m not saying that there’s no plugin-in trumpets out there but in this case I’m talking about a standard acoustic trumpet. An ISP-safe method is to create an interface for each of the instruments that employs only the methods needed for the client:
D: Dependency Inversion Principle
This principle states that high level modules should not depend on low level modules. High level modules should never change and should be decoupled (seperated) from low level modules that could be changed on a daily basis.
The introduction of dependency injection in Magento 2 has made this principle easier to adhere to, as it is now clear which classes and clients are dependent on each other.
Take the example below which shows a rather limited example of higher level code being dependent on lower level code:
This does the job, but the class is completely dependent on us always counting apples. There are other fruits out there kids! We should make our counting class more general:
The end result is code that is less dependent on the lower level code with which it is working. You could take this much further than the example above but the theory is the same.
I hope I have kept this simple enough for beginner OOPHP developers to understand. Thanks for reading.