Mastering Code Architecture: Refactoring Python with SOLID Principles
Overview
Writing software that lasts requires more than just making code run; it requires making code maintainable. The SOLID principles, popularized by Robert C. Martin (Uncle Bob), provide a roadmap for creating robust, flexible, and decoupled Object-Oriented Programming systems. By applying these five design rules, developers transform brittle, "spaghetti" code into a modular architecture where changes in one area don't trigger a cascade of failures elsewhere. This tutorial refactors a standard Python sales system to demonstrate these principles in action.
Prerequisites
To get the most out of this guide, you should possess a firm grasp of Python basics, particularly Class, Inheritance, and Method overriding. Familiarity with the concept of Abstract Base Class will help when we move toward interface design.

Key Libraries & Tools
- abc: Python’s built-in module for defining Abstract Base Classes, essential for enforcing interface contracts.
- Python 3.x: The primary runtime environment for executing our refactored logic.
Code Walkthrough
1. Single Responsibility (SRP)
We start with an Order class that handles items and payment logic. This is high coupling. We extract the payment logic into a separate PaymentProcessor class. Now, Order only tracks items, while PaymentProcessor handles the transaction.
class Order:
def __init__(self):
self.items = []
self.status = "open"
class PaymentProcessor:
def pay_debit(self, order, security_code):
print(f"Paying debit: {security_code}")
order.status = "paid"
2. Open/Closed (OCP)
Adding new payment methods shouldn't mean modifying existing classes. We use the abc module to create an abstract interface. Now, adding Bitcoin or PayPal simply requires a new subclass.
from abc import ABC, abstractmethod
class PaymentProcessor(ABC):
@abstractmethod
def pay(self, order):
pass
3. Liskov Substitution (LSP)
If a Paypal subclass requires an email but a Debit subclass requires a security code, changing the pay method's signature breaks the program. We solve this by moving specific credentials to the __init__ method, keeping the pay method signature identical across all subtypes.
4. Interface Segregation & Dependency Inversion (ISP/DIP)
Instead of forcing every processor to implement Two-Factor Authentication (2FA), we use Composition. We create an Authorizer class and inject it into the processors. This follows DIP: our high-level payment logic depends on an abstract Authorizer rather than a concrete SMS_Authorizer.
class DebitPaymentProcessor(PaymentProcessor):
def __init__(self, security_code, authorizer: Authorizer):
self.authorizer = authorizer
self.security_code = security_code
def pay(self, order):
if not self.authorizer.is_authorized():
raise Exception("Not authorized")
order.status = "paid"
Syntax Notes
Python uses the @abstractmethod decorator to identify methods that subclasses MUST implement. Note the use of Type Hinting (e.g., authorizer: Authorizer) which, while not enforced at runtime, is vital for clarity and IDE support in complex architectures.
Practical Examples
These principles shine in e-commerce backends, plugin systems, and API integrations. If you need to support multiple shipping carriers (FedEx, UPS, DHL), SRP and OCP allow you to add new carriers without touching the core shipping logic.
Tips & Gotchas
Avoid over-engineering. While SOLID is powerful, applying it to a three-line script adds unnecessary complexity. Prefer Composition over Inheritance to avoid deep, confusing class hierarchies. If a subclass method is just raising a NotImplementedError, you are likely violating the Liskov Substitution Principle.
- abc
- 17%· libraries
- Python
- 17%· programming languages
- SOLID
- 17%· concepts
- Abstract Base Class
- 8%· concepts
- Class
- 8%· concepts
- Other topics
- 33%

Uncle Bob’s SOLID Principles Made Easy 🍀 - In Python!
WatchArjanCodes // 19:09
On this channel, I post videos about programming and software design to help you take your coding skills to the next level. I'm an entrepreneur and a university lecturer in computer science, with more than 20 years of experience in software development and design. If you're a software developer and you want to improve your development skills, and learn more about programming in general, make sure to subscribe for helpful videos. I post a video here every Friday. If you have any suggestion for a topic you'd like me to cover, just leave a comment on any of my videos and I'll take it under consideration. Thanks for watching!