天天看點

設計模式 -- 政策模式+Spring Bean代替if/else設計模式 -- 政策模式+Spring Bean代替if/else

設計模式 -- 政策模式+Spring Bean代替if/else

設計模式 -- 政策模式+Spring Bean代替if/else設計模式 -- 政策模式+Spring Bean代替if/else

政策模式

一、什麼是政策模式

  •  政策模式屬于對象的行為模式。其用意是針對一組算法,将每一個算法封裝到具有共同接口的獨立的類中,進而使得它們可以互相替換。政策模式使得算法可以在不影響到用戶端的情況下發生變化。

二、政策模式的結構

  • 政策模式是對算法的包裝,是把使用算法的責任和算法本身分割開來,委派給不同的對象管理。政策模式通常把一個系列的算法包裝到一系列的政策類裡面,作為一個抽象政策類的子類。用一句話來說,就是:“準備一組算法,并将每一個算法封裝起來,使得它們可以互換”。下面就以一個示意性的實作講解政策模式執行個體的結構。
設計模式 -- 政策模式+Spring Bean代替if/else設計模式 -- 政策模式+Spring Bean代替if/else

這個模式涉及到三個角色:

  ●  環境(Context)角色:持有一個Strategy的引用。

  ●  抽象政策(Strategy)角色:這是一個抽象角色,通常由一個接口或抽象類實作。此角色給出所有的具體政策類所需的接口。

  ●  具體政策(ConcreteStrategy)角色:包裝了相關的算法或行為。

使用政策模式完美的解決了我們if else 太多導緻代碼臃腫的問題 如:

if(teachinType == 1){
……

}else if(teachinType == 2){
……
        
}else{
            
}           

三、實戰

介紹:在我們項目實戰中,我們通常會遇到 我們背景拿到前端傳來的參數走不同的邏輯 (線上 ,線下 業務 ) ,傳回相同的資料結構:

if(teachinType == 1){
……
return list<Integer>;

}else if(teachinType == 2){
……
return list<Integer>;
 
}else{
……
return list<Integer>;        
}           

普通政策模式

  1. 定義接口
public interface Type {

    /**
     * 擷取類型,傳回集合
     */
    List<Integer> getType();

}           
  1. 定義OfflineType實作類實作Type
@Service
public class OfflineType implements Type {

    @Override
    public List<Integer> getType() {
    List<Integer> list = new ArrayList<>();
    list.add(1);
    list.add(2);
    return list;
    }
}           
  1. 定義OnlineType實作類 實作Type接口
@Service
public class OnlineType implements Type {

    @Override
    public List<Integer> getType() {
    List<Integer> list = new ArrayList<>();
    list.add(3);
    list.add(4);
    return list;
    }
}           
  1. 定義政策工廠類
public class TypeFactory{

    private static TypeFactory typeFactory = new TypeFactory();
    
    //定義Map
    private static Map<Integer,Type> map = new HashMap<>();
    
    static{
        map.put(1,new OfflineType());
        map.put(2,new OnlineType())
        }

    public static TypeFactory getInstance(){
            return typeFactory;
            }

    public Type getByType(Integer type){
        return map.get(type);
    }
}           
  1. 使用
@GetMapping("list")
public List<Integer> list(@ApiParam(value ="類型")@RequestParam(required = false) Integer type) {
    return TypeFactory.getInstance().getByType(type).getType();
);           

接口測試輸入1,輸出 1,2

接口測試輸入2,輸出 3,4

政策模式+Spring Bean代替if/else

  1. 在上面政策模式中如果在實作類中使用
@Autowired
 private Dao dao;           

就會出現 空指針的情況,

java.lang.NullPointerException           

因為 發現政策實作中的Dao接口注入的都是Null。

我們回頭看spring源碼 以及 他的介紹

  • 必須在所有使用了dao的地方,包括調用它的servcie都要進行@Autowired注入,否則之後的注入就會失敗
  • 順着這句話,發現上述使用處不就沒使用@Autowired進行注入嗎?但是這個政策模式得new啊?
  • 我們還有其他方式:通過給實作類起别名,通過@Qualifier注解擷取不同的實作類

改造:

實作類

@Service("offlineType")
public class OfflineType implements Type {

    @Autowired
    private OfflineDao dao;

    @Override
    public List<Integer> getType() {
    return dao.selectList();
    }
}           
@Service("onlineType")
public class OnlineType implements Type {

    @Autowired
    private OnlineDao dao;
    
    @Override
    public List<Integer> getType() {
  
    return dao.selectList();
    }
}           

工廠

public class TypeFactory{

    @Resource
    @Qualifier("offlineType")
    private  OnlineType offlineType;

    @Resource
    @Qualifier("onlineType")
    private  OnlineType onlineType;

    
    public  Type getByType(Integer type){
        Map<Integer, Type> map =new HashMap<>();
        map.put(1,offlineType);
        map.put(2,onlineType);
        return map.get(type);
    }
}           
//    工廠注入
    @Autowired
    private TypeFactory typeFactory;

@GetMapping("list")
public List<Integer> list(@ApiParam(value ="類型")@RequestParam(required = false) Integer type) {
    return typeFactory.getByType(type).getType();
);           

發現 不會出現空指針,IOC正常注入,資料正常傳回

設計模式 -- 政策模式+Spring Bean代替if/else設計模式 -- 政策模式+Spring Bean代替if/else
設計模式 -- 政策模式+Spring Bean代替if/else設計模式 -- 政策模式+Spring Bean代替if/else

個人部落格:

http://blog.yanxiaolong.cn/