Java設(shè)計模式 - 管道模式

定義

管道模式使用有序的Stage(或者Handler)來順序的處理一個輸入值词顾,每個處理過程被看做一個階段洽故。 但是每一個階段都以來上一個階段的輸出。

如果不依賴上一個階段的輸出結(jié)果,那么使用責任鏈模式即可广恢。責任鏈模式的每個處理器互相獨立欣孤,不依賴別的處理器結(jié)構(gòu)馋没。

做個比喻:

  • 管道模式可用看做是富士康流水線,每個環(huán)節(jié)都依賴上個環(huán)節(jié)的輸出

  • 責任鏈模式類似于招標降传,下發(fā)任務篷朵,誰有能力誰處理,不需要關(guān)心其他人婆排;

當然設(shè)計模式肯定是可以混用的声旺,都是使用兩個模式也是OK的。

需求中的案例

在負責的項目中段只,一般我們的業(yè)務模型會越來越復雜腮猖,想要做一件事需要和多個模型交互;

而模型之間又存在依賴關(guān)系赞枕,一個模型依賴另外一個模型的某個屬性澈缺;

每個模型都有需要校驗的部分,連續(xù)多個之后炕婶,我們的代碼結(jié)構(gòu)就會變得比較長姐赡。

比如:

輸入某個任務:
1、檢查任務是否有其他導出渠道柠掂。   查出渠道模型雏吭;
2、檢查渠道是否審核通過陪踩;

3杖们、檢查渠道審核通過之后是否有導出記錄;  查記錄模型肩狂;
4摘完、檢查導出記錄狀態(tài)是否符合預期;

復制代碼

3,4是以來1傻谁,2的結(jié)果的孝治,但是都在一起寫,目前還不是很長,但是如果繼續(xù)增加邏輯就會變得更長谈飒。

如果使用的管道模式的話:

Code

定義階段

管道模式的輸入依賴上一個階段的輸出岂座,因此入?yún)⒑统鰠⒍夹枰紤]進去。


public interface PipeStage<I,O> {

    /**
     * 通過異常來終止觀點的執(zhí)行過程
     */
    class StepException extends RuntimeException {
        public StepException(Throwable t) {
            super(t);
        }
    }

    O process(I input);
}

復制代碼

定義管道

管道可以不斷的添加新的階段杭措,并且每個階段依賴上個階段的輸出


import lombok.extern.slf4j.Slf4j;

@Slf4j
public class Pipeline<I, O> {
    private final PipeStage<I, O> currentHandler;

    Pipeline(PipeStage<I, O> currentHandler) {
        this.currentHandler = currentHandler;
    }

    <K> Pipeline<I, K> addHandler(PipeStage<O, K> newHandler) {
        log.info("addHandler");
        PipeStage<I, K> ikHandler = input -> newHandler.process(currentHandler.process(input));
        return new Pipeline<>(ikHandler);
    }

    O execute(I input) {
        return currentHandler.process(input);
    }

}
復制代碼

定義管道階段實現(xiàn)

使用剛才的例子:


import lombok.Data;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class AbstractHandler {

    @Data
    static class ChannelConfig {
        /**
         * 渠道Id
         */
        private String id;

        /***
         * 審判狀態(tài)
         */
        private int applyStatus;
    }

    @Data
    static class ChannelExportRecord{
        private String configId;

        /**
         * 導出狀態(tài)
         */
        private int exportStatus;
    }

    static class CheckApprovedHandler implements PipeStage<String, ChannelConfig> {

        @Override
        public ChannelConfig process(String input) {
            // ... 此處查詢input中的值费什,判斷渠道配置
            log.info("apprvoed {}",input);

            ChannelConfig channelConfig = new ChannelConfig();
            return channelConfig;
        }
    }

    public static class CheckRecordSuccessHandler implements PipeStage<ChannelConfig, ChannelExportRecord> {

        @Override
        public ChannelExportRecord process(ChannelConfig input) {
            log.info("record passed {}",input);
            return new ChannelExportRecord();
        }
    }

}
復制代碼

使用管道

把我們剛才的代碼組合起來:

Slf4j
public class PipeDemo {

    public static void main(String[] args) {
        Pipeline<String, ChannelExportRecord> handler = new Pipeline<>(
            new CheckApprovedHandler())
            .addHandler(new CheckRecordSuccessHandler());

        //String filters = (String)handler;
        log.info("start Handler");
        ChannelExportRecord record = handler.execute("導出配置Id");
        log.info("result {}", JSON.toJSONString(record));
    }
}

復制代碼

運行結(jié)果

image.png

總結(jié)

1、每個管道階段在實現(xiàn)的時候是互相獨立的手素;這樣也更方便單測 2鸳址、管道階段在使用的時候會組合成一個流水線管道,每個階段的輸入和輸出有一定依賴關(guān)系泉懦,上個階段要為下個階段準備好數(shù)據(jù)稿黍。 3、設(shè)計模式的通用好處:代碼可讀性崩哩,維護性提升巡球;當然管道模式有點像Java的Stream,只是Stream里面一般不會寫筆記復雜的邏輯邓嘹。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末酣栈,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子吴超,更是在濱河造成了極大的恐慌钉嘹,老刑警劉巖鸯乃,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鲸阻,死亡現(xiàn)場離奇詭異,居然都是意外死亡缨睡,警方通過查閱死者的電腦和手機鸟悴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來奖年,“玉大人细诸,你說我怎么就攤上這事÷兀” “怎么了震贵?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長水评。 經(jīng)常有香客問我猩系,道長,這世上最難降的妖魔是什么中燥? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任寇甸,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘拿霉。我一直安慰自己吟秩,他們只是感情好,可當我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布绽淘。 她就那樣靜靜地躺著涵防,像睡著了一般。 火紅的嫁衣襯著肌膚如雪收恢。 梳的紋絲不亂的頭發(fā)上武学,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天,我揣著相機與錄音伦意,去河邊找鬼火窒。 笑死,一個胖子當著我的面吹牛驮肉,可吹牛的內(nèi)容都是我干的熏矿。 我是一名探鬼主播,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼离钝,長吁一口氣:“原來是場噩夢啊……” “哼票编!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起卵渴,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤慧域,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后浪读,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體昔榴,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年碘橘,在試婚紗的時候發(fā)現(xiàn)自己被綠了互订。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡痘拆,死狀恐怖仰禽,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情纺蛆,我是刑警寧澤吐葵,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站桥氏,受9級特大地震影響温峭,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜识颊,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一诚镰、第九天 我趴在偏房一處隱蔽的房頂上張望奕坟。 院中可真熱鬧,春花似錦清笨、人聲如沸月杉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽苛萎。三九已至,卻和暖如春检号,著一層夾襖步出監(jiān)牢的瞬間腌歉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工齐苛, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留翘盖,地道東北人。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓凹蜂,卻偏偏與公主長得像馍驯,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子玛痊,可洞房花燭夜當晚...
    茶點故事閱讀 43,465評論 2 348

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