策略模式如何解决多重判断,例如根据用户的不同会员等级来计算折扣价格

212 阅读2分钟

策略模式(strategic-mode)

假设有一个系统,根据用户的不同会员等级来计算折扣价格。最初的实现可能会使用多重判断语句来判断不同等级的会员对应的折扣

public double calculateDiscount(String level, double price) {
    double discount = 1.0;
    if (level.equals("普通会员")) {
        discount = 0.9;
    } else if (level.equals("白银会员")) {
        discount = 0.8;
    } else if (level.equals("黄金会员")) {
        discount = 0.7;
    } else if (level.equals("钻石会员")) {
        discount = 0.6;
    }
    return price * discount;
}

存在以下问题:

  • 当会员等级增加时,需要修改原有的方法。
  • 多重判断语句使得代码可读性和可维护性较差。

使用策略模式

  • 定义抽象策略接口discount.DiscountStrategy
public interface DiscountStrategy {

    /**
     * 返回打折后价格
     * @param price
     * @return
     */
    double calculateDiscount(double price);
}
  • 实现具体策略类NormalMemberStrategySilverMemberStrategyGoldMemberStrategyDiamondMemberStrategy
public class NormalMemberStrategy implements DiscountStrategy{
    @Override
    public double calculateDiscount(double price) {
        return price * 0.9;
    }
}

public class SilverMemberStrategy implements DiscountStrategy {
    @Override
    public double calculateDiscount(double price) {
        return price * 0.8;
    }
}

public class GoldMemberStrategy implements DiscountStrategy {
    @Override
    public double calculateDiscount(double price) {
        return price * 0.7;
    }
}

public class DiamondMemberStrategy implements DiscountStrategy {
    @Override
    public double calculateDiscount(double price) {
        return price * 0.6;
    }
}

  • 定义DiscountContext,在构造方法中根据传入的会员等级选择相应的策略对象
public class DiscountContext {
    private DiscountStrategy discountStrategy;

    public DiscountContext(String level) {
        if (level.equals("普通会员")) {
            discountStrategy = new NormalMemberStrategy();
        } else if (level.equals("白银会员")) {
            discountStrategy = new SilverMemberStrategy();
        } else if (level.equals("黄金会员")) {
            discountStrategy = new GoldMemberStrategy();
        } else if (level.equals("钻石会员")) {
            discountStrategy = new DiamondMemberStrategy();
        }
    }

    public double calculateDiscount(double price) {
        return discountStrategy.calculateDiscount(price);
    }
}
  • 使用策略模式计算
public class Main {
    public static void main(String[] args) {
        String level = "白银会员";
        double price = 100.0;
        
        DiscountContext context = new DiscountContext(level);
        double discountPrice = context.calculateDiscount(price);
        
        System.out.println("折扣后的价格为:" + discountPrice);
    }
}

通过策略模式,可以消除多重判断,将不同等级会员的折扣计算逻辑封装成各自的策略类,使得代码结构更清晰、可扩展性更高。在需要增加新的会员等级时,只需要实现相应的策略类即可,而不需要修改原有的代码,符合开闭原则。