工作中用到的狀態(tài)模式

狀態(tài)模式涉及到的類有:
1.上下文陕靠,擁有一個(gè)或多個(gè)狀態(tài)類實(shí)例,對(duì)客戶端暴露接口鞠评;
2.狀態(tài)接口茂蚓,封裝具體狀態(tài)類所對(duì)應(yīng)的行為;
3.具體狀態(tài)類剃幌,真正實(shí)現(xiàn)狀態(tài)行為聋涨。

類圖如下:


微信截圖_20181121143455.png

代碼示例:
先看一下之前同事寫的代碼:

@Override  
    public List<DrlTypeDTO> getDrlOperationDTO(String typeId) {  
        List<Operation> list = Operation.list;  
        List<Operation> operationList = new ArrayList<>();  
          
        //字符串類型(等于,不等于,被包含于,不被包含于,不為空,為空,匹配,不匹配)  
        if (DataType.STR.getValue().toString().equals(typeId)) {  
            for (int i = 0; i < list.size(); i++) {  
                if (!list.get(i).getIndex().equals(Operation.GRE.getIndex())  
                        && !list.get(i).getIndex().equals(Operation.GREEQL.getIndex())   
                        && !list.get(i).getIndex().equals(Operation.LESS.getIndex())   
                        && !list.get(i).getIndex().equals(Operation.LESSEQL.getIndex())   
                        && !list.get(i).getIndex().equals(Operation.BET.getIndex())  
                        && !list.get(i).getIndex().equals(Operation.CONTAINS.getIndex())   
                        && !list.get(i).getIndex().equals(Operation.EXCLUDES.getIndex())) {  
                    operationList.add(list.get(i));  
                }  
            }  
              
        //數(shù)值類型(等于,大于,大于等于,小于,小于等于,不等于,被包含于,不被包含于,不為空,為空)  
        } else if (DataType.INT.getValue().toString().equals(typeId) || DataType.FLOAT.getValue().toString().equals(typeId)  
                || DataType.DOUBLE.getValue().toString().equals(typeId)) {  
            for (int i = 0; i < list.size(); i++) {  
                if (!list.get(i).getIndex().equals(Operation.MATCHES.getIndex())   
                        && !list.get(i).getIndex().equals(Operation.NMATCHES.getIndex())   
                        && !list.get(i).getIndex().equals(Operation.BET.getIndex())  
                        && !list.get(i).getIndex().equals(Operation.CONTAINS.getIndex())   
                        && !list.get(i).getIndex().equals(Operation.EXCLUDES.getIndex())){  
                    operationList.add(list.get(i));  
                }    
            }  
              
        //布爾類型(等于,不等于,不為空,為空)  
        } else if (DataType.BOOLEAN.getValue().toString().equals(typeId)) {  
            for (int i = 0; i < list.size(); i++) {  
                if (list.get(i).getIndex().equals(Operation.EQL.getIndex())  
                        || list.get(i).getIndex().equals(Operation.NEQL.getIndex())  
                        || list.get(i).getIndex().equals(Operation.NULL.getIndex())   
                        || list.get(i).getIndex().equals(Operation.NOTNULL.getIndex())){  
                    operationList.add(list.get(i));  
                }  
            }  
              
        //數(shù)組類型(包含,不包含,不為空,為空)  
        } else if (DataType.STRS.getValue().toString().equals(typeId) || DataType.DOUBLES.getValue().toString().equals(typeId)  
                || DataType.INTS.getValue().toString().equals(typeId)) {  
            for (int i = 0; i < list.size(); i++) {  
                if (list.get(i).getIndex().equals(Operation.CONTAINS.getIndex())  
                        || list.get(i).getIndex().equals(Operation.EXCLUDES.getIndex())  
                        || list.get(i).getIndex().equals(Operation.NULL.getIndex())   
                        || list.get(i).getIndex().equals(Operation.NOTNULL.getIndex())){  
                    operationList.add(list.get(i));  
                }  
            }  
              
        //其他類型為所有操作符  
        } else {  
            operationList = list;  
        }  
        return RuleAssembler.toDrlOperationDtos(operationList);  
    }  

一堆if else看著就頭疼,那么改成狀態(tài)模式怎么做呢负乡?

代碼如下:

1.Context類

public class DrlOperatorContext {  
  
    private DrlOperatorState state;  
  
    private List<Operation> operationList = new ArrayList<>();  
  
    public List<Operation> getOperationList(){  
        return operationList;  
    }  
  
    public List<Operation> addOperateList(String typeId) {  
  
        List<Operation> list = Operation.list;  
  
        //字符串類型(等于,不等于,被包含于,不被包含于,不為空,為空,匹配,不匹配)  
        if (DataType.STR.getValue().toString().equals(typeId)) {  
            state = new DrlStrOperator();  
  
            //數(shù)值類型(等于,大于,大于等于,小于,小于等于,不等于,被包含于,不被包含于,不為空,為空)  
        } else if (DataType.INT.getValue().toString().equals(typeId) || DataType.FLOAT.getValue().toString().equals(typeId)  
                || DataType.DOUBLE.getValue().toString().equals(typeId)) {  
            state = new DrlNumberOperator();  
  
            //布爾類型(等于,不等于,不為空,為空)  
        } else if (DataType.BOOLEAN.getValue().toString().equals(typeId)) {  
  
            state = new DrlBooleanOperator();  
  
            //數(shù)組類型(包含,不包含,不為空,為空)  
        } else if (DataType.STRS.getValue().toString().equals(typeId) || DataType.DOUBLES.getValue().toString().equals(typeId)  
                || DataType.INTS.getValue().toString().equals(typeId)) {  
            state = new DrlArrayOperator();  
            //其他類型為所有操作符  
        } else {  
  
            operationList = list;  
        }  
  
        if (state != null) {  
            operationList = state.addOperateList(list, this);  
        }  
        return operationList;  
    }  
}  

2.State接口

public interface DrlOperatorState {  
  
    List<Operation> addOperateList(List<Operation> list, DrlOperatorContext context);  
}  

3.具體狀態(tài)

public class DrlArrayOperator implements DrlOperatorState {  
  
    @Override  
    public List<Operation> addOperateList(List<Operation> list, DrlOperatorContext context) {  
        List<Operation>  operationList = context.getOperationList();  
        for (int i = 0; i < list.size(); i++) {  
            if (list.get(i).getIndex().equals(Operation.CONTAINS.getIndex())  
                    || list.get(i).getIndex().equals(Operation.EXCLUDES.getIndex())  
                    || list.get(i).getIndex().equals(Operation.NULL.getIndex())  
                    || list.get(i).getIndex().equals(Operation.NOTNULL.getIndex())){  
                operationList.add(list.get(i));  
            }  
        }  
        return operationList;  
    }  
}  
  
public class DrlBooleanOperator implements DrlOperatorState{  
  
    @Override  
    public List<Operation> addOperateList(List<Operation> list, DrlOperatorContext context) {  
  
        List<Operation> operationList = context.getOperationList();  
        for (int i = 0; i < list.size(); i++) {  
            if (list.get(i).getIndex().equals(Operation.EQL.getIndex())  
                    || list.get(i).getIndex().equals(Operation.NEQL.getIndex())  
                    || list.get(i).getIndex().equals(Operation.NULL.getIndex())  
                    || list.get(i).getIndex().equals(Operation.NOTNULL.getIndex())){  
                operationList.add(list.get(i));  
            }  
        }  
        return operationList;  
    }  
}  
  
public class DrlNumberOperator implements DrlOperatorState {  
  
    @Override  
    public List<Operation> addOperateList(List<Operation> list, DrlOperatorContext context) {  
  
        List<Operation> operationList = context.getOperationList();  
  
        for (int i = 0; i < list.size(); i++) {  
            if (!list.get(i).getIndex().equals(Operation.MATCHES.getIndex())  
                    && !list.get(i).getIndex().equals(Operation.NMATCHES.getIndex())  
                    && !list.get(i).getIndex().equals(Operation.BET.getIndex())  
                    && !list.get(i).getIndex().equals(Operation.CONTAINS.getIndex())  
                    && !list.get(i).getIndex().equals(Operation.EXCLUDES.getIndex())){  
                operationList.add(list.get(i));  
            }  
        }  
  
        return operationList;  
    }  
}  
  
  
public class DrlStrOperator implements DrlOperatorState {  
  
    @Override  
    public List<Operation> addOperateList(List<Operation> list, DrlOperatorContext context) {  
  
        List<Operation> operationList = context.getOperationList();  
  
        for (int i = 0; i < list.size(); i++) {  
            if (!list.get(i).getIndex().equals(Operation.GRE.getIndex())  
                    && !list.get(i).getIndex().equals(Operation.GREEQL.getIndex())  
                    && !list.get(i).getIndex().equals(Operation.LESS.getIndex())  
                    && !list.get(i).getIndex().equals(Operation.LESSEQL.getIndex())  
                    && !list.get(i).getIndex().equals(Operation.BET.getIndex())  
                    && !list.get(i).getIndex().equals(Operation.CONTAINS.getIndex())  
                    && !list.get(i).getIndex().equals(Operation.EXCLUDES.getIndex())) {  
                operationList.add(list.get(i));  
            }  
        }  
        return operationList;  
    }  
}  

4.客戶端調(diào)用

@Override  
    public List<DrlTypeDTO> getDrlOperationDTO(String typeId) {  
        DrlOperatorContext context = new DrlOperatorContext();  
        List<Operation> operationList = context.addOperateList(typeId);  
        return RuleAssembler.toDrlOperationDtos(operationList);  
    }  

這樣大大簡化了牍白,客戶端的調(diào)用方式,提高了代碼的也讀性抖棘,同時(shí)需要增加新的類型只需要實(shí)現(xiàn)State接口即可茂腥。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市切省,隨后出現(xiàn)的幾起案子最岗,更是在濱河造成了極大的恐慌,老刑警劉巖数尿,帶你破解...
    沈念sama閱讀 222,807評(píng)論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件仑性,死亡現(xiàn)場離奇詭異惶楼,居然都是意外死亡右蹦,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,284評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門歼捐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來何陆,“玉大人,你說我怎么就攤上這事豹储〈ぃ” “怎么了?”我有些...
    開封第一講書人閱讀 169,589評(píng)論 0 363
  • 文/不壞的土叔 我叫張陵,是天一觀的道長巩剖。 經(jīng)常有香客問我铝穷,道長,這世上最難降的妖魔是什么佳魔? 我笑而不...
    開封第一講書人閱讀 60,188評(píng)論 1 300
  • 正文 為了忘掉前任曙聂,我火速辦了婚禮,結(jié)果婚禮上鞠鲜,老公的妹妹穿的比我還像新娘宁脊。我一直安慰自己,他們只是感情好贤姆,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,185評(píng)論 6 398
  • 文/花漫 我一把揭開白布榆苞。 她就那樣靜靜地躺著,像睡著了一般霞捡。 火紅的嫁衣襯著肌膚如雪坐漏。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,785評(píng)論 1 314
  • 那天碧信,我揣著相機(jī)與錄音仙畦,去河邊找鬼。 笑死音婶,一個(gè)胖子當(dāng)著我的面吹牛慨畸,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播衣式,決...
    沈念sama閱讀 41,220評(píng)論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼寸士,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了碴卧?” 一聲冷哼從身側(cè)響起弱卡,我...
    開封第一講書人閱讀 40,167評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎住册,沒想到半個(gè)月后婶博,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,698評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡荧飞,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,767評(píng)論 3 343
  • 正文 我和宋清朗相戀三年凡人,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片叹阔。...
    茶點(diǎn)故事閱讀 40,912評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡挠轴,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出耳幢,到底是詐尸還是另有隱情岸晦,我是刑警寧澤,帶...
    沈念sama閱讀 36,572評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站启上,受9級(jí)特大地震影響邢隧,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜冈在,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,254評(píng)論 3 336
  • 文/蒙蒙 一府框、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧讥邻,春花似錦迫靖、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,746評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至发魄,卻和暖如春盹牧,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背励幼。 一陣腳步聲響...
    開封第一講書人閱讀 33,859評(píng)論 1 274
  • 我被黑心中介騙來泰國打工汰寓, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人苹粟。 一個(gè)月前我還...
    沈念sama閱讀 49,359評(píng)論 3 379
  • 正文 我出身青樓有滑,卻偏偏與公主長得像,于是被迫代替她去往敵國和親嵌削。 傳聞我的和親對(duì)象是個(gè)殘疾皇子毛好,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,922評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容