无论我们做什么业务都无法避免 if else, 但是多重又会导致很多if,今天我们来讲讲如何干掉if else 让你摆脱被if else 支配的恐惧.
首先让我们来看看简单的if else 语句
public void test(TestUser testUser) {
if (Objects.isNull(testUser)){
System.out.println("执行业务 一");
} else {
System.out.println("执行业务 二");
}
}
并没有什么问题.但是如果业务稍微复杂一些呢,我们再来看看
首先贴出用户实体类
@Data
public class TestUser {
private Integer id;
private String name;
private Viplevel vipLevel;
}
在贴出用户VIP枚举
@Getter
@AllArgsConstructor
public enum Viplevel implements Serializable, IEnum {
NOVIP(0, "普通用户","普通用户"),
VIP_LEVEL1(1, "包月会员","包月会员"),
VIP_LEVEL2(2, "季度会员","季度会员"),
VIP_LEVEL3(3, "半年会员","半年会员"),
VIP_LEVEL4(4, "年费会员","年费会员");
private final Integer code;
private final String desc;
private final String msg;
@JsonCreator
public static Viplevel jsonCreator(Integer code) {
for (Viplevel value : Viplevel.values()) {
if (value.getCode().equals(code)) {
return value;
}
}
return null;
}
@JsonValue
public Map getResult() {
Map<String, Object> map = new LinkedHashMap<String, Object>();
map.put("code", getCode());
map.put("desc", getDesc());
map.put("msg", getMsg());
return map;
}
@Override
public Serializable getValue() {
return this.code;
}
}
再来看看业务
public double sellMoney(TestUser testUser) {
double proPrice = 3000;
double resultMoney = proPrice;
if (Objects.isNull(testUser)) {
//抛出异常
return proPrice;
} else {
if (Viplevel.NOVIP.equals(testUser.getVipLevel())) {
System.out.println("普通用户");
resultMoney = proPrice;
} else if (Viplevel.VIP_LEVEL1.equals(testUser.getVipLevel())) {
System.out.println("包月会员");
resultMoney = proPrice - 100;
} else if (Viplevel.VIP_LEVEL2.equals(testUser.getVipLevel())) {
System.out.println("季度会员");
resultMoney = proPrice - 300;
} else if (Viplevel.VIP_LEVEL3.equals(testUser.getVipLevel())) {
System.out.println("半年会员:");
resultMoney = proPrice * 0.8;
} else if (Viplevel.VIP_LEVEL4.equals(testUser.getVipLevel())) {
System.out.println("年会员:");
resultMoney = proPrice * 0.3;
}
return resultMoney;
}
}
天哪,这只是一个简单的例子,竟然出现如此多让人懊恼的语句.那么该如何解决呢,别着急,让我们一步步来干掉讨厌的 if else
首先思考,最终结果就是要获取到最终产品的售价,那我们就写个计算结果的方法,再让接口去继承他,这样不就能根据需求计算得到结果了吗
/**
* @author NYY
* @decription 普通用户最终产品售价
*/
public class NormalStrategy implements ComputeStrategy {
@Override
public double compute(double money) {
return money;
}
}
/**
* @author NYY
* @date 2020/6/4$
* @decription 月会员最后售价
*/
public class MonthStrategy implements ComputeStrategy {
@Override
public double compute(double money) {
return money - 100;
}
}
....以此类推
那么我们最终的业务实现是这样的
private static double getResultMoney(TestUser testUser) {
double proPrice = 3000;
double resultMoney = proPrice;
if (Objects.isNull(testUser)) {
//抛出异常
return proPrice;
} else {
if (Viplevel.NOVIP.equals(testUser.getVipLevel())) {
resultMoney = new NormalStrategy().compute(proPrice);
} else if (Viplevel.VIP_LEVEL1.equals(testUser.getVipLevel())) {
resultMoney = new MonthStrategy().compute(proPrice);
}
//......
}
return resultMoney;
}
在优化一下变成了这样
private static double getResultMoneyTwo(TestUser testUser) {
double proPrice = 3000;
double resultMoney = proPrice;
ComputeStrategy computeStrategy = null;
if (Objects.isNull(testUser)) {
//抛出异常
return proPrice;
} else {
if (Viplevel.NOVIP.equals(testUser.getVipLevel())) {
computeStrategy = new NormalStrategy();
} else if (Viplevel.VIP_LEVEL1.equals(testUser.getVipLevel())) {
computeStrategy = new MonthStrategy();
}
//......
//最后计算结果
return computeStrategy.compute(proPrice);
}
}
什么,if else 居然还在,我们发现,它需要的不仅是计算结果,主要是根据用户类型,好吧,那我们吧用户类型也提出来
public interface ComputeStrategyTwo {
// 计算方法
double compute(double money);
//获取用户类型
Integer getUserType();
}
接口继承时实现这两个方法
新增的 getUserType
方法,主要用来标示
该策略的type
值。
/**
* @author NYY
* @decription 普通用户
*/
public class NewNormalStrategy implements ComputeStrategyTwo{
@Override
public double compute(double money) {
return money;
}
@Override
public Integer getUserType() {
return Viplevel.NOVIP.getCode();
}
}
/**
* @author NYY
* @decription 月会员最后售价
*/
public class NewMonthStrategy implements ComputeStrategyTwo {
@Override
public double compute(double money) {
return money - 100;
}
@Override
public Integer getUserType() {
return Viplevel.VIP_LEVEL1.getCode();
}
}
重点又来了,这时我们就再把策略的工厂加进来
/**
* @author NYY
* @decription
*/
public class ComputeStrategyFactory {
private Map<Integer, ComputeStrategyTwo> map;
public ComputeStrategyFactory() {
List<ComputeStrategyTwo> strategies = new ArrayList<>();
strategies.add(new NewNormalStrategy());//普通用户
strategies.add(new NewMonthStrategy());//包月用户
//.......
// java 8 stream流
map = strategies.stream().collect(Collectors.toMap(ComputeStrategyTwo::getUserType, computeStrategy -> computeStrategy));
}
public static class Possessor {
public static ComputeStrategyFactory instance = new ComputeStrategyFactory();
}
public static ComputeStrategyFactory getInstance() {
return Possessor.instance;
}
public ComputeStrategyTwo get(Integer type) {
ComputeStrategyTwo computeStrategyTwo = map.get(type);
return computeStrategyTwo;
}
}
这样我们策略的工厂也有了.最终让我们看看处理业务的代码变成什么样了呢.
private static double lastResultMoney(TestUser testUser){
double proPrice = 3000;
Objects.requireNonNull(testUser,"用户对象为空了");
ComputeStrategyTwo computeStrategyTwo = ComputeStrategyFactory.getInstance().get(testUser.getVipLevel().getCode());
if(Objects.isNull(computeStrategyTwo)){
// throw new GlobalException("用户类型未知");
// 抛出全局异常
}
return computeStrategyTwo.compute(proPrice);
}