Article 5: SOLID Principles and Design Patterns
Introduction
The SOLID Principles
S - Single Responsibility Principle
The Problem
# Bad: Class has multiple responsibilities
class UserService:
def __init__(self, db_connection):
self.db = db_connection
def create_user(self, email: str, password: str) -> User:
# Validation logic
if not self._is_valid_email(email):
raise ValueError("Invalid email")
if len(password) < 8:
raise ValueError("Password too short")
# Password hashing
password_hash = bcrypt.hash(password)
# Database logic
user = User(email=email, password_hash=password_hash)
self.db.add(user)
self.db.commit()
# Email notification
self._send_welcome_email(user)
return user
def _is_valid_email(self, email: str) -> bool:
return "@" in email and "." in email
def _send_welcome_email(self, user: User) -> None:
# SMTP logic here
smtp = smtplib.SMTP("localhost")
smtp.send_message(...)The Solution
Benefits
O - Open/Closed Principle
The Problem
The Solution
L - Liskov Substitution Principle
The Problem
The Solution
Another Example: Rectangle/Square
I - Interface Segregation Principle
The Problem
The Solution
D - Dependency Inversion Principle
The Problem
The Solution
Dependency Injection Patterns
Advanced Design Patterns
Observer Pattern
Decorator Pattern
Builder Pattern
Adapter Pattern
Practical Exercise
Exercise 1: Apply SOLID Refactoring
Exercise 2: Implement Observer Pattern
SOLID Cheat Sheet
Principle
One-liner
Key Question
Key Takeaways
What's Next?
Last updated