Most, if not all of you, are aware of the SOLID principles. How many of you apply them day to day?
To help you understand how you can implement SOLID principles, I’m not going to recount the same descriptive lines you’ll find on every other SOLID blog post. Instead, I’m going to give you examples. To understand SOLID principles, I suggest reading these articles:
A toaster has toggles to change the length of time the bread stays in the toaster; it has buttons to eject the toast early. Each of those pieces all directly affects the primary operation of the toaster, to toast your bread! Toasting your bread is the only thing the toaster does, it doesn’t make your coffee too!
All methods on an object should directly contribute to the primary outcome of the object, of which there should be exactly one.
Open (to extension), Closed (to modification)
A package holiday includes certain things: a hotel, travel arrangements, etc. The travel company cannot remove those expected items. Open to extension means that the travel company can add additional items. For example they could throw in a complimentary car for your holiday at no cost to you.
If you have a “SaveCustomer” method, you shouldn’t stop it from saving a customer (closed to modification). You could add another step to send a welcome email (open to extension). Open closed applies at all levels, e.g. Don’t modify an interface or class by removing methods or changing method signatures, instead add new methods or overloads of existing methods.
Liskov Substitution states that you should be able to substitute an object for any descendant object without your implementation knowing any different. A descendant object is an object that inherits from another object and extends it. E.g. List inherits from and extends IEnumerable.
A particular taxi app offers these options: standard (base type), large (fit’s larger groups) (descendant), and executive (descendant), etc. The company must send a car that fit’s larger groups if you choose the large option. The only requirement of the standard option is for a car that can get you from A to B. Any car, whether from the standard, large or executive options fulfills that requirement as the other options inherit and extend from the standard option.
Car manufacturers offer many different options on their cars, and most aggregate these options into common “packs,” e.g. A winter pack with heated steering wheel and front windscreen. You’re not forced to choose from packs that have options you’re not going to use, as you can choose individual options.
You shouldn’t offer interfaces that are a “pack” of options. You should have each option in its own interface so that people inheriting from them later down the line can choose the options they require. This means you are not implementing functionality you don’t need or paying for options you are not interested in.
Dependency inversion is an object not creating other objects that it relies upon; Instead, they’re passed in by an outside source, e.g. relying on an email service interface and the email service object being passed in by your dependency injection container. Another example is relying on an IEnumerable in a method parameter and the calling method passing in a List.
When you book a hotel room (an object you rely on), you’re relying on the hotel (an outside source) providing you with a room on your arrival.
The SOLID principles are a set of guidelines; because of this, they mean different things to every person. They will mean different things to you throughout your career. As your experience grows and changes, you’ll change how you apply them, but applying them is the important step.
The most effective method to keep code quality high is by creating well designed code because you don’t always have time to refactor the code later.