Introduction to the Strategy Pattern

Introduction to the Strategy Pattern

Welcome back! We are continuing our journey through Behavioral Patterns in software design. In previous lessons, we explored the Command and Observer patterns, focusing on object communication and state changes. Now, we will learn how to implement the Strategy Pattern in Python. We will break down the pattern into manageable parts and illustrate its practical application through a clear example.

Consider a scenario where you have a ShoppingCart class that can handle payments through different methods, such as credit cards or PayPal. Using the Strategy Pattern, we can encapsulate these payment methods into separate classes and have the ShoppingCart class use any of these strategies interchangeably.

Strategy Interface

First, we need to define an abstract base class that all payment strategies will inherit from. This ensures that all payment methods follow a common interface and can be used interchangeably.

from abc import ABC, abstractmethod

class PaymentStrategy(ABC):
    @abstractmethod
    def pay(self, amount):
        pass

In this snippet, we create an abstract class PaymentStrategy with an abstract method pay. Any class that inherits from PaymentStrategy must implement the pay method.

Concrete Strategies

Next, we implement concrete strategies that encapsulate different payment methods. Here, we define two strategies: CreditCardStrategy and PayPalStrategy.

class CreditCardStrategy(PaymentStrategy):
    def __init__(self, card_number):
        self.card_number = card_number

    def pay(self, amount):
        print(f"Paid {amount} using Credit Card: {self.card_number}")

In the CreditCardStrategy class, we implement the pay method to handle credit card transactions. This class requires a card number upon initialization.

class PayPalStrategy(PaymentStrategy):
    def __init__(self, email):
        self.email = email

    def pay(self, amount):
        print(f"Paid {amount} using PayPal: {self.email}")

Similarly, the PayPalStrategy class implements the pay method for PayPal transactions. It requires an email address to initialize.

Context Class

The ShoppingCart class is our context class that will use any given payment strategy. This class keeps a reference to a PaymentStrategy object and can switch strategies at runtime.

class ShoppingCart:
    def __init__(self):
        self.strategy = None

    def set_payment_strategy(self, strategy):
        self.strategy = strategy

    def checkout(self, amount):
        if self.strategy:
            self.strategy.pay(amount)
        else:
            print("No payment strategy set.")

In the ShoppingCart class, the set_payment_strategy method allows us to set the payment strategy, and the checkout method uses the selected strategy to make a payment.

Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal