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

What are the SOLID prin­ciples 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­ciples, coined by Robert C. Martin, Bertrand Meyer and Barbara Liskov, ensure. By following these prin­ciples 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­ten­ance, sus­tain­able and flexible software design and greater security in the long term.

The name SOLID is rep­res­ent­at­ive of the solid pro­gram­ming found­a­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­ciples to create it:

  • Single Re­spons­ib­il­ity 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 modi­fic­a­tion.
  • Liskov Sub­sti­tu­tion Principle: Sub­classes should be able to inherit and implement all methods and prop­er­ties of the su­per­class.
  • Interface Se­greg­a­tion Principle: In­ter­faces should not contain more methods than are required for im­ple­ment­ing classes.
  • De­pend­ency Inversion Principle: Classes should not depend on other classes, but on in­ter­faces or abstract classes.

What benefits do the SOLID prin­ciples offer?

Where there are no rules, chaos ensues, and this becomes par­tic­u­larly no­tice­able when pro­gram­ming. Even small errors, in­ac­curacies and gaps can make good source code com­pletely unusable in the long term if left ‘untreated’. Sometimes all it takes is complex classes that make im­ple­ment­a­tion difficult or sub­classes that lack in­di­vidu­al prop­er­ties of their su­per­classes. The SOLID prin­ciples ensure that as little code as possible needs to be repaired with re­fact­or­ing.

SOLID prin­ciples make code:

  • Clear, clean and at­tract­ive: 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­or­at­ors to maintain and manage both new code and legacy code.
  • Cus­tom­is­able, ex­pand­able, reusable: Through improved read­ab­il­ity, reduced com­plex­it­ies and re­spons­ib­il­it­ies, and decreased de­pend­en­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­dent­ally affect other areas or functions.
  • Secure and more reliable: Reducing or elim­in­at­ing vul­ner­ab­il­it­ies, in­com­pat­ib­il­it­ies and errors enhances a systems’ func­tion­al­ity and de­pend­ab­il­ity, which in turn improves security.

What do each of the SOLID prin­ciples mean?

The SOLID prin­ciples 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­spons­ib­il­ity Principle

Robert C. Martin created the original defin­i­tion for this principle in ‘Agile Software De­vel­op­ment: Prin­ciples, Patterns and Practices’; writing:

Quote

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

The Single Re­spons­ib­il­ity Principle (SRP) states that each class in object-oriented pro­gram­ming (OOP) should have only one re­spons­ib­il­ity. This implies there should only be one reason to modify a class. Contrary to common in­ter­pret­a­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­spons­ible for specific tasks that ideally do not overlap with other areas.

An overlap of re­spons­ib­il­it­ies, such as offering functions for various business segments, might impact the class’s func­tion­al­ity when modi­fic­a­tions are made in one segment. Holding multiple re­spons­ib­il­it­ies and numerous de­pend­en­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­spons­ib­il­ity 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­pend­en­cies and in­de­pend­ent im­ple­ment­a­tions, modi­fic­a­tions and ad­just­ments can be made more ef­fi­ciently, 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­utes 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 modi­fic­a­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­it­ance.

New features and ex­ten­sions with clear new functions and methods that need to be im­ple­men­ted can be easily added to a su­per­class via an interface in the form of sub­classes. This way, you don’t have to tamper with the written, stable code. It sim­pli­fies the main­ten­ance and upkeep of software and sig­ni­fic­antly improves the ef­fi­ciency 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­ha­vi­or­al 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­classes must function like their su­per­classes or base classes. This means that each subclass must retain the prop­er­ties of its re­spect­ive su­per­class through in­her­it­ance 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­classes, on the other hand, may be modified.

To explain, let’s look at the classic example from Robert C. Martin about rect­angles 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 rect­angles 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­men­ted sep­ar­ately. Without an in­teg­rated 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­ment­a­tions in sub­classes or su­per­classes, without re­per­cus­sions.

ISP: Interface Se­greg­a­tion Principle

According to Robert C. Martin in ‘The Interface Se­greg­a­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­pend­en­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­pend­ency Inversion Principle

According to Robert C. Martin in ‘The De­pend­ency Inversion Principle’, the fifth and last of the SOLID prin­ciples, 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­it­ies and de­pend­en­cies within source code layers rely on abstract in­ter­faces, not directly on each other. Software ar­chi­tec­tures are typically organised into higher user levels and lower, more abstract levels. Logically, one might think that the abstract found­a­tion in­flu­ences the behaviour of the upper layers. However, the DIP iden­ti­fies a potential issue here, as it creates de­pend­en­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­it­ies that are required at higher levels from lower levels and make them available. In this way, a bottom-up hierarchy of de­pend­en­cies can be avoided, which can lead to errors in the code over time. This fa­cil­it­ates the re­usab­il­ity of modules and enables changes to lower classes without affecting higher levels.

Web hosting
The hosting your website deserves at an un­beat­able price
  • Loading 3x faster for happier customers
  • Rock-solid 99.99% uptime and advanced pro­tec­tion
  • Only at IONOS: up to 500 GB included

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

Creating clean, readable code that sim­pli­fies main­ten­ance should be a primary aim in software de­vel­op­ment. If de­velopers overlook essential guidelines like the SOLID prin­ciples, the code can degrade severely due to vul­ner­ab­il­it­ies, re­dund­an­cies, ac­cu­mu­lated errors and excessive de­pend­en­cies. In extreme cases, the code might become unusable as time passes. This is a sig­ni­fic­ant issue in agile software de­vel­op­ment, where many people often work on complex coding tasks.

The con­sequences of unclean code or poor code main­ten­ance include:

  • Code smell: When code isn’t written in ac­cord­ance with the necessary standards, this can cause code smell or ‘smelly code’, leading to func­tion­al errors and in­com­pat­ible programs.
  • Code rot: If it is not main­tained or repaired by re­fact­or­ing or a costly code review, code can fig­ur­at­ively ‘rot’ and com­pletely lose its func­tion­al­ity. Another term for un­read­able, con­vo­luted code is spaghetti code.
  • Security risks: The issues that arise aren’t limited to outages, complex upkeep and com­pat­ib­il­ity problems. There are also security gaps that provide malware with op­por­tun­it­ies to exploit the code, including zero-day exploits.

Who developed the SOLID prin­ciples?

The origin of the SOLID prin­ciples lies in several prin­ciples first in­tro­duced by Robert C. Martin (‘Uncle Bob’), one of the ini­ti­at­ors of agile pro­gram­ming, in the year 2000 in his essay titled ‘Design Prin­ciples and Design Patterns’. The SOLID prin­ciples were coined by Robert C. Martin, Bertrand Meyer and Barbara Liskov. The catchy acronym was pop­ular­ised by Michael Feathers, who re­arranged the initial letters of the five essential prin­ciples into a memorable order.

What similar pro­gram­ming prin­ciples are there?

In software de­vel­op­ment, prin­ciples are general or very specific guidelines and re­com­mend­a­tions for action. In addition to the SOLID prin­ciples, which were developed for object-oriented pro­gram­ming, other pro­gram­ming prin­ciples for clean code include:

  • DRY principle (Don’t repeat yourself) for functions with a single, unique rep­res­ent­a­tion
  • KISS principle (Keep it simple, stupid) for code con­struc­ted as simply as possible
Go to Main Menu