一、说明
策略模式是一种行为设计模式,它定义了一系列算法,将每个算法封装起来,并使它们可以互相替换。
(一) 解决问题
在需要根据不同情况选择不同算法或策略,规避不断开发新需求后,代码变得非常臃肿难以维护管理。
(二) 使用场景
- 当一个类有多个行为,而且这些行为在不同的情况下有不同的实现时
- 当需要在运行时动态地选择算法时
- 当一个类的一部分行为是固定的,一部分是可变的时,可以使用策略模式来封装可变的部分
二、结构
- 上下文(Context)维护指向具体策略的引用,且仅通过策略接口与该对象进行交流。
- 策略(Strategy)接口是所有具体策略的通用接口,它声明了一个上下文用于执行策略的方法。
- 具体策略(ConcreteStrategies)实现了上下文所用算法的各种不同变体。
- 当上下文需要运行算法时,它会在其已连接的策略对象上调用执行方法。上下文不清楚其所涉及的策略类型与算法的执行方式。
- 客户端(Client)会创建一个特定策略对象并将其传递给上下文。上下文则会提供一个设置器以便客户端在运行时替换相关联的策略。
三、伪代码
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
__doc__ = """
策略模式
例:商场优惠活动,选择不同的优惠策略,最后计算的价格也不同。而如果增加新算法,只需增加一个策略类,无需修改现有代码
"""
from abc import ABC, abstractmethod
class DiscountStrategy(ABC):
"""抽象策略类"""
@abstractmethod
def apply_discount(self, price):
pass
class PercentDiscount(DiscountStrategy):
"""具体策略类:打折策略"""
def __init__(self, discount_percent):
self.discount_percent = discount_percent
def apply_discount(self, price):
return price * (1 - self.discount_percent / 100)
class FullReduction(DiscountStrategy):
"""具体策略类:满减策略"""
def __init__(self, full_price, reduction_price):
self.full_price = full_price
self.reduction_price = reduction_price
def apply_discount(self, price):
return price - (price // self.full_price) * self.reduction_price
class Promotion:
"""上下文类:商场促销"""
def __init__(self, discount_strategy):
self.discount_strategy = discount_strategy
def apply_discount(self, price):
return self.discount_strategy.apply_discount(price)
if __name__ == "__main__":
"""
打折后价格:80.0
满减后价格:100
"""
# 商品原价
original_price = 100
# 选择打折策略,打8折
promotion = Promotion(PercentDiscount(20))
discounted_price = promotion.apply_discount(original_price)
print(f"打折后价格:{discounted_price}")
# 选择满减策略,满200减50
promotion = Promotion(FullReduction(200, 50))
discounted_price = promotion.apply_discount(original_price)
print(f"满减后价格:{discounted_price}")
四、优缺点
优点
- 灵活性和可扩展性:策略模式将算法封装成独立的类,使得可以独立地添加、修改或替换算法,而不影响到客户端的代码,从而提高了代码的灵活性和可扩展性。
- 易于维护:由于算法被封装在独立的类中,使得每个算法都有自己的类,易于理解和维护。
- 避免条件语句的使用:策略模式避免了使用大量的条件语句来选择不同的算法,使得代码更加清晰和易于理解。
- 符合开闭原则:策略模式符合开闭原则,即对扩展开放,对修改关闭,可以通过添加新的策略类来扩展功能,而不需要修改现有的代码。
缺点
- 增加了类的数量:每个具体策略都需要一个对应的策略类,可能会增加类的数量。
- 客户端必须知道所有的策略类:客户端必须知道所有的策略类,并且在使用时需要显式地选择合适的策略类,这可能会增加客户端的复杂性。
- 如果算法极少发生改变,那么没有任何理由引入新的类和接口。使用该模式只会让程序过于复杂。
【Python笔记】设计模式-CSDN博客