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!