Business Optimization with the Strategy Pattern in Python: Practical Application with Dynamic Discounting


Definition
The Strategy pattern allows defining a family of algorithms, encapsulating each one, and making them interchangeable. This way, the behavior of an object can be modified dynamically without altering its internal structure. It is especially useful in business contexts where business rules must change in real-time, such as discount systems, commissions, or pricing.
Example in Python
Below is an implementation of the Strategy pattern to apply different types of discounts based on the type of client:
from abc import ABC, abstractmethod
# Base strategy
class DiscountStrategy(ABC):
@abstractmethod
def apply_discount(self, amount: float) -> float:
pass
# Concrete strategies
class RegularDiscount(DiscountStrategy):
def apply_discount(self, amount: float) -> float:
return amount * 0.95
class VIPDiscount(DiscountStrategy):
def apply_discount(self, amount: float) -> float:
return amount * 0.85
class CorporateDiscount(DiscountStrategy):
def apply_discount(self, amount: float) -> float:
return amount * 0.75
# Context
class DiscountContext:
def __init__(self, strategy: DiscountStrategy):
self._strategy = strategy
def set_strategy(self, strategy: DiscountStrategy):
self._strategy = strategy
def get_discounted_price(self, amount: float) -> float:
return self._strategy.apply_discount(amount)
# Example usage
if __name__ == "__main__":
amount = 1000
context = DiscountContext(RegularDiscount())
print(f"Regular: ${context.get_discounted_price(amount)}")
context.set_strategy(VIPDiscount())
print(f"VIP: ${context.get_discounted_price(amount)}")
context.set_strategy(CorporateDiscount())
print(f"Corporate: ${context.get_discounted_price(amount)}")
Explanation
A common interface
DiscountStrategy
is defined with the methodapply_discount
.The classes
RegularDiscount
,VIPDiscount
, andCorporateDiscount
implement this interface, encapsulating different discount logics.The class
DiscountContext
holds a reference to a strategy that can change dynamically using theset_strategy
method.
This allows new rules to be applied without modifying existing context code, favoring reuse and maintainability.
Automation with GitHub Actions
To ensure the code works correctly after each change, a CI automation can be used with GitHub Actions.
Workflow file (.github/workflows/python.yml
):
name: Python CI
on:
push:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.10'
- name: Run script
run: python strategy_discount.py
โ This pipeline performs:
Repository checkout.
Sets up Python 3.10.
Executes the
strategy_
discount.py
file.
๐ฅ Watch code explanation on YouTube: https://www.youtube.com/watch?v=lC-fBlfUM8k
The full source code and workflow can be explored here:
https://github.com/jf2021070309/strategy-pattern-business-rules-python
Pattern Comparison
Pattern | Language | Main Purpose | Key Benefit |
Repository | Java | Abstract data access to keep business logic decoupled | Facilitates unit testing and switching data sources |
Strategy | Python | Dynamically switch algorithms without modifying the context | Changes behavior at runtime |
Unit of Work | Ruby | Manage a set of operations as a single transaction | Ensures consistency across multiple actions |
Conclusion
The Strategy pattern is a powerful tool to manage variable behaviors such as discounts, fees, or commissions. When applied in Python, it provides greater flexibility in business systems without sacrificing clarity or scalability. Moreover, compared with other patterns like Repository in Java or Unit of Work in Ruby, each one fulfills specific roles in enterprise software design, contributing to clean, efficient, and adaptable solutions.
Subscribe to my newsletter
Read articles from JAIME ELIAS FLORES QUISPE directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
