软件设计模式-策略模式的简单使用

策略模式

​ 策略模式是一种行为设计模式,是23种软件设计模式之一,它允许在运行时选择算法的行为。通过定义一系列的算法,将它们各自封装成策略(Strategy)类,并使它们可以互相替换,策略模式让算法独立于使用它们的客户端而变化,从而能够方便地切换算法或策略。

一.不使用策略模式

Cost实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class Cost {
    private Integer unitPrice;
    private int type;
}

计算运费service类

@Service
public class ExpressServiceImpl implements ExpressService {
    private static Cost JD = new Cost(8, 1);//京东的单价是8元,类型是1
    private static Cost SF = new Cost(9, 2);//顺丰的单价是9元,类型是2
    private static Cost YT = new Cost(6, 2);//圆通的单价是9元,类型是2

    @Override
    public Integer calculateCost(int type, int distance) {
        // 运费=距离*单价
        if (type == JD.getType()) {
            return JD.getUnitPrice() * distance;
        } else if (type == SF.getType()) {
            return SF.getUnitPrice() * distance;
        } else if (type == YT.getType()) {
            return YT.getUnitPrice() * distance;
        } else {
            return -1;
        }
    }
}

如果是通过以上实现该功能,每次新增快递公司都需要新增一条else-if语句,需要修改到原代码,不符合开闭原则

二.使用策略模式

1.新增策略接口
public interface ExpressStrategy {
    int calculateCost(int distance);
}
2.新增具体策略实现类

京东策略实现类

public class JDExpressStrategy implements ExpressStrategy {
    //设置单价
    private static final int UNIT_PRICE=8;
    @Override
    public int calculateCost(int distance) {
        return UNIT_PRICE * distance;
    }
}

顺丰策略实现类

public class SFExpressStrategy implements ExpressStrategy {
    private static final int UNIT_PRICE = 9;

    @Override
    public int calculateCost(int distance) {
        return UNIT_PRICE * distance;
    }
}

圆通策略实现类

public class YTExpressStrategy implements ExpressStrategy {
    private static final int UNIT_PRICE = 6;

    @Override
    public int calculateCost(int distance) {
        return UNIT_PRICE * distance;
    }
}
3.新增枚举类

供业务方法注入使用, 也可以使用Map类型、集合或者常量类等多种注入方式, 根据实际需求和个人习惯

public enum ExpressTypeEnum {
    JD(1, new JDExpressStrategy()),
    SF(2, new SFExpressStrategy()),
    YT(3, new YTExpressStrategy());

    private final int type;
    private final ExpressStrategy strategy;

    ExpressTypeEnum(int type, ExpressStrategy strategy) {
        this.type = type;
        this.strategy = strategy;
    }

    public int getType() {
        return type;
    }

    public ExpressStrategy getStrategy() {
        return strategy;
    }

    public static ExpressStrategy getStrategyByType(int type) {
        for (ExpressTypeEnum expressType : values()) {
            if (expressType.getType() == type) {
                return expressType.getStrategy();
            }
        }
        return null;
    }
}
4.业务注入并使用策略模式
@Service
public class ExpressServiceImpl_Strategy implements ExpressService  {

    @Override
    public Integer calculateCost(int type, int distance) {
        ExpressStrategy strategy = ExpressTypeEnum.getStrategyByType(type);
        if (strategy == null) {
            return -1;
        }
        return strategy.calculateCost(distance);
    }
}

三.为什么要使用策略模式

​ 使用策略模式可以避免许多的条件语句(多个if-else if-else或switch-case),使得代码更加清晰。通过策略模式,可以把具体的算法和客户端的使用代码可以被分离开,提高了算法的重用性和灵活性。增加条件时只需增加策略实现类,无需修改原本的代码,符合开闭原则。

​ 在以上例子中,想增加快递公司,只需要新增快递公司的策略实现类,和在枚举类中新增对应的枚举,不必修改任何业务逻辑层面的代码。

​ 建议在面对多层 if-else 结构(大于三层)并且每层包含的业务逻辑代码较为复杂(超过三行)时,考虑实施策略模式以优化代码结构和维护性。例子中看起来使用if-else判断更方便是因为我为了方便理解, 把业务写的很简单.

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值