Design Principles of Software: How I Apply Them in Python
Source: Dev.to
Why Design Principles Are Important
Imagine you’ve built a small project, and six months later you come back to fix a bug or add a feature. If your code is messy, you’ll spend more time figuring out what’s happening than actually solving the problem. Good design principles make your code:
- Easy to read
- Easy to maintain
- Flexible for future changes
The most common set of design principles is SOLID:
- Single Responsibility Principle (SRP) – Each class or function should have only one job.
- Open/Closed Principle (OCP) – Classes should be open for extension but closed for modification.
- Liskov Substitution Principle (LSP) – Subclasses should be able to replace parent classes without breaking the program.
- Interface Segregation Principle (ISP) – Don’t force classes to implement methods they don’t need.
- Dependency Inversion Principle (DIP) – High‑level modules should depend on abstractions, not on concrete low‑level modules.
A Real Example in Python
To make this concrete, let’s say I’m building a notification system where users can receive alerts via email or SMS. Here’s how I apply the design principles:
from abc import ABC, abstractmethod
# Interface defining what a Notifier should do
class Notifier(ABC):
@abstractmethod
def send(self, message: str):
pass
# SRP: Each notifier has a single responsibility
class EmailNotifier(Notifier):
def send(self, message: str):
print(f"Sending email: {message}")
class SMSNotifier(Notifier):
def send(self, message: str):
print(f"Sending SMS: {message}")
# OCP & DIP: NotificationService works with any notifier
class NotificationService:
def __init__(self, notifiers: list[Notifier]):
self.notifiers = notifiers
def notify_all(self, message: str):
for notifier in self.notifiers:
notifier.send(message)
# Using the system
email = EmailNotifier()
sms = SMSNotifier()
service = NotificationService([email, sms])
service.notify_all("Your order has been shipped!")
How the Principles Are Applied
- SRP: Each class has one job (sending email or SMS).
- OCP: New notifiers (e.g., WhatsApp) can be added without changing
NotificationService. - DIP & ISP:
NotificationServicedepends on theNotifierinterface, not on specific concrete classes.
This structure keeps the system flexible, easy to extend, and clean, even as it grows.
Conclusion
Applying design principles is not just a recommendation—it is an investment in the quality and longevity of your code. Following SRP, OCP, DIP, and the other SOLID principles makes your code easier to understand, safer to modify, and more scalable.
The goal is not just to make your software work today, but to build something that can grow and adapt tomorrow without complications. Adopting these principles from the start ensures cleaner projects, simpler changes, and smoother collaboration.