Java之策略模式解析

策略模式

    • 前言
    • 1.概念
      • 结构
    • 2.基本用法
    • 3.代码示例
    • 4.策略模式的优点与缺点
    • 5.总结

前言

在开发过程中,经常不得不使用if else逻辑判断语句,太多的 if…else增加了代码的可读性,这时你可能需要策略模式来帮助你!

1.概念

策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一簇算法,将每个算法都封装起来,并且使它们之间可以互换。策略模式使得算法的变化独立于使用算法的客户端。

结构

  1. 环境类(Context): 持有一个策略对象,并在需要时调用策略对象的方法。环境类通常会将客户端的请求委托给策略对象。

  2. 策略接口(Strategy): 声明算法的接口,所有具体策略类都实现这个接口。

  3. 具体策略类(Concrete Strategy): 实现策略接口,提供具体的算法实现

2.基本用法

  1. 定义策略接口
  2. 实现具体的策略类
  3. 创建上下文类即环境类
  4. 通过调用环境类切换不同策略

定义策略接口和实现具体的策略类很好理解,重点在于环境类的构造方法形参是策略接口,使用时,通过调用环境类时传入的形参类型切换不同的策略模式。

3.代码示例

下面是一个商场销售的场景,要求根据不同的促销策略计算商品的最终价格。
示例中,PriceCalculator 是环境类,它持有一个具体的策略对象(PricingStrategy),并在需要时调用策略对象的方法。客户端可以根据不同的情况切换不同的策略,而不影响 PriceCalculator 的使用。这样,我们实现了算法的独立变化,使得系统更加灵活。

// 先定义一个策略接口,里面定义一个计算商品最终价格的抽象方法。
public interface PricingStrategy {
    double calculatePrice(double originalPrice);
}

// 具体策略类 - 普通折扣策略
public class DiscountStrategy implements PricingStrategy {
    private double discountRate;

    public DiscountStrategy(double discountRate) {
        this.discountRate = discountRate;
    }

    public double calculatePrice(double originalPrice) {
        return originalPrice * (1 - discountRate);
    }
}

// 具体策略类 - 满减策略
public class FullReductionStrategy implements PricingStrategy {
    private double fullAmount;
    private double reductionAmount;

    public FullReductionStrategy(double fullAmount, double reductionAmount) {
        this.fullAmount = fullAmount;
        this.reductionAmount = reductionAmount;
    }

    public double calculatePrice(double originalPrice) {
        return originalPrice >= fullAmount ? originalPrice - reductionAmount : originalPrice;
    }
}

// 环境类
public class PriceCalculator {
    private PricingStrategy pricingStrategy;
    //调用环境类时传入一个PricingStrategy 形参,具体策略由PricingStrategy的实现类决定
    public PriceCalculator(PricingStrategy pricingStrategy) {
        this.pricingStrategy = pricingStrategy;
    }
    
    //通过setPricingStrategy方法切换策略
    public void setPricingStrategy(PricingStrategy pricingStrategy) {
        this.pricingStrategy = pricingStrategy;
    }
    //调用具体策略
    public double calculateFinalPrice(double originalPrice) {
        return pricingStrategy.calculatePrice(originalPrice);
    }
}

// 客户端使用
public class Client {
    public static void main(String[] args) {
        // 创建具体策略对象
        PricingStrategy discountStrategy = new DiscountStrategy(0.2);
        PricingStrategy fullReductionStrategy = new FullReductionStrategy(100, 20);

        // 创建环境类
        PriceCalculator calculator = new PriceCalculator(discountStrategy);

        // 计算最终价格
        double finalPrice1 = calculator.calculateFinalPrice(100);
        System.out.println("Final Price 1: " + finalPrice1);

        // 切换策略
        calculator.setPricingStrategy(fullReductionStrategy);

        // 再次计算最终价格
        double finalPrice2 = calculator.calculateFinalPrice(150);
        System.out.println("Final Price 2: " + finalPrice2);
    }
}

4.策略模式的优点与缺点

优点 描述
***避免使用条件语句 使用策略模式可以避免大量的条件语句,提高代码的可读性和可维护性,这是使用策略模式的主要原因。
灵活性和可扩展性 策略模式使得算法独立于客户端而变得可替换和可扩展,因此系统更加灵活。
符合开闭原则 新的策略可以通过实现新的策略类来添加,而无需修改上下文类的代码,符合开闭原则。
缺点 描述
类数量增加 - 每个具体策略需一个独立策略类,可能增加类的数量。
客户端需要了解不同的策略 - 客户端需了解所有策略类,选择合适策略可能增加复杂性。
通信开销 - 切换策略时可能涉及上下文类与策略类之间的通信开销。
逻辑分散 - 将算法逻辑分散到不同策略类,可能导致简单算法过度拆分。

5.总结

步骤 描述
定义策略接口 确定共同的操作接口,各具体策略类将实现这一接口。
实现具体的策略类 为每个具体算法创建独立的策略类,分别实现策略接口中定义的操作。
创建上下文类(环境类) 上下文类包含一个策略接口的引用,并提供一个方法用于切换不同的策略。
设置策略 在客户端中,创建具体的策略对象,并将其设置到上下文类中,用于指定当前使用的算法。
调用策略方法 通过上下文类调用策略的方法,执行具体的算法。
切换策略 在运行时,可以动态切换策略,更换当前的算法实现。
优势 通过策略模式,实现了算法的独立性和可维护性,客户端可以灵活地选择和切换算法,不影响上下文类的代码。

你可能感兴趣的:(策略模式,java,策略模式,开发语言)