Design Patterns in Python
Implement Singleton, Factory, Observer, Strategy, Decorator, Command, and Repository patterns idiomatically in Python.
Part 1: What You Will Learn
- Recognise when a design pattern solves a recurring software-design problem.
- Implement the Strategy and Factory patterns using normal Python classes.
- Use the Observer idea to notify multiple objects when an event occurs.
- Avoid over-engineering: use a pattern only when it makes the code easier to change or test.
Part 2: Key Concepts
Design patterns are reusable approaches to common design problems. In Python, they are often lighter than their equivalents in more rigid languages because functions, classes, protocols, and dictionaries can all be used to compose behaviour.
- Strategy: choose an algorithm at runtime.
- Factory: centralise object creation.
- Observer: notify interested objects when something changes.
- Repository: isolate data-access code from business logic.
Part 3: Topic-Specific Code Example
from abc import ABC, abstractmethod
class DiscountStrategy(ABC):
@abstractmethod
def apply(self, total: float) -> float:
pass
class NoDiscount(DiscountStrategy):
def apply(self, total: float) -> float:
return total
class StudentDiscount(DiscountStrategy):
def apply(self, total: float) -> float:
return total * 0.90
class MemberDiscount(DiscountStrategy):
def apply(self, total: float) -> float:
return total * 0.85
def create_discount(customer_type: str) -> DiscountStrategy:
strategies = {
"regular": NoDiscount,
"student": StudentDiscount,
"member": MemberDiscount,
}
strategy_class = strategies.get(customer_type.lower(), NoDiscount)
return strategy_class()
def checkout(total: float, customer_type: str) -> float:
strategy = create_discount(customer_type)
return strategy.apply(total)
for customer in ["regular", "student", "member"]:
final_total = checkout(200.0, customer)
print(customer, "->", final_total)Part 4: How the Example Works
DiscountStrategy defines the common behaviour. Each concrete strategy provides its own calculation, while create_discount() acts as a Factory that selects the correct object. The checkout function does not contain a long chain of discount calculations, so new strategies can be added with minimal changes.
Part 5: Hands-On Practice
Mini project โ Notification Factory. Create EmailNotification, SMSNotification, and ConsoleNotification classes with a common send(message) method. Add a factory that creates the correct notifier from a string such as "email" or "sms". As an extension, allow several observers to receive the same order-status event.
Part 6: Next Steps
Run and modify the pattern example in Visual Studio 2026, then continue to Lesson 31. Return to Python Tutorial Home to review the full curriculum.