DEV Community

Plug panther
Plug panther

Posted on

Understanding SOLID Principles with Python Examples

Understanding SOLID Principles with Python Examples

The SOLID principles are a set of design principles that help developers create more maintainable and scalable software. Let's break down each principle with brief Python examples.

1. Single Responsibility Principle (SRP)

A class should have only one reason to change, meaning it should have only one job or responsibility.

class Invoice:
    def __init__(self, items):
        self.items = items

    def calculate_total(self):
        return sum(item['price'] for item in self.items)

class InvoicePrinter:
    def print_invoice(self, invoice):
        for item in invoice.items:
            print(f"{item['name']}: ${item['price']}")
        print(f"Total: ${invoice.calculate_total()}")

# Usage
invoice = Invoice([{'name': 'Book', 'price': 10}, {'name': 'Pen', 'price': 2}])
printer = InvoicePrinter()
printer.print_invoice(invoice)
Enter fullscreen mode Exit fullscreen mode

2. Open/Closed Principle (OCP)

Software entities should be open for extension but closed for modification.

class Discount:
    def apply(self, amount):
        return amount

class TenPercentDiscount(Discount):
    def apply(self, amount):
        return amount * 0.9

# Usage
discount = TenPercentDiscount()
print(discount.apply(100))  # Output: 90.0
Enter fullscreen mode Exit fullscreen mode

3. Liskov Substitution Principle (LSP)

Objects of a superclass should be replaceable with objects of a subclass without affecting the correctness of the program.

class Bird:
    def fly(self):
        return "Flying"

class Sparrow(Bird):
    pass

class Ostrich(Bird):
    def fly(self):
        return "Can't fly"

# Usage
def make_bird_fly(bird: Bird):
    print(bird.fly())

sparrow = Sparrow()
ostrich = Ostrich()
make_bird_fly(sparrow)  # Output: Flying
make_bird_fly(ostrich)  # Output: Can't fly
Enter fullscreen mode Exit fullscreen mode

4. Interface Segregation Principle (ISP)

Clients should not be forced to depend on interfaces they do not use.

class Printer:
    def print(self, document):
        pass

class Scanner:
    def scan(self, document):
        pass

class MultiFunctionPrinter(Printer, Scanner):
    def print(self, document):
        print(f"Printing: {document}")

    def scan(self, document):
        print(f"Scanning: {document}")

# Usage
mfp = MultiFunctionPrinter()
mfp.print("Document1")
mfp.scan("Document2")
Enter fullscreen mode Exit fullscreen mode

5. Dependency Inversion Principle (DIP)

High-level modules should not depend on low-level modules. Both should depend on abstractions.

class Database:
    def connect(self):
        pass

class MySQLDatabase(Database):
    def connect(self):
        print("Connecting to MySQL")

class Application:
    def __init__(self, db: Database):
        self.db = db

    def start(self):
        self.db.connect()

# Usage
db = MySQLDatabase()
app = Application(db)
app.start()  # Output: Connecting to MySQL
Enter fullscreen mode Exit fullscreen mode

These examples illustrate the SOLID principles in a concise manner using Python. Each principle helps in building a robust, scalable, and maintainable codebase.

Top comments (0)