Python – SOLID Principles Demystified: Building Better Software Designs


please read the detailed SOLID Principles explanation here:

If you have read this post already, then this post uses Python as a programming language to explain the SOLID principles. Please note that this is specifically for Python version 3 or higher

from abc import ABC, abstractmethod

class Bird(ABC):
    @abstractmethod
    def get_legs(self):
        pass
    
    @abstractmethod
    def get_wings(self):
        pass

class FlyingBirds(ABC):
    @abstractmethod
    def fly(self):
        pass

class RunningBirds(ABC):
    @abstractmethod
    def run(self):
        pass

class SwimmingBirds(ABC):
    @abstractmethod
    def swim(self):
        pass

class CommonBirdFeatures:
    def get_legs(self):
        return "This bird has 2 legs"
    
    def get_wings(self):
        return "This bird has two wings"

class Sparrow(FlyingBirds, CommonBirdFeatures):
    def fly(self):
        return "This bird can fly"
    
    def make_bird_fly(self, bird):
        return bird.fly()

class Ostrich(RunningBirds, CommonBirdFeatures):
    def run(self):
        return "This bird can run"

robin = Sparrow()
print(robin.get_legs())
print(robin.make_bird_fly(robin))

In this Python version, I’ve converted the PHP code to adhere to SOLID principles:

  1. Single Responsibility Principle (SRP): Each class and interface has a single responsibility. The interfaces are separated according to the different behaviors birds can have.
  2. Open/Closed Principle (OCP): The code is designed in a way that new bird types can be added (like Ostrich) without modifying existing classes, promoting extension without modification.
  3. Liskov Substitution Principle (LSP): The Sparrow class, which implements the FlyingBirds interface, adheres to the Liskov Substitution Principle. It can be substituted for other FlyingBirds instances without altering program correctness.
  4. Interface Segregation Principle (ISP): The interfaces are segregated based on the specific behaviors they represent (FlyingBirds, RunningBirds, SwimmingBirds), preventing classes from implementing unnecessary methods.
  5. Dependency Inversion Principle (DIP): The code relies on abstractions (interfaces and abstract base classes) rather than concrete implementations, allowing for easier substitution of components and better decoupling.

Remember that Python doesn’t have strict interfaces like PHP, so I used abstract base classes (ABCs) to define the contracts that classes must adhere to.

In the Python code provided, the line from abc import ABC, abstractmethod is importing two elements from the abc module: ABC and abstractmethod. Let me explain what these are:

  1. ABC (Abstract Base Class): The ABC class stands for Abstract Base Class. In Python, abstract base classes are a way to define abstract interfaces that concrete classes must adhere to. They provide a way to define a contract that classes inheriting from the abstract base class must fulfill. Abstract base classes are used to implement some aspects of interface-like behavior in Python.When a class inherits from an abstract base class, it’s indicating that the derived class is expected to implement the abstract methods defined in the base class. Abstract methods are declared using the @abstractmethod decorator.Abstract base classes help enforce design principles like the Liskov Substitution Principle, as they ensure that derived classes adhere to a common interface.
  2. abstractmethod: The abstractmethod decorator is used to define abstract methods within an abstract base class. An abstract method is a method that is declared in the base class but does not provide an implementation. Instead, the responsibility of implementing the method is left to the derived classes. When a class inherits from an abstract base class that contains abstract methods, it must provide implementations for those methods, effectively fulfilling the contract defined by the base class.

the ABC and abstractmethod are used to define the abstract base classes (Bird, FlyingBirds, RunningBirds, SwimmingBirds) and the abstract methods that derived classes must implement. This creates a structured and standardized way for classes to provide certain behaviors while adhering to the SOLID principles, particularly the Liskov substitution Principle.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.