跳转到内容

Java策略模式

来自代码酷

Java策略模式[编辑 | 编辑源代码]

策略模式(Strategy Pattern)是行为型设计模式之一,它允许在运行时选择算法的行为。通过将算法封装成独立的类,策略模式使得算法可以独立于使用它的客户端变化。这种模式遵循开闭原则(Open/Closed Principle),即对扩展开放,对修改关闭。

介绍[编辑 | 编辑源代码]

策略模式的核心思想是将一组算法(策略)封装到独立的类中,并使它们可以互相替换。客户端代码不直接依赖具体的算法实现,而是通过一个统一的接口调用不同的策略。这种方式提高了代码的灵活性,减少了条件语句的使用,并使得添加新策略变得简单。

策略模式通常包含以下三个角色:

  • Context(上下文):维护对策略对象的引用,并通过策略接口调用具体策略。
  • Strategy(策略接口):定义所有支持的算法的公共接口。
  • ConcreteStrategy(具体策略):实现策略接口的具体算法。

结构[编辑 | 编辑源代码]

以下是策略模式的类图表示:

classDiagram class Context { -strategy: Strategy +setStrategy(Strategy) +executeStrategy() } class Strategy { <<interface>> +execute() } class ConcreteStrategyA { +execute() } class ConcreteStrategyB { +execute() } Context --> Strategy Strategy <|-- ConcreteStrategyA Strategy <|-- ConcreteStrategyB

代码示例[编辑 | 编辑源代码]

以下是一个简单的Java示例,展示如何使用策略模式实现不同的支付方式:

// 策略接口
interface PaymentStrategy {
    void pay(int amount);
}

// 具体策略:信用卡支付
class CreditCardPayment implements PaymentStrategy {
    private String cardNumber;
    private String name;

    public CreditCardPayment(String cardNumber, String name) {
        this.cardNumber = cardNumber;
        this.name = name;
    }

    @Override
    public void pay(int amount) {
        System.out.println(amount + " paid with credit card (" + cardNumber + ")");
    }
}

// 具体策略:PayPal支付
class PayPalPayment implements PaymentStrategy {
    private String email;

    public PayPalPayment(String email) {
        this.email = email;
    }

    @Override
    public void pay(int amount) {
        System.out.println(amount + " paid via PayPal (" + email + ")");
    }
}

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

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

    public void checkout(int amount) {
        paymentStrategy.pay(amount);
    }
}

// 客户端代码
public class StrategyPatternDemo {
    public static void main(String[] args) {
        ShoppingCart cart = new ShoppingCart();

        // 使用信用卡支付
        cart.setPaymentStrategy(new CreditCardPayment("1234-5678-9012-3456", "John Doe"));
        cart.checkout(100);

        // 使用PayPal支付
        cart.setPaymentStrategy(new PayPalPayment("john.doe@example.com"));
        cart.checkout(50);
    }
}

输出:

100 paid with credit card (1234-5678-9012-3456)
50 paid via PayPal (john.doe@example.com)

实际应用场景[编辑 | 编辑源代码]

策略模式在以下场景中特别有用: 1. 支付系统:支持多种支付方式(信用卡、PayPal、加密货币等)。 2. 排序算法:根据数据量大小选择不同的排序策略(快速排序、归并排序等)。 3. 压缩工具:提供不同的压缩算法(ZIP、RAR、7z等)。 4. 导航系统:根据用户偏好提供不同的路线规划策略(最快路线、最短路线、避开收费站等)。

优点[编辑 | 编辑源代码]

  • 符合开闭原则,易于扩展新策略。
  • 避免使用多重条件判断语句。
  • 算法可以自由切换。
  • 提高代码的可维护性和可读性。

缺点[编辑 | 编辑源代码]

  • 客户端必须了解不同的策略。
  • 会增加系统中类的数量。
  • 策略对象可能会增加内存开销。

与其他模式的关系[编辑 | 编辑源代码]

  • 策略模式与状态模式相似,但策略模式中的策略变化由客户端控制,而状态模式中的状态转换由上下文或状态本身控制。
  • 策略模式与模板方法模式都封装算法,但策略模式使用组合,而模板方法模式使用继承。

数学表示[编辑 | 编辑源代码]

从数学角度看,策略模式可以表示为: Context=(S,f)其中f:SAlgorithm,S={s1,s2,...,sn} 其中S是策略集合,f是策略选择函数。

总结[编辑 | 编辑源代码]

策略模式是一种强大的设计模式,特别适用于需要动态选择算法或行为的场景。通过将算法封装到独立的类中,它提高了代码的灵活性和可维护性。初学者可以从简单的支付系统示例开始理解策略模式,而高级用户可以利用它构建更复杂的系统架构。