SOLID – Principles for Maintainable OO Code Posted on Dec 2, 2013 by Corinna in Development, DevOps & SysAdmins |

A short explanation of the 5 SOLID principles for object-oriented programming. The principles are:

Single Responsibility Open / Closed Liskov Substitution Interface Segregation Dependency Inversion

These were grouped by Robert C. Martin, who invented 1), 4) and 5). 2) was formulated by Bertrand Meyer and 3) by Barbara Liskov. The acronym was coined by Michael Feathers.

The SOLID principle is controversially discussed. See this slide deck by Dan North for a concise critique.

Did you know there are compilations of our 1-pagers? About Agile & Scrum, Facilitation and for Product Owners

Content of the 1-Pager:

Single Responsibility Principle

Each class has a single purpose. All its methods should relate to function.

Reasoning: Each responsibility could be a reason to change a class in the future. Fewer responsibilities -> fewer opportunities to introduce bugs during changes.

Example: Split formatting & calculating of a report into different classes.

Open / Closed Principle

Classes (or methods) should be open for extension and closed for modification. Once written they should only be touched to fix errors. New functionality should go into new classes that are derived. This is popularly interpreted to advocate inheritingfrom an abstract base class.

Reasoning: Again you lower the odds of breaking existing code.

Liskov Substitution Principle

You should be able to replace an object with any of its derived classes. Your code should never have to checl which sub-type its’s dealing with.

Reasoning: Prevents awkward type checking and weird side-effects.

Interface Segregation Principle

Define subsets of functionality as interfaces.

Reasoning: Small, specific interfaces lead to a more decoupled system than a big general-purpose one.

Example: A PersistenceManager implements DBReader & DBWriter.

Dependency Inversion Principle

High-level modules should not depend on low-level modules. Instead, both should depend on abstractions. Abstractions should not depend on details. Details should depend upon abstractions.

Reasoning: High-level modules become more reusable if they are ignorant of low-level module implementation details.

Examples: 1) Dependency Injection, 2) Putting high-level modules in different packages than the low-level modules it uses.