/SOLID-principles-Python

Simple explanation of SOLID principles with examples in Python

Primary LanguagePython

A brief guide to understanding SOLID principles with examples written in Python.

SOLID Principles is an acronym of 5 principles in Object Oriented Design (OOD). Robert C. Martin introduced these 5 principles in his 2000 paper "Design Principles and Design Patterns".

  • Make things (subsystem, classes, modules, functions, etc.) responsible for fulfilling single functionality. In other words, it should have only a single reason to change.
  • Only one potential change (database logic, logging logic, and so on.) in the software’s specification should be able to affect the specification of the class.

Why useful?

• Team collaboration on the same project, less prone to incompatibility.
• Help in unit testing.
• It makes version control easier, fewer conflicts will appear.

  • Be able to add new functionality to existing code(subsystem, classes, modules, functions, etc.) easily without modifying existing code.
  • This could be done via:
    • Inheritance.
    • Composition.
    • @decoration: rewrites a class.
    • Mixins and multiple inheritanc.
    • Functional composition: functions and callable objects.

Why useful?

• Avoid tweaking the code to handle new requiremnts.
    - e.g. When you have algorithms that perform a calculation (cost, tax, game score, etc.):
           the algorithm will likely change over time.
    - e.g. When you have data coming or going from the system: the endpoint (file, database, another system) 
           is likely to change. So is the actual format of the data.
• Building applications that are reusable and can be maintained easily.

  • States that Objects in a program should be substitutable by the instances of their subtypes without modifying the correctness of a program.
  • The problem is usually caused by inheriting class S from class T where S and T seem related but have one or more fundamental interface differences.
  • To make sure you avoid violating this rule, try to first think of high-level abstractions/interfaces instead of low-level/concrete implementations.
    • e.g. use inheritance hierarchies.
    • e.g. define constructor arguments to keep inheritance flexible.
  • Liskov Substitution help minimize the diffrence in method parameters, to assure the subclasses match the superclasses design.

Why useful?

• Helps programmers design good polymorphism. 
• Constrains subclass design.

LSP is a concept that applies to polymorphism.

If you don’t use polymorphism at all you don’t need to care about the LSP.


  • Make interfaces (parent abstract classes) more specific, rather than generic.
  • Clients should not be forced to implement a function they do not require.
    • e.g. Create more interfaces (abstract classes) if needed and/or provide objects to constructors.

Why useful?

• Help write good classes.
• Help write unit tests.

  • High-level modules should not depend on low-level modules. Both should depend on abstractions or interfaces.
    • e.g. Make classes inherit from abstract classes.
  • A direct dependency - on a concrete class - need to be "inverted".

Why useful?

• It helps you separate components and helps reduce coupling in the code.

Final note

The starting point for design includes defining the overall responsibilities and collaboration,
and unit test cases; the SOLID principles help make a design better. .

Reference: