Loading...

Strategy pattern - Design Patterns

This pattern falls into the behavioural category, it allows algorithms to be selected on-the-fly at runtime


Pattern type

This is a behavioural pattern, it allows algorithms to be selected on-the-fly at runtime

Intent

This pattern allows the client to choose from a family of algorithms and gives a simple way to switch between the different algorithms.

Problem

You may have a class that has a method that performs a specific task, but you want to be able to change the way the task is performed without changing the class.

As an example imagine you have a class that has a method that calculates the total cost of a shopping cart. You may want to be able to change the way the total is calculated, for example, you may want to calculate the total with or without tax.

Pattern

ShoppingCart
+calculateTotal()
+calulateShipping()
ShoppingCartWithTax
+calculateTotal()
ShoppingCartWithoutTax
+calculateTotal()
Item
+price

Code example

class ShoppingCart:
    def __init__(self, items):
        self.items = items
 
    def calculate_total(self):
        raise NotImplementedError()
class Item:
    def __init__(self, price):
        self.price = price
class ShoppingCartWithTax(ShoppingCart):
    def calculate_total(self):
        total = sum(item.price for item in self.items)
        return total * 1.2
 
class ShoppingCartWithoutTax(ShoppingCart):
    def calculate_total(self):
        return sum(item.price for item in self.items)
cart = ShoppingCartWithTax([Item(10), Item(20)])
print(f"total cart with tax {cart.calculate_total()}")
 
cart_without_tax = ShoppingCartWithoutTax([Item(10), Item(20)])
print(f"total cart without tax {cart_without_tax.calculate_total()}")

prints out:

total cart with tax: 36.0
total cart with out tax: 30