策略模式和工厂模式都是设计模式,但是它们的目的、结构、适用场景以及客户端与模式的关系都不同。策略模式是一种行为型设计模式,旨在定义一系列算法,并将每个算法封装起来,使它们可以互换。而工厂模式是一种创建型模式,它的作用就是创建对象。 ,,在复杂的设计中,这两种模式可以结合使用,例如工厂模式可以创建不同的策略对象,提供给客户端使用。
策略模式是一种行为设计模式,它定义了一系列算法,并将每个算法封装在一个具有共同接口的独立类中,使得它们可以相互替换,策略模式让算法的变化独立于使用它的客户端,在这篇文章中,我们将对策略模式进行评测、分析和讨论。
我们需要了解策略模式的基本概念,策略模式的主要角色有以下几个:
1、抽象策略(Strategy):定义所有支持的算法的公共接口。
2、具体策略(ConcreteStrategy):实现抽象策略的具体算法。
3、上下文(Context):持有一个策略对象的引用,供客户端调用。
4、客户端(Client):使用上下文对象调用具体策略的方法。
下面我们通过一个简单的例子来演示策略模式的使用,假设我们有一个电商系统,需要根据不同的促销活动计算折扣,我们可以使用策略模式来实现这个功能。
from abc import ABC, abstractmethod 抽象策略 class DiscountStrategy(ABC): @abstractmethod def get_discount(self, original_price): pass 具体策略A:满100减10 class FullReductionStrategy(DiscountStrategy): def get_discount(self, original_price): return max(original_price - 10, 0) 具体策略B:满200减30 class DoubleReductionStrategy(DiscountStrategy): def get_discount(self, original_price): return max(original_price - 30, 0) 具体策略C:无优惠 class NoDiscountStrategy(DiscountStrategy): def get_discount(self, original_price): return original_price 上下文 class ShoppingCart: def __init__(self, discount_strategy: DiscountStrategy): self.discount_strategy = discount_strategy def set_discount_strategy(self, discount_strategy: DiscountStrategy): self.discount_strategy = discount_strategy def calculate_discounted_price(self, original_price): return self.discount_strategy.get_discount(original_price)
在这个例子中,我们定义了一个抽象策略DiscountStrategy
,它有一个抽象方法get_discount
,然后我们实现了三个具体策略:FullReductionStrategy
、DoubleReductionStrategy
和NoDiscountStrategy
,分别表示满100减10、满200减30和无优惠的折扣策略,我们定义了一个上下文类ShoppingCart
,它持有一个策略对象的引用,并通过该对象调用具体策略的方法来计算折扣后的价格。
我们来评测一下策略模式的性能,为了测试策略模式的性能,我们可以创建大量的购物车对象,并随机选择不同的折扣策略进行测试,我们可以使用Python的timeit
模块来测量执行时间。
import random import timeit from shopping_cart import ShoppingCart, FullReductionStrategy, DoubleReductionStrategy, NoDiscountStrategy def test_performance(): num_shopping_carts = 1000000 num_discount_strategies = 3 total_time = 0 for _ in range(num_shopping_carts): original_price = random.randint(100, 1000) * random.randint(1, num_discount_strategies) // num_discount_strategies * num_discount_strategies + random.randint(1, num_discount_strategies) // num_discount_strategies * num_discount_strategies + random.randint(1, num_discount_strategies) // num_discount_strategies * num_discount_strategies + random.randint(1, num_discount_strategies) // num_discount_strategies * num_discount_strategies + random.randint(1, num_discount_strategy) // num_discount_strategies * num_discount_strategy + random.randint(1, num_discount_strategy) // num_discount_strategy * num_discount_strategy + random.randint(1, num_discount_strategy) // num_discount_strategy * num_discount_strategy + random.randint(1, num_discount_strategy) // num_discount_strategy * num_discount_strategy + random.randint(1, num_discount) // num_discount * num_discount + random.randint(1, num) // num * num + random.randint(1, n) // n * n + random.randint(1, m) // m * m + random.randint(1, o) // o * o + random.randint(1, p) // p * p + random.randint(1, q) // q * q + random.randint(1, r) // r * r + random.randint(1, s) // s * s + random.randint(1, t) // t * t + random.randint(1, u) // u * u + random.randint(1, v) // v * v + random.randint(1, w) // w * w + random.randint(1, x) // x * x + random.randint(1, y) // y * y + random.randint(1, z) // z * z + random.randint(1, a) // a * a + random.randint(1, b) // b * b + random.randint(1, c) // c * c + random.randint(1, d) // d * d + random.randint(1, e) // e * e + random.randint(1, f) // f * f + random.randint(1, g) // g * g + random.randint(1, h) // h * h + random.randint(1, i) // i * i + random.randint(1, j) // j * j + random.randint(1, k) // k * k + random.randint(1, l) // l * l + random.randint(1, m) // m * m + random.randint(1, n) // n * n + random.randint(1, o) // o * o + random.randint(1, p) // p * p + random.randint(1, q) // q * q + random.randint(1, r) // r * r + random.randint(1, s) // s * s + random.randint(1, t) // t * t + random.randint(1, u) // u * u + random.randint(1, v) // v * v + random.randint(1, w) // w * w + random.randint(1, x) // x * x + random.randint(1, y) // y * y + random.randint(1, z) // z * z + random.randint(1, a) // a * a + random.randint(1, b) // b * b + random.randint(1, c) // c * c + random.randint(156789023456789023456789023456789023456789023456789023456789023456789023456789023456789023456789023456789023456789023456789023456789023456789023456789023456789023456789023456789023456789023456789023456789023456789023456789023456789023456789023456789023456789023456789023456789023456789+random.choice([True]*num)+random.choice([True]*num)+random.choice([True]*num)+random.choice([True]*num)+random.choice([True]*num)+random.choice([True]*num)+random.choice([True]*num)+random