The SOLID prin­ci­ples consist of five guide­lines for clean, main­tain­able and flexible code in object-based pro­gram­ming. Applying and adhering to the prin­ci­ples results in easy-to-un­der­stand software design over long de­vel­op­ment periods. With these prin­ci­ples, not only can better code be written, but existing code can also be main­tained more easily.

What are the SOLID prin­ci­ples and who developed them?

Good source code starts with rules, pro­gram­ming paradigms and a suitable pro­gram­ming style for efficient and clean code. This is exactly what the five SOLID prin­ci­ples, coined by Robert C. Martin, Bertrand Meyer and Barbara Liskov, ensure. By following these prin­ci­ples in object-oriented pro­gram­ming (OOP) with languages such as Python or Java, you not only write better code, but you also ensure more efficient code main­te­nance, sus­tain­able and flexible software design and greater security in the long term.

The name SOLID is rep­re­sen­ta­tive of the solid pro­gram­ming foun­da­tion that anyone who wants to learn pro­gram­ming should have. The acronym itself was created by Michael Feathers, who took the first letters of each of the five prin­ci­ples to create it:

  • Single Re­spon­si­bil­i­ty Principle: A class should have one, and only one, reason to change.
  • Open-Closed Principle: Software entities (classes, modules, functions, etc.) should be open for extension, but closed for mod­i­fi­ca­tion.
  • Liskov Sub­sti­tu­tion Principle: Sub­class­es should be able to inherit and implement all methods and prop­er­ties of the su­per­class.
  • Interface Seg­re­ga­tion Principle: In­ter­faces should not contain more methods than are required for im­ple­ment­ing classes.
  • De­pen­den­cy Inversion Principle: Classes should not depend on other classes, but on in­ter­faces or abstract classes.

What benefits do the SOLID prin­ci­ples offer?

Where there are no rules, chaos ensues, and this becomes par­tic­u­lar­ly no­tice­able when pro­gram­ming. Even small errors, in­ac­cu­ra­cies and gaps can make good source code com­plete­ly unusable in the long term if left “untreated”. Sometimes all it takes is complex classes that make im­ple­men­ta­tion difficult or sub­class­es that lack in­di­vid­ual prop­er­ties of their su­per­class­es. The SOLID prin­ci­ples ensure that as little code as possible needs to be repaired with refac­tor­ing.

SOLID prin­ci­ples make code:

  • Clear, clean and at­trac­tive: Software and codes are easier to un­der­stand, more effective and simply look better.
  • Easy to maintain: The straight­for­ward and clear structure makes it simpler for multiple col­lab­o­ra­tors to maintain and manage both new code and legacy code.
  • Cus­tomiz­able, ex­pand­able, reusable: Through improved read­abil­i­ty, reduced com­plex­i­ties and re­spon­si­bil­i­ties, and decreased de­pen­den­cies on classes, code can be better edited, adapted and expanded through in­ter­faces, and flexibly reused.
  • Less error-prone: Clean code with a simple structure means that changes to one part of the code do not ac­ci­den­tal­ly affect other areas or functions.
  • Secure and more reliable: Reducing or elim­i­nat­ing vul­ner­a­bil­i­ties, in­com­pat­i­bil­i­ties and errors enhances a systems’ func­tion­al­i­ty and de­pend­abil­i­ty, which in turn improves security.

What do each of the SOLID prin­ci­ples mean?

The SOLID prin­ci­ples belong to the golden rules for good pro­gram­ming and should be familiar to anyone that works in object-based pro­gram­ming. Below we’ll explain each principle in detail.

SRP: Single Re­spon­si­bil­i­ty Principle

Robert C. Martin created the original de­f­i­n­i­tion for this principle in “Agile Software De­vel­op­ment: Prin­ci­ples, Patterns and Practices”; writing:

Quote

“Each software module should have one and only one reason to change.”

The Single Re­spon­si­bil­i­ty Principle (SRP) states that each class in object-oriented pro­gram­ming (OOP) should have only one re­spon­si­bil­i­ty. This implies there should only be one reason to modify a class. Contrary to common in­ter­pre­ta­tions, this does not mean that a class or module can only have exactly one task. Rather, it means that it should only be re­spon­si­ble for specific tasks that ideally do not overlap with other areas.

An overlap of re­spon­si­bil­i­ties, such as offering functions for various business segments, might impact the class’s func­tion­al­i­ty when mod­i­fi­ca­tions are made in one segment. Holding multiple re­spon­si­bil­i­ties and numerous de­pen­den­cies may cause a single change in one area to bring about code errors or the need for ad­di­tion­al changes.

The Single Re­spon­si­bil­i­ty Principle (SRP) is designed to create cohesive modules tasked with specific, well-defined functions or objects. Thanks to its clear, struc­tured setup with minimal de­pen­den­cies and in­de­pen­dent im­ple­men­ta­tions, mod­i­fi­ca­tions and ad­just­ments can be made more ef­fi­cient­ly, swiftly and smoothly.

Note

Classes, also known as object types, are the central elements in object-oriented pro­gram­ming (OOP). They can be seen as blue­prints for objects, outlining their at­trib­ut­es so that it’s possible to recreate real-world objects and concepts in software. Classes, also known as modules, are often compared to file types.

OCP: Open Closed Principle

According to Robert C. Martin and Bertrand Meyer in “Object Oriented Software Con­struc­tion”, the OCP states:

Quote

“Software entities (classes, modules, functions, etc.) should be open for extension, but closed for mod­i­fi­ca­tion.”

The OCP ensures that you do not have to rewrite software at its core in order to implement changes. If in-depth code mod­u­la­tions are required, there is a risk of subtle errors and code smells. A well-struc­tured code should provide in­ter­faces that can be used to extend it with ad­di­tion­al functions. The keyword here is class in­her­i­tance.

New features and ex­ten­sions with clear new functions and methods that need to be im­ple­ment­ed can be easily added to a su­per­class via an interface in the form of sub­class­es. This way, you don’t have to tamper with the written, stable code. It sim­pli­fies the main­te­nance and upkeep of software and sig­nif­i­cant­ly improves the ef­fi­cien­cy of reusing stable code elements via in­ter­faces.

LSP: Liskov’s Sub­sti­tu­tion Principle

According to Barbara H. Liskov and Jeannette M. Wing in “Be­hav­ioral Subtyping Using In­vari­ants and Con­straints”, the LSP states that:

Quote

“Let q(x) be a property provable about objects x of type T. Then q(y) should be provable for objects y of type S where S is a subtype of T.”

It may sound cryptic, but it’s actually quite easy to un­der­stand: Linked or extended sub­class­es must function like their su­per­class­es or base classes. This means that each subclass must retain the prop­er­ties of its re­spec­tive su­per­class through in­her­i­tance and these prop­er­ties must not be changed in the subclass. They must be re­place­able in principle, hence the sub­sti­tu­tion principle. Su­per­class­es, on the other hand, may be modified.

To explain, let’s look at the classic example from Robert C. Martin about rec­tan­gles and squares. In geometry lessons, we learn the following principle: every square is a rectangle, but not every rectangle is a square. A square not only has right-angled sides like rec­tan­gles do, but all its sides are also equal in length.

In pro­gram­ming, assuming that similar or seemingly identical classes are related or dependent on each other leads to errors, mis­un­der­stand­ings and unclear code. For this reason, in pro­gram­ming, the class “Rectangle” is not a square, and the class “Square” is not a rectangle. Both are decoupled and im­ple­ment­ed sep­a­rate­ly. Without an in­te­grat­ed con­nec­tion between the classes, mis­un­der­stand­ings cannot lead to errors across classes. This enhances the security and stability when swapping im­ple­men­ta­tions in sub­class­es or su­per­class­es, without reper­cus­sions.

ISP: Interface Seg­re­ga­tion Principle

According to Robert C. Martin in “The Interface Seg­re­ga­tion Principle”, the ISP is defined as follows:

Quote

“Clients should not be forced to depend upon in­ter­faces that they do not use.”

The ISP states that users should not have to use in­ter­faces that they do not need. In other words: In order to provide clients with the functions of certain classes, new, smaller in­ter­faces are tailored to specific re­quire­ments. This prevents in­ter­faces from becoming too large and ensures that strong de­pen­den­cies don’t form between classes. The advantage is that software with decoupled classes and several small in­ter­faces tailored to specific re­quire­ments is easier to maintain.

DIP: De­pen­den­cy Inversion Principle

According to Robert C. Martin in “The De­pen­den­cy Inversion Principle”, the fifth and last of the SOLID prin­ci­ples, is as follows:

Quote

“A. High-level modules should not depend on low-level modules. Both should depend on ab­strac­tions. B. Ab­strac­tions should not depend upon details.”

The DIP ensures that specific func­tion­al­i­ties and de­pen­den­cies within source code layers rely on abstract in­ter­faces, not directly on each other. Software ar­chi­tec­tures are typically organized into higher user levels and lower, more abstract levels. Logically, one might think that the abstract foun­da­tion in­flu­ences the behavior of the upper layers. However, the DIP iden­ti­fies a potential issue here, as it creates de­pen­den­cies for the higher levels on the lower levels, which can lead to problems.

Instead of linking higher levels to lower levels, classes in high and low levels should depend on abstract, in­ter­me­di­ate in­ter­faces. The in­ter­faces retrieve func­tion­al­i­ties that are required at higher levels from lower levels and make them available. In this way, a bottom-up hierarchy of de­pen­den­cies can be avoided, which can lead to errors in the code over time. This fa­cil­i­tates the reusabil­i­ty of modules and enables changes to lower classes without affecting higher levels.

Web Hosting
Hosting that scales with your ambitions
  • Stay online with 99.99% uptime and robust security
  • Add per­for­mance with a click as traffic grows
  • Includes free domain, SSL, email, and 24/7 support

What happens if the SOLID prin­ci­ples aren’t adhered to?

Creating clean, readable code that sim­pli­fies main­te­nance should be a primary aim in software de­vel­op­ment. If de­vel­op­ers overlook essential guide­lines like the SOLID prin­ci­ples, the code can degrade severely due to vul­ner­a­bil­i­ties, re­dun­dan­cies, ac­cu­mu­lat­ed errors and excessive de­pen­den­cies. In extreme cases, the code might become unusable as time passes. This is a sig­nif­i­cant issue in agile software de­vel­op­ment, where many people often work on complex coding tasks.

The con­se­quences of unclean code or poor code main­te­nance include:

  • Code smell: When code isn’t written in ac­cor­dance with the necessary standards, this can cause code smell or “smelly code”, leading to func­tion­al errors and in­com­pat­i­ble programs.
  • Code rot: If it is not main­tained or repaired by refac­tor­ing or a costly code review, code can fig­u­ra­tive­ly “rot” and com­plete­ly lose its func­tion­al­i­ty. Another term for un­read­able, con­vo­lut­ed code is spaghetti code.
  • Security Risks: The issues that arise aren’t limited to outages, complex upkeep and com­pat­i­bil­i­ty problems. There are also security gaps that provide malware with op­por­tu­ni­ties to exploit the code, including zero-day exploits.

Who developed the SOLID prin­ci­ples?

The origin of the SOLID prin­ci­ples lies in several prin­ci­ples first in­tro­duced by Robert C. Martin (“Uncle Bob”), one of the ini­tia­tors of agile pro­gram­ming, in the year 2000 in his essay titled “Design Prin­ci­ples and Design Patterns”. The SOLID prin­ci­ples were coined by Robert C. Martin, Bertrand Meyer and Barbara Liskov. The catchy acronym was pop­u­lar­ized by Michael Feathers, who re­arranged the initial letters of the five essential prin­ci­ples into a memorable order.

What similar pro­gram­ming prin­ci­ples are there?

In software de­vel­op­ment, prin­ci­ples are general or very specific guide­lines and rec­om­men­da­tions for action. In addition to the SOLID prin­ci­ples, which were developed for object-oriented pro­gram­ming, other pro­gram­ming prin­ci­ples for clean code include:

  • DRY principle (Don’t repeat yourself) for functions with a single, unique rep­re­sen­ta­tion
  • KISS principle (Keep it simple, stupid) for code con­struct­ed as simply as possible
Go to Main Menu