無論我們做什麼業務都無法避免 if else, 但是多重又會導致很多if,今天我們來講講如何干掉if else 讓你擺脫被if else 支配的恐懼. 首先讓我們來看看簡單的if else 語句 public void test(TestUser testUser) { if (Objects.is ...
無論我們做什麼業務都無法避免 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);
}