設(shè)計模式 -- 策略模式+Spring Bean代替if/else

設(shè)計模式 -- 策略模式+Spring Bean代替if/else

在這里插入圖片描述

策略模式

一、什么是策略模式

  • 策略模式屬于對象的行為模式。其用意是針對一組算法瓤狐,將每一個算法封裝到具有共同接口的獨立的類中乱陡,從而使得它們可以相互替換。策略模式使得算法可以在不影響到客戶端的情況下發(fā)生變化盖袭。

二、策略模式的結(jié)構(gòu)

  • 策略模式是對算法的包裝彼宠,是把使用算法的責(zé)任和算法本身分割開來鳄虱,委派給不同的對象管理。策略模式通常把一個系列的算法包裝到一系列的策略類里面凭峡,作為一個抽象策略類的子類拙已。用一句話來說,就是:“準(zhǔn)備一組算法摧冀,并將每一個算法封裝起來倍踪,使得它們可以互換”。下面就以一個示意性的實現(xiàn)講解策略模式實例的結(jié)構(gòu)索昂。
在這里插入圖片描述

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

●  環(huán)境(Context)角色:持有一個Strategy的引用建车。

●  抽象策略(Strategy)角色:這是一個抽象角色,通常由一個接口或抽象類實現(xiàn)椒惨。此角色給出所有的具體策略類所需的接口缤至。

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

使用策略模式完美的解決了我們if else 太多導(dǎo)致代碼臃腫的問題 如:

if(teachinType == 1){
……

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

三康谆、實戰(zhàn)

介紹:在我們項目實戰(zhàn)中领斥,我們通常會遇到 我們后臺拿到前端傳來的參數(shù)走不同的邏輯 (線上 嫉到,線下 業(yè)務(wù) ) ,返回相同的數(shù)據(jù)結(jié)構(gòu):

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實現(xiàn)類實現(xiàn)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實現(xiàn)類 實現(xiàn)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. 在上面策略模式中如果在實現(xiàn)類中使用
 @Autowired
 private Dao dao;

就會出現(xiàn) 空指針的情況,

java.lang.NullPointerException

因為 發(fā)現(xiàn)策略實現(xiàn)中的Dao接口注入的都是Null唬涧。

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

  • 必須在所有使用了dao的地方,包括調(diào)用它的servcie都要進(jìn)行@Autowired注入,否則之后的注入就會失敗

  • 順著這句話疫赎,發(fā)現(xiàn)上述使用處不就沒使用@Autowired進(jìn)行注入嗎?但是這個策略模式得new熬糇洹虚缎?

  • 我們還有其他方式:通過給實現(xiàn)類起別名撵彻,通過@Qualifier注解獲取不同的實現(xiàn)類

改造:

實現(xiàn)類

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

    @Autowired
    private OfflineDao dao;

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

實現(xiàn)類

@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();
);

發(fā)現(xiàn) 不會出現(xiàn)空指針钓株,IOC正常注入,數(shù)據(jù)正常返回


image.png
image.png

個人博客:http://blog.yanxiaolong.cn/

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末陌僵,一起剝皮案震驚了整個濱河市轴合,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌碗短,老刑警劉巖受葛,帶你破解...
    沈念sama閱讀 212,718評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異偎谁,居然都是意外死亡总滩,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評論 3 385
  • 文/潘曉璐 我一進(jìn)店門巡雨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來闰渔,“玉大人,你說我怎么就攤上這事铐望「越В” “怎么了?”我有些...
    開封第一講書人閱讀 158,207評論 0 348
  • 文/不壞的土叔 我叫張陵正蛙,是天一觀的道長督弓。 經(jīng)常有香客問我,道長乒验,這世上最難降的妖魔是什么愚隧? 我笑而不...
    開封第一講書人閱讀 56,755評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮奸攻,結(jié)果婚禮上蒜危,老公的妹妹穿的比我還像新娘。我一直安慰自己睹耐,他們只是感情好辐赞,可當(dāng)我...
    茶點故事閱讀 65,862評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著硝训,像睡著了一般响委。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上窖梁,一...
    開封第一講書人閱讀 50,050評論 1 291
  • 那天赘风,我揣著相機(jī)與錄音,去河邊找鬼纵刘。 笑死邀窃,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的假哎。 我是一名探鬼主播瞬捕,決...
    沈念sama閱讀 39,136評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼舵抹!你這毒婦竟也來了肪虎?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,882評論 0 268
  • 序言:老撾萬榮一對情侶失蹤惧蛹,失蹤者是張志新(化名)和其女友劉穎扇救,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體香嗓,經(jīng)...
    沈念sama閱讀 44,330評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡迅腔,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,651評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了靠娱。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片沧烈。...
    茶點故事閱讀 38,789評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖饱岸,靈堂內(nèi)的尸體忽然破棺而出掺出,到底是詐尸還是另有隱情,我是刑警寧澤苫费,帶...
    沈念sama閱讀 34,477評論 4 333
  • 正文 年R本政府宣布汤锨,位于F島的核電站,受9級特大地震影響百框,放射性物質(zhì)發(fā)生泄漏闲礼。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,135評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望柬泽。 院中可真熱鬧慎菲,春花似錦、人聲如沸锨并。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽第煮。三九已至解幼,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間包警,已是汗流浹背撵摆。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留害晦,地道東北人特铝。 一個月前我還...
    沈念sama閱讀 46,598評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像壹瘟,于是被迫代替她去往敵國和親鲫剿。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,697評論 2 351