id="design-pattDesign Patterns Tutorial with Python Examples

Design patterns are reusable solutions to common software design problems. They help improve code readability, maintainability, and scalability. In this tutorial, we'll cover 10 design patterns with Python code examples and discuss when to use them.

1. Singleton Pattern

Use the Singleton pattern when you want only one instance of a class throughout the application.

class Singleton:
    _instance = None

    @classmethod
    def get_instance(cls):
        if not cls._instance:
            cls._instance = cls()
        return cls._instance

2. Factory Pattern

Use the Factory pattern when you need to create objects without specifying the exact class.

class Dog:
    def speak(self):
        return "Woof!"

class Cat:
    def speak(self):
        return "Meow!"

class AnimalFactory:
    def create_animal(self, animal_type):
        if animal_type == "dog":
            return Dog()
        elif animal_type == "cat":
            return Cat()

3. Observer Pattern

Use the Observer pattern to establish a one-to-many dependency between objects, where changes in one object trigger updates in others.

class Subject:
    def __init__(self):
        self._observers = []

    def add_observer(self, observer):
        self._observers.append(observer)

    def notify_observers(self, message):
        for observer in self._observers:
            observer.update(message)

class Observer:
    def update(self, message):
        print("Received:", message)

4. Strategy Pattern

Use the Strategy pattern to define a family of algorithms and make them interchangeable.

class Operation:
    def execute(self, a, b):
        pass

class Add(Operation):
    def execute(self, a, b):
        return a + b

class Multiply(Operation):
    def execute(self, a, b):
        return a * b

5. Decorator Pattern

Use the Decorator pattern to add additional functionality to objects at runtime.

class Coffee:
    def cost(self):
        return 5

class MilkDecorator:
    def __init__(self, coffee):
        self._coffee = coffee

    def cost(self):
        return self._coffee.cost() + 2

6. Adapter Pattern

Use the Adapter pattern to convert the interface of a class into another interface that clients expect.

class OldPrinter:
    def print_old(self):
        print("Old Printer")

class NewPrinter:
    def print_new(self):
        print("New Printer")

class PrinterAdapter:
    def __init__(self, new_printer):
        self._new_printer = new_printer

    def print_old(self):
        self._new_printer.print_new()

7. Template Method Pattern

Use the Template Method pattern to define the outline of an algorithm, allowing subclasses to provide specific implementations.

class Pizza:
    def prepare(self):
        self.prepare_dough()
        self.add_toppings()
        self.bake()

    def prepare_dough(self):
        pass

    def add_toppings(self):
        pass

    def bake(self):
        pass

8. Proxy Pattern

Use the Proxy pattern to control access to an object, acting as an intermediary or placeholder.

class RealSubject:
    def request(self):
        print("Real Subject Request")

class Proxy:
    def __init__(self):
        self._real_subject = RealSubject()

    def request(self):
        self._real_subject.request()

9. Command Pattern

Use the Command pattern to encapsulate a request as an object, allowing parameterization of clients with different requests.

class Light:
    def turn_on(self):
        print("Light is on")

class LightOnCommand:
    def __init__(self, light):
        self._light = light

    def execute(self):
        self._light.turn_on()

class RemoteControl:
    def __init__(self):
        self._command = None

    def set_command(self, command):
        self._command = command

    def press_button(self):
        self._command.execute()

10. State Pattern

Use the State pattern to change the behavior of an object based on its internal state.

class Context:
    def __init__(self):
        self._state = StateA()

    def set_state(self, state):
        self._state = state

    def request(self):
        self._state.handle()

class State:
    def handle(self):
        pass

class StateA(State):
    def handle(self):
        print("State A")

class StateB(State):
    def handle(self):
        print("State B")

Conclusion

Design patterns are essential tools for software developers to improve code structure, maintainability, and flexibility. In this tutorial, we covered 10 design patterns, each with a Python code example. Understanding these patterns and their use cases will empower you to design more robust and scalable applications.

Comments

Popular posts from this blog

PyTorch Tutorial: Using ImageFolder with Code Examples

A Tutorial on IBM LSF Scheduler with Examples

Explaining Chrome Tracing JSON Format