【设计模式】策略模式
前言
1. 单例模式(Singleton Pattern):保证一个类只有一个实例,并提供一个全局的访问点。
2. 工厂模式(Factory Pattern):定义一个创建对象的接口,但由子类决定要实例化的类是哪一个。
3. 观察者模式(Observer Pattern):定义对象之间的一对多依赖关系,使得当一个对象的状态发生改变时,所有依赖于它的对象都会被自动通知并更新。
4. 装饰器模式(Decorator Pattern):动态地给一个对象添加一些额外的职责,而不会影响到其他对象。
5. 策略模式(Strategy Pattern):定义一系列的算法,将每个算法封装起来,并使它们可以相互替换。
6. 命令模式(Command Pattern):将请求封装成一个对象,从而使用户可以用不同的请求对客户进行参数化。
7. 适配器模式(Adapter Pattern):将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的类能够一起工作。
8. 外观模式(Facade Pattern):为子系统中的一组接口提供一个统一的接口,从而使得子系统更加容易使用。
9. 状态模式(State Pattern):允许一个对象在其内部状态改变时改变其行为。
10. 模板方法模式(Template Method Pattern):定义一个操作中的算法的骨架,而将一些步骤延迟到子类中实现。
这些是Python中常用的设计模式,通过使用这些设计模式可以提高代码的可读性、可维护性和重用性。
策略模式是一种行为设计模式,它定义了一系列算法,并将每个算法封装起来,使它们可以相互替换。策略模式允许客户端代码选择算法的实现方式,而不必改变其使用的上下文。
- Context:上下文类,持有具体策略类的实例,并负责调用相关的算法
- Strategy:策略抽象类,用来约束一系列的策略算法(Context 使用这个接口来调用具体的策略实现算法)
- ConcreateStrategy:具体的策略类(继承抽象策略类)
策略模式
在Python中,可以通过定义一个为算法定义接口的Strategy基类,然后为从?Strategy类派生并实现该算法的每个算法定义一个单独的类来实现策略模式。
代码示例?
# 策略接口
class PaymentStrategy:
    def pay(self, amount):
        pass
# 具体策略类1
class CreditCardPayment(PaymentStrategy):
    def pay(self, amount):
        print(f"Paid {amount} via credit card")
# 具体策略类2
class PayPalPayment(PaymentStrategy):
    def pay(self, amount):
        print(f"Paid {amount} via PayPal")
# 上下文
class ShoppingCart:
    def __init__(self, payment_strategy):
        self._payment_strategy = payment_strategy
    def checkout(self, amount):
        self._payment_strategy.pay(amount)
# 使用策略模式
credit_card_payment = CreditCardPayment()
paypal_payment = PayPalPayment()
cart1 = ShoppingCart(credit_card_payment)
cart1.checkout(100)
cart2 = ShoppingCart(paypal_payment)
cart2.checkout(50)
在上面的例子中,PaymentStrategy 是策略接口,而 CreditCardPayment 和 PayPalPayment 是具体的策略类。ShoppingCart 是上下文类,它包含了一个策略对象,并在 checkout 方法中调用策略的 pay 方法。
通过使用策略模式,可以轻松地添加新的支付策略,而不必修改 ShoppingCart 类的代码。这样的设计使得系统更加灵活,易于扩展和维护。
具体案例
Context
上下文类,持有具体策略类的实例,并负责调用相关的算法
class Customer:
    """顾客类"""
    def __init__(self, name, integral, is_vip):
        self.name = name
        self.integral = integral
        self.is_vip = is_vip
    def __repr__(self):
        return self.name
class Goods:
    """商品类"""
    def __init__(self, name, price, num):
        self.name = name
        self.price = price
        self.num = num
    def total(self):
        return self.price * self.num
class Order:
    """
    订单类
    关联上用户、对应的商品、折扣策略
    通过折扣策略来计算订单的实际价格
    """
    def __init__(self, customer, promotion=None):
        """
        :param customer: 顾客对象
        :param promotion: 折扣策略对象
        """
        self.cart = []  # 购物车
        self.customer = customer  # 客户信息
        self.promotion = promotion  # 具体的折扣策略
    def add_cart(self, *good):
        """商品加入购物车"""
        self.cart += good
    def total(self):
        """计算购物车商品总价"""
        return sum(map(lambda x: x.total(), self.cart))
    def due(self):
        """计算商品具体折扣后价格"""
        if self.promotion is None:
            return self.total()
        return self.total() - self.promotion.discount(self)
    def __repr__(self):
        return f"<{self.customer} Order total:{self.total()} due:{self.due()}>"
Strategy
策略抽象类,用来约束一系列的策略算法。
class Promotion(ABC):
    """折扣策略基类"""
    def discount(self, order):
        """计算折扣后的价格"""
        raise NotImplementedError
?未来我们具体实现的折扣策略必须是继承自Promotion的子类,并实现discount方法。
ConcreateStrategy
具体的折扣策略
class NoPromotion(Promotion):
    """不打折"""
    def discount(self, order):
        return 0  
class RatePromotion(Promotion):
    """按比例打折"""
    def __init__(self, rate):
        self.rate = rate
    def discount(self, order):
        return order.total() * (1 - self.rate)
可以观察到,我们使用Promotion作为子类的约束,而RatePromotion是具体的折扣策略。
通过Order类来协同消费者、商品、折扣策略,实现订单的折扣计算。
# 创建三个商品
good1 = Goods('apple', 10, 1)
good2 = Goods('banana', 20, 2)
good3 = Goods('orange', 30, 3)
# 创建一个消费者
customer = Customer('米乐', 100, False)
# 将消费者和折扣绑定到订单上
order = Order(
  customer=customer, 
  promotion=RatePromotion(0.8)
)
# 将商品添加到订单中
order.add_cart(good1, good2, good3)
print(order)
# <米乐 Order total:140 due:112.0>
?新的折扣策略来了,满100减10的活动。
class FullReductionPromotion(Promotion):
    """满减"""
    def __init__(self, full, reduction):
        self.full = full
        self.reduction = reduction
    def discount(self, order):
        return order.total() // self.full * self.reduction
?调用方式
order = Order(
        customer=customer,
        promotion=FullReductionPromotion(100, 10)
)
print(order)
# <米乐 Order total:140 due:130>
应用场景
- APP的分享,它可以是微信分享,QQ分享,微博分享,各种分享所要输出的内容不一样,所以可以使用策略模式来实现不同的分享。
- 再比如出门旅游,可以自驾、坐高铁、坐飞机,这种属于出行策略。
- 日常网购各种折扣,礼金,满减等等折扣场景。
参考链接:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!