一、适用场景
在日常的代码开发过程中,你是否频繁的适用if/else、if elseif else 等这种语句,有没有想过使用设计模式来改造你的代码,让你的代码更加有质量。
我们在开发过程中,很常见的会遇到,不同角色对资源进行不同的分配,例如:不同的用户身份(vip、svip、normal)面临不同的计价策略。
此时面对这样的场景:
这种计价策略属于平级状态,每次根据用户的身份只会选择一种计价策略。
未使用策略模式前的代码:
import com.shuwen.demo.service.FeeCalculationService;
import org.springframework.stereotype.Service;
@Service
public class FeeCalculationsServiceImpl implements FeeCalculationService {
@Override
public double feeCalculation(String type, double fee) {
if ("vip".equals(type)){
return fee * 0.98;
}else if ("svip".equals(type)){
return fee * 0.90;
}else{
return fee ;
}
}
}
发现当我们需要对其进行扩展时,只能对原来的代码进行添加,在原来的代码上修改代码,这就是代码中的坏味道。
我们需要去除这种代码中的坏味道,让代码清新起来,让代码的可拓展性更强,便于项目的维护和二次开发。
现在我们将其进行改造:
a)定义策略接口 规范策略必有内容
public interface DiscountStrategy {
//角色类型
public String type();
//计价策略
public double discount(double fee);
}
b)实现策略接口,编写具体的实现业务
1)VIP用户计价策略的具体实现
import com.shuwen.demo.strategy.DiscountStrategy;
import org.springframework.stereotype.Service;
@Service
public class VipDiscountStrategy implements DiscountStrategy {
@Override
public String type() {
return "vip";
}
@Override
public double discount(double fee) {
return fee * 0.98;
}
}
2)SVIP用户计价策略的具体实现
import com.shuwen.demo.strategy.DiscountStrategy;
import org.springframework.stereotype.Service;
@Service
public class SvipDiscountStrategy implements DiscountStrategy {
@Override
public String type() {
return "svip";
}
@Override
public double discount(double fee) {
return fee * 0.70;
}
}
3)普通用户计价策略的具体实现
import com.shuwen.demo.strategy.DiscountStrategy;
import org.springframework.stereotype.Service;
@Service
public class NormalDiscountStrategy implements DiscountStrategy {
@Override
public String type() {
return "normal";
}
@Override
public double discount(double fee) {
return fee;
}
}
c)将具体的策略方法,存放到map之中,方便使用
//用map来存策略方法
Map<String,DiscountStrategy> discountStrategyMap = new HashMap<>();
//利用构造方法 将策略方法放到map中 此处List<DiscountStrategy> spring将自动注入策略
public FeeCalculationServiceImpl(List<DiscountStrategy> discountStrategies) {
for (DiscountStrategy discountStrategy : discountStrategies){
discountStrategyMap.put(discountStrategy.type(),discountStrategy);
}
}
d)具体的业务实现,就变的可拓展性极强。
import com.shuwen.demo.service.FeeCalculationService;
import com.shuwen.demo.strategy.DiscountStrategy;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class FeeCalculationServiceImpl implements FeeCalculationService {
//用map来存策略方法
Map<String,DiscountStrategy> discountStrategyMap = new HashMap<>();
//利用构造方法 将策略方法放到map中 此处List<DiscountStrategy> spring将自动注入策略
public FeeCalculationServiceImpl(List<DiscountStrategy> discountStrategies) {
for (DiscountStrategy discountStrategy : discountStrategies){
discountStrategyMap.put(discountStrategy.type(),discountStrategy);
}
}
@Override
public double feeCalculation(String type, double fee) {
// 只需利用map 用key:type 找到对应的具体策略方法,直接使用即可
// 如有需求改变,有新的用户身份 直接实现策略接口 并交由spring工厂管理即可
DiscountStrategy discountStrategy = discountStrategyMap.get(type);
double discount = discountStrategy.discount(fee);
return discount;
}
}
这样来实现业务代码,泛泛而看是去掉了很多if else 条件判断,这样当我们的需求发生变化时,只需新增一个具体的策略方法即可。
例如现在有一个新需求,黑卡用户需要打0.5折:

这时,我们只需要增加一个黑卡用户的计价具体策略方法即可,不需要变更原来的业务处理方法。
import com.shuwen.demo.strategy.DiscountStrategy;
import org.springframework.stereotype.Service;
@Service
public class HVipDiscountStrategy implements DiscountStrategy {
@Override
public String type() {
return "hvip";
}
@Override
public double discount(double fee) {
return fee * 0.50;
}
}
这时,我们的代码质量大大改善,以后维护也更加轻松~
测试调用方法具体实现:
@Test
public void test1() {
double vip = feeCalculationService.feeCalculation("vip", 5000);
System.out.println("yesterday you have consumer 5000 dollars,true you have consumer "+vip);
}
原文:https://www.cnblogs.com/l3306/p/10763305.html