策略模式:
策略模式定义了一系列的算法,并且将每个算法封装起来,而且可以使他们之间可以相互替换,让算法独立于使用它的客户而独立变化。
案例分析:
假如在某电商软件中,有普通用户、VIP用户、SVIP用户.....,而不同等级的用户,对同一件商品的打折力度不同,这时候在代码中怎么使用策略模式去实现:
1、不使用设计模式,用if...else if...去实现
//业务层
@Service
public class StrategyService {
public double strategy(String userType, double fee) {
if ("normal".equals(userType)) {
//逻辑省略
return 0.9 * fee;
}else if("vip".equals(userType)){
//逻辑省略
return 0.8 * fee;
}else{
return fee;
}
}
}
//测试类
@SpringBootTest
class HelloDemoApplicationTests {
@Autowired
private StrategyService strategyService;
@Test
void test01() {
double normal = strategyService.strategy("normal", 100);
double vip = strategyService.strategy("vip", 100);
System.out.println("正常用户:"+normal);
System.out.println("vip用户:"+vip);
}
}
正常用户:90.0
vip用户:80.0
弊端:
(1) 如果使用if...else if...这种的话,那么strategy这个业务层的方法中,if....else if....里面会有大量的逻辑代码,导致这个方法会有大量的代码
(2)每次增加一种用户等级,这个方法就会新增加一个else if判断;
2、使用策略模式
计算策略的接口:
public interface CalculateStrategy {
String userType();
double discount(double fee);
}
正常用户的算法实现类:
@Service
public class NormalStrategy implements CalculateStrategy {
@Override
public String userType() {
return "normal";
}
@Override
public double discount(double fee) {
return 0.9 * fee;
}
}
vip用户的算法实现类:
@Service
public class VipStrategy implements CalculateStrategy {
@Override
public String userType() {
return "vip";
}
@Override
public double discount(double fee) {
return 0.9 * fee;
}
}
业务层:
@Service
public class StrategyService {
@Resource
private NormalStrategy normalStrategy;
@Resource
private VipStrategy vipStrategy;
public double strategy(String userType, double fee) {
if ("normal".equals(userType)) {
return normalStrategy.discount(fee);
} else if ("vip".equals(userType)) {
return vipStrategy.discount(fee);
} else {
return fee;
}
}
}
弊端:
虽然对比1中的代码,业务层strategy方法的代码量减少了,但是违反了开闭原则(ps:在面向对象编程领域中,开闭原则规定“软件中的对象(类,模块,函数等等)应该对于扩展是开放的,但是对于修改是封闭的”,这意味着一个实体是允许在不改变它的源代码的前提下变更它的行为。),此时如果增加新的用户等级,发现还会新增if....else if...代码。
3、在2的基础上优化
@Service
public class StrategyService {
HashMap<String, CalculateStrategy> calculateStrategyHashMap = new HashMap<>();
public StrategyService(List<CalculateStrategy> calculateStrategyList) {
for (CalculateStrategy calculateStrategy : calculateStrategyList) {
calculateStrategyHashMap.put(calculateStrategy.userType(), calculateStrategy);
}
}
public double strategy(String userType, double fee) {
CalculateStrategy calculateStrategy = calculateStrategyHashMap.get(userType);
return calculateStrategy.discount(fee);
}
}
此时的业务层代码中,就不再需要繁琐的if....else if....代码了,就算增加一个新的用户等级,比如Svip等级:
@Service
public class SvipStrategy implements CalculateStrategy {
@Override
public String userType() {
return "Svip";
}
@Override
public double discount(double fee) {
return 0.75*fee;
}
}
只需要增加一个类而已,对现有的应用层代码并无影响。