Blog | Dave Feltz Software Developer LLC

Independent Software Developer


Is Your Custom Software S.O.L.I.D.?

It is no longer good enough that custom software just works. To be considered a quality, reliable, maintainable product, it also needs to be properly engineered. In my opinion one of the most important aspects of well-engineered custom software is code that adheres to the S.O.L.I.D. design principles.

In this post I will provide a brief overview of the five S.O.L.I.D. software design principles.

S.O.L.I.D. Software Design Principles

S.O.L.I.D. is an acronym that stands for five principles of quality software engineering: Single Responsibility Principle, Open Closed Principle, Liskov Substitution Principle, Interface Segregation Principle, and Dependency Inversion Principle.

These five principles form an essential element of quality software engineering and adhering to them results in software that is easier to modify and maintain. Since software is supposed to be “SOFT”, meaning it is easy to change as business requirements change, building for easy modification is of utmost importance.

Single Responsibility Principle

Robert C. Martin in his book Clean Architecture describes The Single Responsibility Principle as “an active corollary to Conway’s law: The best structure for a software system is heavily influenced by the social structure of the organization that uses it so that each software module has one, and only one, reason to change” 1.

This means that a class (or module) should be focused on a single purpose or responsibility and have a single reason for changing.

As an example, let’s say you have two use cases that both are dependent on an “Employee” class. One of the use cases depends on the “Employee” from a management perspective and the other depends on the “Employee” from a payroll perspective. Implementing a single “Employee” class with functionality for both use cases would violate the Single Responsibility Principle because each use case has a unique reason to change; one could change due to employee management changes and the other could change due employee payroll changes.

A design keeping with the Single Responsibility Principle would implement two classes, possibly a “ManagedEmployee” and a “PaidEmployee”, for example.

Open Closed Principle

Robert C. Martin describes the Open Closed Principle this way: “for software systems to be easy to change, they must be designed to allow the behavior of those systems to be changed by adding new code, rather than changing existing code” 2.

Another way to describe the Open Closed Principle is to say that classes should be open for extension but closed for modification.

To illustrate why the Open Closed Principle is important, consider this example: you have a software application that is deployed and working correctly. Now you need to add new features but to do so you modify existing classes for the new functionality. Since the existing code depends on the classes you are modifying you risk breaking the existing code.

Extending the existing classes or adding new classes when more appropriate reduces the probability that implementing new features will break existing code. It also keeps the code simpler and easier to read and understand.

Liskov Substitution Principle

Robert C. Martin describes the Liskov 3 Substitution Principle as: “to build software systems from interchangeable parts, those parts must adhere to a contract that allows those parts to be substituted one for another” 4.

This means that classes should be designed so that they can be replaced in a program with objects of a sub-type of that class without modifying the functionality of the program.

As an example, imagine that you are building an application that models dogs. You have a base “Dog” class and a “GermanShepherdDog” sub class. If it is to comply with the Liskov Substitution Principle the application’s classes that depend on the “Dog” class must also be able to use the “GermanShepherdDog” sub class without functional modifications.

Interface Segregation Principle

Robert C. Martin says that the Interface Segregation Principle “advises software designers to avoid depending on things that they don’t use” 5,

Basically to comply with the Interface Segregation Principle classes should not implement methods or functions that they don’t use.

An example that violates the Interface Segregation Principle is class A and class B implementing an interface that defines three methods. Class B implements all three methods while class A only implements two of those methods. The third unused method in class A would be coded to throw an “UnsupportedOperationException” error or just do nothing, thus violating the Interface Segregation Principle.

A better approach would be to create two interfaces, one with the two methods used by both class A and B, and the other with the third method only used by class B.

Dependency Inversion Principle

Robert C. Martin in his book Clean Architecture describes the Dependency Inversion Principle as: “the code that implements high-level policy should not depend on the code that implements low-level details. Rather, details should depend on the policies” 6.

I like to think of the Dependency Inversion Principle as having two parts:

  1. High-level code that depends on lower level code should use an abstraction that the lower level code implements.
  2. The abstraction implemented by the lower level code should not depend on details (it should be abstract) but instead the lower level code should implement the details.

Complying with the Dependency Inversion Principle means that your high-level classes should specify an interface that the low-level concrete classes implement with the details, thus inverting the dependency.

This allows for modification or replacement of the low-level classes without modifications to the high-level classes, provided that the abstraction doesn’t change. The concrete low-level classes become more like replaceable parts simplifying future changes.

Conclusion

Every software engineer should understand and build their code in compliance with the S.O.L.I.D. principles. I have encountered many code bases that were built with no regard to good software engineering fundamentals making changes difficult and risky.

For more information on the S.O.L.I.D. principles I recommend the available course on Pluralsight (pluralsight.com). Also, Robert C. Martins book “Clean Architecture: A Craftsman’s Guide to Software Structure and Design” is a great resource for more information on the S.O.L.I.D. principles as well as quality software architecture in general.

References

  1. Martin, Robert C. (2018). Clean Architecture: A Craftsman’s Guide to Software Structure and Design” p. 58 ISBN 978-0-13-449416-6
  2. Martin, Robert C. (2018). Clean Architecture: A Craftsman’s Guide to Software Structure and Design” p. 59 ISBN 978-0-13-449416-6
  3. Wikipedia – “Barbara Liskov” https://en.wikipedia.org/wiki/Barbara_Liskov Retrieved 2021-10-20.
  4. Martin, Robert C. (2018). Clean Architecture: A Craftsman’s Guide to Software Structure and Design” p. 59 ISBN 978-0-13-449416-6
  5. Martin, Robert C. (2018). Clean Architecture: A Craftsman’s Guide to Software Structure and Design” p. 59 ISBN 978-0-13-449416-6
  6. Martin, Robert C. (2018). Clean Architecture: A Craftsman’s Guide to Software Structure and Design” p. 59 ISBN 978-0-13-449416-6