Python 程序语言设计模式思路-行为型模式:策略模式:将算法封装成独立的类,并使它们可以互相替换及支付模式数据压缩

Python 行为型模式:策略模式:将算法封装成独立的类,并使它们可以互相替换

公众号:人生只不过是一场投资

引言

在软件开发中,设计模式是一套被反复使用、经过分类和总结的代码设计经验。被广泛用于解决常见的问题。在 Python 脚本设计中,创建对象的方式多种多样,设计模式提供了多种有效的解决方案。策略模式(Strategy Pattern)是一种行为型设计模式,旨在将算法封装成独立的类,并使它们可以互相替换。这种模式使得算法的变化独立于使用算法的客户端,从而提供了灵活性和可扩展性。策略模式常用于需要在运行时根据不同条件选择不同算法的场景,如支付处理、排序和数据压缩等。

应用领域

策略模式在以下几种场景中有广泛的应用:

  1. 算法的多样性:在需要使用多种算法解决同一问题时,可以通过策略模式将不同算法封装为独立的类,并根据需求动态替换。
  2. 行为的动态改变:在运行时需要动态改变对象的行为时,可以通过策略模式在不同的算法之间切换。
  3. 消除条件语句:在使用多个条件语句选择不同算法的情况下,可以通过策略模式消除条件语句,提高代码的可维护性。
  4. 扩展性要求:在需要不断添加新算法的情况下,策略模式使得添加新算法变得简单,而不影响现有系统。
  5. 条件判断过多:当一个类的多个行为在多个条件分支中变化时,使用策略模式可以避免过多的条件判断。

示例一

以下是一个Python实现策略模式的示例,展示如何将不同的算法封装成独立的类,并使它们可以互相替换:

from abc import ABC, abstractmethod

# 策略接口
class Strategy(ABC):
    @abstractmethod
    def execute(self, data):
        pass

# 具体策略A
class ConcreteStrategyA(Strategy):
    def execute(self, data):
        return sorted(data)

# 具体策略B
class ConcreteStrategyB(Strategy):
    def execute(self, data):
        return sorted(data, reverse=True)

# 具体策略C
class ConcreteStrategyC(Strategy):
    def execute(self, data):
        return list(set(data))

# 上下文类
class Context:
    def __init__(self, strategy: Strategy):
        self._strategy = strategy

    def set_strategy(self, strategy: Strategy):
        self._strategy = strategy

    def execute_strategy(self, data):
        return self._strategy.execute(data)

# 测试策略模式

data = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]

context = Context(ConcreteStrategyA())
print("ConcreteStrategyA:", context.execute_strategy(data))  # 输出:ConcreteStrategyA: [1, 1, 2, 3, 3, 4, 5, 5, 5, 6, 9]

context.set_strategy(ConcreteStrategyB())
print("ConcreteStrategyB:", context.execute_strategy(data))  # 输出:ConcreteStrategyB: [9, 6, 5, 5, 5, 4, 3, 3, 2, 1, 1]

context.set_strategy(ConcreteStrategyC())
print("ConcreteStrategyC:", context.execute_strategy(data))  # 输出:ConcreteStrategyC: [1, 2, 3, 4, 5, 6, 9]

详解:

  1. 策略接口:Strategy类定义了一个execute方法,这是所有具体策略类必须实现的方法。
  2. 具体策略:ConcreteStrategyAConcreteStrategyBConcreteStrategyC分别实现了不同的算法。
  3. 上下文类:Context类包含一个策略对象,并提供一个execute_strategy方法来执行策略。set_strategy方法用于动态更换策略。
  4. 测试代码:创建一个上下文对象,并依次设置不同的策略,验证不同策略的执行结果。

示例二

# 支付处理

from abc import ABC, abstractmethod
# 首先,定义一个策略接口:使用 ABC 和 abstractmethod 定义了一个抽象类 PaymentStrategy,要求具体支付策略实现 pay 方法。
class PaymentStrategy(ABC):
    @abstractmethod
    def pay(self, amount):
        pass

# 然后,定义具体的支付策略类:CreditCardPayment、PayPalPayment 和 BitcoinPayment 是具体的支付策略,实现了 PaymentStrategy 接口的 pay 方法。
class CreditCardPayment(PaymentStrategy):
    def pay(self, amount):
        print(f"Paying {amount} using Credit Card.")

class PayPalPayment(PaymentStrategy):
    def pay(self, amount):
        print(f"Paying {amount} using PayPal.")

class BitcoinPayment(PaymentStrategy):
    def pay(self, amount):
        print(f"Paying {amount} using Bitcoin.")


# 定义上下文类 `PaymentContext`,用于设置和执行支付策略:PaymentContext 类包含一个策略对象,并提供 set_strategy 方法用于动态更改策略。pay 方法调用当前策略的 pay 方法进行支付。
class PaymentContext:
    def __init__(self, strategy: PaymentStrategy):
        self._strategy = strategy

    def set_strategy(self, strategy: PaymentStrategy):
        self._strategy = strategy

    def pay(self, amount):
        self._strategy.pay(amount)

# 通过具体的策略类和上下文类实现支付处理:
# 创建 PaymentContext 实例,并初始化为 CreditCardPayment 策略。
context = PaymentContext(CreditCardPayment())
# 调用 pay 方法进行支付,输出支付信息。
context.pay(100)  # 使用信用卡支付
# 使用 set_strategy 方法更改支付策略,并进行支付。
context.set_strategy(PayPalPayment())
context.pay(200)  # 使用PayPal支付

context.set_strategy(BitcoinPayment())
context.pay(300)  # 使用比特币支付

# 运行结果
Paying 100 using Credit Card.
Paying 200 using PayPal.
Paying 300 using Bitcoin.

示例三

# 数据压缩

# 首先,定义一个策略接口:使用 ABC 和 abstractmethod 定义了一个抽象类 CompressionStrategy,要求具体压缩策略实现 compress 方法。
class CompressionStrategy(ABC):
    @abstractmethod
    def compress(self, files):
        pass


# 然后,定义具体的压缩策略类:ZipCompression 和 TarCompression 是具体的压缩策略,实现了 CompressionStrategy 接口的 compress 方法。
class ZipCompression(CompressionStrategy):
    def compress(self, files):
        print(f"Compressing {files} using ZIP compression.")

class TarCompression(CompressionStrategy):
    def compress(self, files):
        print(f"Compressing {files} using TAR compression.")

# 定义上下文类 CompressionContext,用于设置和执行压缩策略:CompressionContext 类包含一个策略对象,并提供 set_strategy 方法用于动态更改策略。compress 方法调用当前策略的 compress 方法进行数据压缩。
class CompressionContext:
    def __init__(self, strategy: CompressionStrategy):
        self._strategy = strategy

    def set_strategy(self, strategy: CompressionStrategy):
        self._strategy = strategy

    def compress(self, files):
        self._strategy.compress(files)

# 通过具体的策略类和上下文类实现数据压缩:

context = CompressionContext(ZipCompression())
context.compress(["file1.txt", "file2.txt"])  # 使用ZIP压缩

context.set_strategy(TarCompression())
context.compress(["file3.txt", "file4.txt"])  # 使用TAR压缩

优点

  1. 算法独立性:将算法封装在独立的类中,使得算法可以独立于客户端进行修改和扩展。
  2. 消除条件判断:通过策略模式,可以消除客户端代码中的条件判断语句,简化代码逻辑。
  3. 动态切换:可以在运行时动态切换算法,允许在运行时选择不同的算法,提高了系统的灵活性。
  4. 扩展性强:添加新算法时,只需实现策略接口,而不需要修改现有系统代码。
  5. 开闭原则:可以在不修改现有代码的情况下引入新算法,符合开闭原则。

缺点

  1. 开销增加:引入策略模式会增加系统的类数量,每个具体策略都需要一个类,可能会增加系统的类数量。
  2. 复杂性提升:策略模式会使系统变得更加复杂,尤其是在策略数量较多时,可能会导致系统难以理解和维护。
  3. 客户端了解策略:客户端必须了解所有的策略,并且知道何时使用哪种策略,这可能会增加客户端的复杂性。

结论

策略模式在解决算法多样性和行为动态改变方面具有显著的优势,尤其在算法需要频繁变化和扩展的场景中表现出色。尽管策略模式存在增加系统复杂性和开销等缺点,但其带来的灵活性和可扩展性使其在实际开发中非常有价值。在实际应用中,应根据具体需求权衡利弊,合理使用策略模式,以充分发挥其优势,避免其不足对系统造成影响。通过合适的设计和实现,策略模式在Python应用中可以有效提高系统的灵活性和可维护性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ょ镜花う水月

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值