设计模式|策略模式

文章目录

策略模式(Strategy Pattern)是一种行为设计模式,它允许在运行时选择算法的行为。它定义了一系列算法,将每个算法封装起来,并且使它们可以互相替换。策略模式可以使算法独立于使用它的客户端而变化。

策略模式的结构

策略模式包括以下结构:

  • Context(上下文):上下文是持有一个策略引用的类。上下文将客户端的请求委派给策略对象,客户端通过上下文来与策略进行交互。

  • Strategy(策略):策略是一个接口或抽象类,定义所有支持的算法的公共接口。它使得算法可以相互替换,而不影响使用算法的客户端。

  • ConcreteStrategy(具体策略):具体策略实现了策略接口,提供了算法的具体实现。

策略模式的使用场景

策略模式在以下情况下可以被考虑使用:

  • 算法需要灵活变化:当系统中某个算法的实现经常变化,并且希望在运行时能够灵活选择不同算法时,策略模式就能够胜任这个任务。

  • 避免使用条件语句:当一个类有多个行为,而这些行为在代码中通过条件语句进行切换时,策略模式可以避免使用大量的条件语句,提高代码的可读性和可维护性。

  • 相同行为的多种实现:当一个类的某个行为有多种不同的实现方式,可以使用策略模式来封装这些实现,使得可以在运行时动态切换。

  • 算法独立于客户端:当算法涉及的数据不应该被客户端暴露,或者算法的实现对客户端无关紧要时,使用策略模式可以保持算法的封装性。

  • 系统有许多类,而它们之间只有一些区别:当一系列类仅仅是行为有所不同,可以使用策略模式来避免大量的相似类的产生。

  • 支持开放/封闭原则:策略模式支持对算法的独立扩展,使得新增的算法不需要修改现有的代码,符合开放/封闭原则。

  • 需要在运行时动态选择算法:当需要在运行时动态地选择算法时,策略模式是一个很好的选择,因为它允许客户端在不修改代码的情况下切换算法。

总的来说,策略模式适用于需要在运行时选择算法 的场景,以及希望将算法的实现与调用方解耦的情况。

策略模式的优缺点

优点

  • 算法的独立性:通过将算法封装在独立的策略类中,可以使得它们易于切换、理解和扩展,而不会影响到上下文。

  • 避免条件语句:策略模式可以避免大量的条件语句,使代码更加清晰、易于维护。

  • 增强了对象的封装性:每个具体策略都是一个独立的类,策略模式有助于避免使用复杂的条件逻辑,并且使得每个策略的实现可以更加独立。

缺点

  • 增加类的数量:引入策略模式会增加系统中类的数量,每个具体策略都需要一个单独的类,这可能会导致类的数量增多,增加了系统的复杂度和理解难度。

  • 客户端必须了解所有的策略:在使用策略模式时,客户端必须了解所有可用的策略,并且决定使用哪一个策略。这可能会增加客户端的复杂性。

  • 增加对象之间的通信开销:在策略模式中,上下文对象和具体策略对象之间需要进行通信,这可能会增加对象之间的通信开销,特别是在需要频繁切换策略的情况下。

  • 选择正确的策略:选择正确的策略可能会带来一定的复杂性。如果策略选择不当,可能会导致性能下降或者产生错误的结果。

  • 可能导致类爆炸:如果系统中有大量的策略,可能会导致类的爆炸,增加维护和理解的复杂度。

尽管策略模式存在一些缺点,但在很多情况下,这些缺点都可以通过合理的设计和权衡来解决。在需要根据不同的情况选择不同的算法时,策略模式仍然是一个非常有用的设计模式。

策略模式的示例

假设有一个电商平台,根据不同的支付方式(策略),计算订单的最终价格。我们可以通过策略模式来实现:

java 复制代码
// 定义策略接口
interface PaymentStrategy {
    double calculate(double amount);
}

// 具体策略实现
class CardPaymentStrategy implements PaymentStrategy {
    @Override
    public double calculate(double amount) {
        return amount * 0.98; // 2% discount for card payment
    }
}

class PayPalPaymentStrategy implements PaymentStrategy {
    @Override
    public double calculate(double amount) {
        return amount * 0.95; // 5% discount for PayPal payment
    }
}

// 上下文
class ShoppingCart {
    private PaymentStrategy paymentStrategy;

    public void setPaymentStrategy(PaymentStrategy paymentStrategy) {
        this.paymentStrategy = paymentStrategy;
    }

    public double checkout(double amount) {
        // 计算最终价格
        return paymentStrategy.calculate(amount);
    }
}

// 使用示例
public class Main {
    public static void main(String[] args) {
        ShoppingCart cart = new ShoppingCart();
        cart.setPaymentStrategy(new PayPalPaymentStrategy()); // 选择 PayPal 支付方式
        double amount = 100;
        double finalAmount = cart.checkout(amount);
        System.out.println("Final amount after payment: " + finalAmount);
    }
}

在这个示例中,通过将不同的支付方式封装在不同的策略类中,客户端(即购物车)可以根据需要选择不同的支付方式,而不需要修改购物车的代码。这样使得系统更加灵活和可扩展。

相关推荐
WaaTong1 小时前
《重学Java设计模式》之 单例模式
java·单例模式·设计模式
7年老菜鸡3 小时前
策略模式(C++)三分钟读懂
c++·qt·策略模式
WaaTong3 小时前
《重学Java设计模式》之 原型模式
java·设计模式·原型模式
霁月风3 小时前
设计模式——观察者模式
c++·观察者模式·设计模式
暗黑起源喵6 小时前
设计模式-工厂设计模式
java·开发语言·设计模式
wrx繁星点点13 小时前
状态模式(State Pattern)详解
java·开发语言·ui·设计模式·状态模式
金池尽干15 小时前
设计模式之——观察者模式
观察者模式·设计模式
也无晴也无风雨15 小时前
代码中的设计模式-策略模式
设计模式·bash·策略模式
捕鲸叉1 天前
MVC(Model-View-Controller)模式概述
开发语言·c++·设计模式
wrx繁星点点1 天前
享元模式:高效管理共享对象的设计模式
java·开发语言·spring·设计模式·maven·intellij-idea·享元模式