Introduction
The SOLID principles form the foundation of clean, scalable, and maintainable software development. Though these principles...
For further actions, you may consider blocking this person and/or reporting abuse
This is an interesting take on applying SOLID principles to non-OOP programming. Thanks for creating this!
I do have some disagreement with the examples, though.
LSP
While the idea of Liskov Substitution Principle is reasonable, the example provided I think does more to confuse the topic. While a button and a link are both clickable, they should not share a base class. To provide an OOP equivalent,
car
,cat
, andplanet
could all support themove
method, but I would not expect a common class between the three.We've misaligned "click" as the shared capability, mostly because it's one of the few common interactions. The link could be more accurately described with
navigate
and the button, depending on type, could be "submit" or "action".The idea of a
LinkButton
is incorrectly represented, mostly because we introduced action buttons that appear to be links in various design schemes, from Bootstrap'sben-tertiary
to Microsoft's Metro UI...whole vibe.LinkButton
should still be a button, with perhaps different styling.ISP
The Interface Segregation Principle React example is wholly confusing to me. The
MultiPurposeComponent
is accumulating the presentation of three already distinct components that show clear segregation of the interface. . The refactor does not provide equivalent functionality at all, simply wrapping the original components, but not creating any output. If the props come from one source, they "anti-pattern" will need to be recreated almost exactly as-is.If the original included the markup for each of the nested components, the example would have made sense, but it does not, here.
OCP (Nitpicking)
As a small note, in the OCP example, I would recommend reversing the order of arguments to
validate
. This is more a functional programming consideration, but if we wantvalidate
to operate as it did before, we need to pass the rules first, then accept the value. This could be done with Higher-order-functions (HOFs) or with currying...Thanks for your thoughtful feedback! I really appreciate the time you took to dig into the examples and share your perspective.
Regarding the Liskov Substitution Principle (LSP) example, you raise a valid point. The intention was to illustrate shared behavior, but I can see how the "click" interaction may have oversimplified the concept, particularly when applied to elements with different purposes like Link and Button. Your suggestion of focusing on distinct actions such as navigate and submit definitely clarifies this, and I’ll be refining this example.
For the Interface Segregation Principle (ISP), the aim was to highlight separation of concerns by breaking functionality into smaller, distinct components, but I understand how the current example didn’t reflect that clearly. I’ll revisit this to ensure the refactor reflects a clearer segregation of functionality.
As for the Open/Closed Principle (OCP), I appreciate your recommendation on using higher-order functions or currying to improve flexibility. I wanted to keep it simple, but your suggestion adds an additional layer of sophistication, and I’ll incorporate that into future revisions.
I value feedback like yours—it helps me continue to grow and improve the clarity of my explanations. Thanks again for taking the time to engage with the article!
Good
I enjoy refactoring the codebase and keeping it as clean as possible. During refactoring and code reviews, I provided feedback to my team, but I didn't consciously apply the SOLID principles at the time. Most of the SOLID principles were already part of my daily practice, but I wasn’t aware of them. However, after reading this article, I am now fully confident that when I review or write code, I will keep the SOLID principles in mind, maintain the codebase properly, and provide constructive feedback. Thank you, Wafa Bergaou
Thanks for your comment! I’m really happy to hear that the article helped make the SOLID principles clearer for you. It sounds like you’ve been applying them naturally, which is awesome! Now that you’re more aware of them, I’m sure your code reviews and refactoring will be even stronger. Feel free to reach out anytime, and thanks again for reading!
The SOLID principles have been introduced by Robert C. Martin (Uncle Bob) and reflect his experience of what he thinks could help people to use OOP for web development,
They do not necessarily apply to OOP in general, as many OOP projects do not follow this principles. Most core API´s like the Windows GDI implement large and deeply nestend hierarchies which surely violates the SOLID principles. But they are build with optimizing compilers that do tree shaking by default, so things are much different here.
I wonder if implementing a global state would be a better solution for the Dependency Inversion Principle (DIP) problem?
I'm no expert on SOLID but I think global state is misunderstanding the problem. You would still need the user slice of state. Rather than have the function get the slice, solid says you have a separate function that gets the slice and pass the function in as an argument. This means that if you have to change the shape of the user slice you only have to change the getter function and if you want a unit test you can use a different function that generates a static user, especially useful when you need to test validation rules as your real data source may not have real examples.
Excellent point! You're right—SOLID encourages decoupling functions from state retrieval. Rather than having a function directly access global state, a separate getter function can retrieve the slice. This approach simplifies testing and reduces the risk of breaking changes when the data structure evolves.
You have a point, thanks for the feedback!
Great question! While using global state (like Redux or context) can centralize data, it doesn't fully address the Dependency Inversion Principle (DIP). DIP emphasizes decoupling high-level and low-level modules via abstractions, often achieved with dependency injection. Global state could lead to tight coupling, making testing harder, especially for isolated logic.
👍
SOLID is just solid. 😉
Thanks for sharing.
You're welcome! Glad you found it helpful! 😊
That Button/Clickable example is not a refactor - wrapping them in a div with onClick is definitely not a good idea.
It's a contrived example. Buttons and A-tags are different elements with different purposes. There's no shared concern between these components - there's nothing to "fix".
Your LSP example for React is a really, really bad idea as far as accessibility and semantic html is concerned. A div should not be clickable in this way. I understand what you were getting at, but this is definitely not the example I'd include.
I chose the clickable
example to simplify illustrating the Liskov Substitution Principle (LSP) without introducing too many other elements that might distract from the concept. However, you’re right—this wasn’t the best approach for accessibility and semantic HTML. Using semantic elements like or would have maintained accessibility while still demonstrating LSP in a clearer, more appropriate way. I’ll be updating the example to align with best practices!