SoFunction
Updated on 2025-03-02

A new dimension of policy patterns in Python unlock programming

introduction

A policy pattern is a behavioral design pattern that allows the algorithm to vary independently of the client using it. This allows us to choose different algorithms or strategies to solve the problem according to different situations, thereby enhancing the flexibility of the system. In daily development, policy modes are often used to handle switching between multiple algorithms or behaviors, such as implementing multiple payment methods in e-commerce systems, implementing different attack modes of characters in game development, etc.

Introduction to basic grammar

Core concept

  • Policy interface(Strategy Interface): Defines the common interface that a set of algorithms should have.
  • Specific strategy category(Concrete Strategy Classes): Implements a policy interface, and each class represents a specific algorithm or policy.
  • Context(Context): Use a policy interface and can dynamically change the specific policy class used at runtime.

Basic grammar rules

In Python, implementing a policy pattern usually involves defining an abstract base class (or interface) and then creating multiple concrete classes inherited from that base class to represent different policies. The context object is responsible for calling the method of the policy object.

from abc import ABC, abstractmethod
class Strategy(ABC):
    @abstractmethod
    def do_algorithm(self, data):
        pass
class ConcreteStrategyA(Strategy):
    def do_algorithm(self, data):
        return sorted(data)
class ConcreteStrategyB(Strategy):
    def do_algorithm(self, data):
        return reversed(sorted(data))
class Context:
    def __init__(self, strategy: Strategy):
        self._strategy = strategy
    def set_strategy(self, strategy: Strategy):
        self._strategy = strategy
    def do_some_business_logic(self, data):
        result = self._strategy.do_algorithm(data)
        print(f"Sorting data with {type(self._strategy).__name__}: {result}")
if __name__ == "__main__":
    context = Context(ConcreteStrategyA())
    context.do_some_business_logic([1, 3, 2])
    context.set_strategy(ConcreteStrategyB())
    context.do_some_business_logic([1, 3, 2])

Basic examples

Suppose we need to provide multiple ways to sort items (by price, sales, etc.) for an online store. Here we can use the policy pattern to achieve this requirement.

Problem description

Users hope to be able to choose different sorting methods according to their preferences when browsing product lists.

Code Example

from abc import ABC, abstractmethod
class ProductSorter(ABC):
    @abstractmethod
    def sort_products(self, products):
        pass
class PriceSorter(ProductSorter):
    def sort_products(self, products):
        return sorted(products, key=lambda p: )
class PopularitySorter(ProductSorter):
    def sort_products(self, products):
        return sorted(products, key=lambda p: , reverse=True)
class Product:
    def __init__(self, name, price, popularity):
         = name
         = price
         = popularity
products = [
    Product("Laptop", 1200, 5),
    Product("Headphones", 150, 3),
    Product("Smartphone", 800, 7)
]
context = Context(PriceSorter())
sorted_by_price = context.sort_products(products)
print("Sorted by price:", [ for p in sorted_by_price])
context.set_strategy(PopularitySorter())
sorted_by_popularity = context.sort_products(products)
print("Sorted by popularity:", [ for p in sorted_by_popularity])

Advanced examples

In complex environments, we may need to consider more factors, such as choosing different combinations of strategies based on different conditions. Next, we will further explore the application of policy patterns through a more complex example.

Problem description

A certain e-commerce platform needs to dynamically adjust the recommendation algorithm based on factors such as user's shopping history, membership level, etc.

Advanced code examples

class User:
    def __init__(self, id, purchase_history, membership_level):
         = id
        self.purchase_history = purchase_history
        self.membership_level = membership_level
def get_recommendation_strategy(user: User):
    if user.membership_level == "premium":
        return PremiumUserRecommendationStrategy()
    else:
        return RegularUserRecommendationStrategy()
class RecommendationStrategy(ABC):
    @abstractmethod
    def recommend_products(self, user: User):
        pass
class RegularUserRecommendationStrategy(RecommendationStrategy):
    def recommend_products(self, user: User):
        # Implement logic for regular users
        pass
class PremiumUserRecommendationStrategy(RecommendationStrategy):
    def recommend_products(self, user: User):
        # Implement logic for premium users
        pass
# Example usage
user = User(1, ["laptop", "smartphone"], "premium")
strategy = get_recommendation_strategy(user)
recommended_products = strategy.recommend_products(user)
print("Recommended products:", recommended_products)

Practical cases

Problem description

In a real e-commerce project, we need to dynamically adjust the product price display strategy based on the user's geographical location information. For example, for overseas users, the price of US dollars is displayed; for domestic users, the price of RMB is displayed.

Solution

Introduce a policy model to dynamically select appropriate pricing strategies based on user's geographical location information.

Code implementation

from abc import ABC, abstractmethod
class PricingStrategy(ABC):
    @abstractmethod
    def calculate_price(self, base_price):
        pass
class USDollarPricingStrategy(PricingStrategy):
    def calculate_price(self, base_price):
        return base_price * 1.15  # Assuming exchange rate of 1.15 USD/CNY
class CNYPricingStrategy(PricingStrategy):
    def calculate_price(self, base_price):
        return base_price
class Product:
    def __init__(self, name, base_price):
         = name
        self.base_price = base_price
def get_pricing_strategy(user_location):
    if user_location == "US":
        return USDollarPricingStrategy()
    else:
        return CNYPricingStrategy()
# Example usage
product = Product("Smartphone", 800)
strategy = get_pricing_strategy("US")
final_price = strategy.calculate_price(product.base_price)
print(f"Final price for {} in US: {final_price} USD")
strategy = get_pricing_strategy("CN")
final_price = strategy.calculate_price(product.base_price)
print(f"Final price for {} in CN: {final_price} CNY")

Extended discussion

In addition to the above application scenarios, the policy model can also be applied to many other fields, such as logging, error handling, etc. In actual work, we can flexibly use the strategy model according to the specific needs of the project to achieve the best results. In addition, combining other design patterns (such as factory mode, decorator mode, etc.) can further improve the flexibility and maintainability of the code.

This is the article about strategy mode in Python: unlocking new dimensions of programming. For more related Python strategy mode content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!