๐Ÿ  VisualStudioTutor.com  ยท  Python Tutorial Home  ยท  Python Lesson 30 of 40
Lesson 30 of 40 Architecture Advanced โฑ 35 min

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.

๐Ÿ“˜ Want the complete guide with projects? Get the book โ†’