優雅的處理if-else 工廠模式+策略模式

摘要

對於簡單的if-else語句可以通過衛語句處理。

public void doSomeThing(Object obj){
       if(obj!=null){
           System.out.println("繼續處理");
       }else{
           System.out.println("不處理");
       }
   }

   //衛語句
   public void doSomeThing2(Object obj){
       if(obj==null){
           System.out.println("不處理");
           return;
       }
       System.out.println("繼續處理");
   }

但是實際開發過程中我們會遇到複雜的多的條件判斷,此時這種方式就無法優化了。

需求

電商系統中,可以根據用戶VIP等級,享受打折優惠。

  • 普通會員 不打折
  • 白銀會員 9折
  • 黃金會員 8折
  • 白金會員 7折
    此時直接通過if-else實現代碼如下
public double getMoney(long money,int type ){
        double result=money;
        if(type== VipEnum.PLATINUM.getValue()){
            System.out.println("白金會員7折");
            result=money*0.7;
        }else if(type==VipEnum.GOLD.getValue()){
            System.out.println("黃金會員8折");
            result=money*0.8;
        }else if(type==VipEnum.SILVER.getValue()){
            System.out.println("白銀會員9折");
            result=money*0.9;
        }else if(type==VipEnum.NORMAL.getValue()){
            System.out.println("普通會員不打折");
        }
        return result;
    }

策略模式

通過策略模式優化。

  1. 定義vip計價接口類
public interface VipStrategy {
    double getMoney(long money);
}
  1. 針對每一類vip實現上面接口

普通會員

public class NormalStrategy implements VipStrategy {
    @Override
    public double getMoney(long money) {
        System.out.println("普通會員不打折");
        return money;
    }
}

白銀會員

public class SilverStrategy implements VipStrategy {
    @Override
    public double getMoney(long money) {
        System.out.println("白銀會員9折");
        return money*0.9;
    }
}

黃金會員

public class GoldStrategy implements VipStrategy {
    @Override
    public double getMoney(long money) {
        System.out.println("黃金會員8折");
        return money*0.8;
    }
}

白金會員

public class PlatinumStrategy implements VipStrategy {
    @Override
    public double getMoney(long money) {
        System.out.println("白金會員7折");
        return money*0.7;
    }
}
  1. 根據type分別實例vipStrategy從而計算價格
public double getMoney(long money,int type ){
        VipStrategy vipStrategy;
        if(type== VipEnum.PLATINUM.getValue()){
            vipStrategy=new PlatinumStrategy();
        }else if(type==VipEnum.GOLD.getValue()){
            vipStrategy=new GoldStrategy();
        }else if(type==VipEnum.SILVER.getValue()){
            vipStrategy=new SilverStrategy();
        }else{
            vipStrategy=new NormalStrategy();
        }
        return vipStrategy.getMoney(money);
    }

通過策略模式還是會存在if-else,只是進行了一定程度的解耦。增加了可讀性,更方便了擴展。

工廠+策略模式

  1. 定義vip策略接口類
public interface VipStrategy {
    double getMoney(long money);
    int getType();
}
  1. 針對每一類vip實現上面接口

普通會員

public class NormalStrategy implements VipStrategy {
    @Override
    public double getMoney(long money) {
        System.out.println("普通會員不打折");
        return money;
    }

    @Override
    public int getType() {
        return VipEnum.NORMAL.getValue();
    }
}

白銀會員

public class SilverStrategy implements VipStrategy {
    @Override
    public double getMoney(long money) {
        System.out.println("白銀會員9折");
        return money*0.9;
    }

    @Override
    public int getType() {
        return VipEnum.SILVER.getValue();
    }
}

黃金會員

public class GoldStrategy implements VipStrategy {
    @Override
    public double getMoney(long money) {
        System.out.println("黃金會員8折");
        return money*0.8;
    }

    @Override
    public int getType() {
        return VipEnum.GOLD.getValue();
    }
}

白金會員

public class PlatinumStrategy implements VipStrategy {
    @Override
    public double getMoney(long money) {
        System.out.println("白金會員7折");
        return money*0.7;
    }

    @Override
    public int getType() {
        return VipEnum.PLATINUM.getValue();
    }
}
  1. 初始化策略工廠
public class VipStrategyFactory {
    private Map<Integer, VipStrategy> map;
    public VipStrategyFactory() {
        List<VipStrategy> strategies = new ArrayList<>();
        strategies.add(new NormalStrategy());
        strategies.add(new SilverStrategy());
        strategies.add(new GoldStrategy());
        strategies.add(new PlatinumStrategy());
        map = strategies.stream().collect(Collectors.toMap(VipStrategy::getType, strategy -> strategy));
    }
    public static class Holder {
        public static VipStrategyFactory instance = new VipStrategyFactory();
    }

    public static VipStrategyFactory getInstance() {
        return Holder.instance;
    }

    public VipStrategy get(Integer type) {
        return map.get(type);
    }
}
  1. 根據type分別實例vipStrategy從而計算價格
public static double getMoney(long money, int type) {
    VipStrategy strategy = VipStrategyFactory.getInstance().get(type);
    if (strategy == null){
        throw new IllegalArgumentException("對應vip策略不存在,[type={"+type+"}]");
    }
    return strategy.getMoney(money);
}
發佈了36 篇原創文章 · 獲贊 28 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章