1. 程式人生 > >利用策略模式改善程式碼中的if巢狀

利用策略模式改善程式碼中的if巢狀

      什麼是策略模式?其思想是針對一組演算法,將每一種演算法都封裝到具有共同介面的獨立的類中,從而是它們可以相互替換。策略模式的最大特點是使得演算法可以在不影響客戶端的情況下發生變化,從而改變不同的功能。

     假如我們有一個根據不同使用者型別返回不同折扣的方法,我們的實現可能是這樣:

import org.springframework.stereotype.Service;

@Service
public class CashService {

    public double cash(String type, double
money) { if ("svip".equals(type)) { return money * 0.75; } else if ("vip".equals(type)) { return money * 0.9; } else { return money; } } }

    現在我們各個型別的使用者折扣耦合在一起,修改一個使用者的折扣力度有可能會對其他型別使用者造成影響。根據策略模式的思想,我們需要把折扣力度封裝成具體的方法並面向介面程式設計。我們首先定義公共的介面DiscountService,編寫其實現類,則我們改造後的程式碼可能如下所示:

     

import com.study.designer.strategy.NormalDiscountStrategy;
import com.study.designer.strategy.SvipDiscountStrategy;
import com.study.designer.strategy.VipDiscountStrategy;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class CashService { @Autowired private SvipDiscountStrategy svipDiscountStrategy; @Autowired private VipDiscountStrategy vipDiscountStrategy; @Autowired private NormalDiscountStrategy normalDiscountStrategy; public double cash(String type, double money) { if ("svip".equals(type)) { return svipDiscountStrategy.getMoney(money); } else if ("vip".equals(type)) { return vipDiscountStrategy.getMoney(money); } else { return normalDiscountStrategy.getMoney(money); } } }

 

      可以看到,改造後的CashService中還存在許多if判斷,我們需要消除這些if判斷。我們可以在CashService初始化時就獲取到所有的折扣策略,然後根據具體型別計算具體折扣。獲取所有策略可以交由Spring來完成,改造後的程式碼如下所示:

import com.study.designer.strategy.inf.DiscountStrategy;

import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class CashService {


    private Map<String, DiscountStrategy> strategyMap = new HashMap<>();


    public CashService(List<DiscountStrategy> strategies) {
        for (DiscountStrategy strategy : strategies) {
            strategyMap.put(strategy.getType(), strategy);
        }
    }


    public double cash(String type, double money) {
        return strategyMap.get(type).getMoney(money);
    }
}