Java設(shè)計模式綜合運用(門面+模版方法+責任鏈+策略)

引言:很久沒有更新了,主要是工作忙奋姿。最近逸尖,工作中一個子系統(tǒng)升級古沥,把之前不易擴展的缺點給改進了一下,主要是運用了幾個設(shè)計模式進行稍微改造了一下娇跟。

1.項目背景

在公司的一個實際項目中岩齿,需要做一個第三方公司(以下簡稱GMG)的系統(tǒng)集成工作,把該公司的一些訂單數(shù)據(jù)集成到自己公司平臺下苞俘,各個訂單具有一些共性盹沈,但是也有其特有的特征。 經(jīng)過設(shè)計苗胀,目前我把訂單分為POLICY和BOB類型(暫且這么說吧襟诸,反正就是一種訂單類型,大家參照著看就OK)基协。

在訂單數(shù)據(jù)集成到公司平臺前歌亲,需要對訂單數(shù)據(jù)進行一些必要的業(yè)務(wù)邏輯校驗操作,并且每個訂單都有自己的校驗邏輯(包含公共的校驗邏輯)澜驮。 本節(jié)介紹的便是整個訂單集成系統(tǒng)中的校驗邏輯在綜合利用設(shè)計模式的基礎(chǔ)上進行架構(gòu)設(shè)計陷揪。

2.校驗邏輯

本校驗邏輯主要分為四個部分:

  1. 校驗文件名稱(RequestValidator.validateFileInfo)
  2. 校驗文件內(nèi)容中的概要部分(RequestValidator.validateSummary)
  3. 校驗文件內(nèi)容中的列名稱(RequestValidator.validateHeaders)
  4. 校驗文件內(nèi)容中的明細(RequestValidator.validateDetails)
    其實上面的RequestValidator的實現(xiàn)邏輯最后都是委托給RequestValidationFacade這個門面類進行相應的校驗操作。

3.實現(xiàn)細節(jié)

3.1 domain介紹

主要分為RequestFile和RequestDetail兩個domain,RequestFile接收泛型的類型(即RequestFile), 使得其子類能夠自動識別相應的RequestDetail的子類杂穷。RequestFile為抽象類悍缠,定義了以下抽象方法,由子類實現(xiàn):

//由子類實現(xiàn)具體的獲取文件明細內(nèi)容
public abstract List<T> getRequestDetails();
//由子類實現(xiàn)具體的獲取workflow的值
public abstract WorkflowEnum getProcessWorkFlow();
//由子類實現(xiàn)文件列字段名列表
public abstract String[] getDetailHeaders();

RequestDetail及其子類就是workflow對應文件的明細內(nèi)容耐量。

3.2 WorkflowEnum枚舉策略

本例中如下規(guī)定:

  1. workflow為WorkflowEnum.POLICY對應文件名為:csync_policy_yyyyMMdd_HHmmss_count.txt
  2. workflow為WorkflowEnum.BOB對應文件名為:csync_bob_integration_yyyyMMdd_HHmmss_count.txt
    以上校驗邏輯在AbstractRequestValidation類相應的子類中實現(xiàn)(validateFileName方法)飞蚓,其實這個枚舉貫穿整個校驗組件,它就是一個針對每個業(yè)務(wù)流程定義的一個枚舉策略廊蜒。

3.3 涉及到的設(shè)計模式實現(xiàn)思路

3.3.1 門面模式

在客戶端調(diào)用程序中趴拧,采用門面模式進行統(tǒng)一的入口(門面模式講究的是脫離具體的業(yè)務(wù)邏輯代碼)。門面模式封裝的結(jié)果就是避免高層模塊深入子系統(tǒng)內(nèi)部山叮,同時提供系統(tǒng)的高內(nèi)聚著榴、低耦合的特性。

此案例中屁倔,門面類為RequestValidationFacade脑又,然后各個門面方法的參數(shù)均為抽象類RequestFile,通過RequestFile->getProcessWorkFlow()決定調(diào)用AbstractRequestValidation中的哪個子類。 AbstractRequestValidation類構(gòu)造方法中定義了如下邏輯:

requestValidationHandlerMap.put(this.accessWorkflow(),this.accessBeanName());

把子類中Spring自動注入的實體bean緩存到requestValidationHandlerMap中问麸,key即為WorkflowEnum枚舉值往衷,value為spring bean name, 然后在門面類中可以通過對應的枚舉值取得BeanName,進而得到AbstractRequestValidation相應的子類對象口叙,進行相應的校驗操作炼绘。

注:這邊動態(tài)調(diào)用到AbstractRequestValidation相應的子類對象,其實也是隱藏著【策略模式】的影子妄田。

類圖如下:


門面模式

3.3.2 模版方法模式

在具體的校驗邏輯中,用到核心設(shè)計模式便是模版方法模式驮捍,AbstractRequestValidation抽象類中定義了以下抽象方法:

 /**
     * validate the file details
     * @param errMsg
     * @param requestFile
     * @return
     */
    protected abstract StringBuilder validateFileDetails(StringBuilder errMsg,RequestFile requestFile);

    /**
     * validate the file name
     * @param fileName
     * @return
     */
    protected abstract String validateFileName(String fileName);

    /**
     * return the current CSYNC_UPDATE_WORKFLOW.UPDATE_WORKFLOW_ID
     * @return
     */
    protected abstract WorkflowEnum accessWorkflow();

    /**
     * return the current file name's format ,such as: csync_policy_yyyyMMdd_HHmmss_count.txt
     * @return
     */
    protected abstract String accessFileNameFormat();

    /**
     * return the subclass's spring bean name
     * @return
     */
    protected abstract String accessBeanName();

以上抽象方法就類似我們常說的鉤子函數(shù)疟呐,由子類實現(xiàn)即可。類圖如下圖所示:


模版方法模式

3.3.3 責任鏈模式

在AbstractRequestValidation抽象類中有個抽象方法validateFileDetails东且,校驗的是文件的明細內(nèi)容中的相應業(yè)務(wù)規(guī)則,此為核心校驗, 較為復雜扣讼,而且針對每個業(yè)務(wù)流程猜极,其校驗邏輯相差較大,在此處色查,利用了責任鏈模式進行處理薯演。

Validator為校驗器的父接口,包含兩個泛型參數(shù)(即:<R extends RequestDetail,F extends RequestFile>)秧了,其實現(xiàn)類可以方便的轉(zhuǎn)換需要校驗的文件明細跨扮。

String doValidate(R detail, F file, ValidatorChain chain) throws BusinessValidationException;

該方法含有一個ValidatorChain參數(shù),就自然而然的為該校驗器形成一個鏈條提供便利條件验毡。

ValidatorChain為校驗器鏈衡创,含有兩個接口方法:

String doValidate(T requestDetail, F requestFile) throws BusinessValidationException;

ValidatorChain addValidator(Validator validator, WorkflowEnum workflowId);

該處有一個addValidator方法,為ValidatorChain對象添加校驗器的方法晶通,返回本身璃氢。對應于每個業(yè)務(wù)流程需要哪些校驗器就在此實現(xiàn)即可(即AbstractRequestValidation的子類方法validateFileDetails)。

類圖如下圖所示:


責任鏈模式1-validator chain

責任鏈模式2-部分validator

3.3.4 策略模式

如果單單從上面的校驗器實現(xiàn)上來看狮辽,如果需要增加一個校驗器一也,就需要在AbstractRequestValidation的子類方法validateFileDetails中添加,然后進行相應的校驗操作隘竭。這樣就會非常的麻煩塘秦,沒有做到真正的解耦。 此時动看,策略模式就發(fā)揮到了可以動態(tài)選擇某種校驗策略的作用(Validator的實現(xiàn)類就是一個具體的校驗策略)尊剔。

AbstractValidatorHandler抽象類持有FileDetailValidatorChain類的對象,并且實現(xiàn)累Spring的一個接口ApplicationListener(是為了Spring容器啟動完成的時候自動把相應的校驗器加入到校驗器鏈中)菱皆。 核心就是WorkflowEnum這個策略枚舉的作用须误,在子類可以動態(tài)的取得相應的校驗器對象挨稿。

根據(jù)子類提供需要的校驗器所在的包名列表和不需要的校驗器列表,動態(tài)配置出需要的校驗器鏈表京痢。核心實現(xiàn)邏輯如下:

private void addValidators() {
    List<Class<? extends Validator>> validators = getValidators();

    validators.forEach((validator) -> {
        String simpleName = validator.getSimpleName();
        String beanName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1);

        LOGGER.info("Added validator:{},spring bean name is:{}",simpleName,beanName);

        Validator validatorInstance = ApplicationUtil.getApplicationContext().getBean(beanName,validator);

        fileDetailValidatorChain.addValidator(validatorInstance,getWorkflowId());

    });
}

具體實現(xiàn)可以參考github代碼即可奶甘。

該類含有以下幾個抽象方法:

protected abstract WorkflowEnum getWorkflowId();
/**
 * the package need to be added the validators
 * @return
 */
protected abstract Set<String> getBasePackages();

/**
 * the classes need to be excluded
 * @return
 */
protected abstract Set<Class> excludeClasses();

事例代碼地址https://github.com/landy8530/DesignPatterns

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市祭椰,隨后出現(xiàn)的幾起案子臭家,更是在濱河造成了極大的恐慌,老刑警劉巖方淤,帶你破解...
    沈念sama閱讀 216,744評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件钉赁,死亡現(xiàn)場離奇詭異,居然都是意外死亡携茂,警方通過查閱死者的電腦和手機你踩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,505評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來讳苦,“玉大人带膜,你說我怎么就攤上這事≡眨” “怎么了膝藕?”我有些...
    開封第一講書人閱讀 163,105評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長卿堂。 經(jīng)常有香客問我束莫,道長,這世上最難降的妖魔是什么草描? 我笑而不...
    開封第一講書人閱讀 58,242評論 1 292
  • 正文 為了忘掉前任览绿,我火速辦了婚禮,結(jié)果婚禮上穗慕,老公的妹妹穿的比我還像新娘饿敲。我一直安慰自己,他們只是感情好逛绵,可當我...
    茶點故事閱讀 67,269評論 6 389
  • 文/花漫 我一把揭開白布怀各。 她就那樣靜靜地躺著,像睡著了一般术浪。 火紅的嫁衣襯著肌膚如雪瓢对。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,215評論 1 299
  • 那天胰苏,我揣著相機與錄音硕蛹,去河邊找鬼。 笑死,一個胖子當著我的面吹牛法焰,可吹牛的內(nèi)容都是我干的秧荆。 我是一名探鬼主播,決...
    沈念sama閱讀 40,096評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼埃仪,長吁一口氣:“原來是場噩夢啊……” “哼乙濒!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起卵蛉,我...
    開封第一講書人閱讀 38,939評論 0 274
  • 序言:老撾萬榮一對情侶失蹤颁股,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后傻丝,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體豌蟋,經(jīng)...
    沈念sama閱讀 45,354評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,573評論 2 333
  • 正文 我和宋清朗相戀三年桑滩,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片允睹。...
    茶點故事閱讀 39,745評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡运准,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出缭受,到底是詐尸還是另有隱情胁澳,我是刑警寧澤,帶...
    沈念sama閱讀 35,448評論 5 344
  • 正文 年R本政府宣布米者,位于F島的核電站韭畸,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏蔓搞。R本人自食惡果不足惜胰丁,卻給世界環(huán)境...
    茶點故事閱讀 41,048評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望喂分。 院中可真熱鬧锦庸,春花似錦、人聲如沸蒲祈。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,683評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽梆掸。三九已至扬卷,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間酸钦,已是汗流浹背怪得。 一陣腳步聲響...
    開封第一講書人閱讀 32,838評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人汇恤。 一個月前我還...
    沈念sama閱讀 47,776評論 2 369
  • 正文 我出身青樓庞钢,卻偏偏與公主長得像,于是被迫代替她去往敵國和親因谎。 傳聞我的和親對象是個殘疾皇子基括,可洞房花燭夜當晚...
    茶點故事閱讀 44,652評論 2 354

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

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法财岔,內(nèi)部類的語法风皿,繼承相關(guān)的語法,異常的語法匠璧,線程的語...
    子非魚_t_閱讀 31,624評論 18 399
  • 設(shè)計模式匯總 一桐款、基礎(chǔ)知識 1. 設(shè)計模式概述 定義:設(shè)計模式(Design Pattern)是一套被反復使用、多...
    MinoyJet閱讀 3,939評論 1 15
  • 參考資料:菜鳥教程之設(shè)計模式 設(shè)計模式概述 設(shè)計模式(Design pattern)代表了最佳的實踐夷恍,通常被有經(jīng)驗...
    Steven1997閱讀 1,173評論 1 12
  • 我們浪費掉了太多的青春,那是一段如此自以為是又如此狼狽不堪的青春歲月指黎。有歡笑也有淚水朋凉,有朝氣也有頹廢,有甜蜜也有荒...
    阿準先生閱讀 442評論 3 4
  • 夜風很好醋安,盡管到家已經(jīng)快11點了杂彭,我還是想去跑兩圈。 一吓揪、或者逆流亲怠,不要害怕 到體育公園的時候,最后幾個跑步的人三...
    阿不快跑閱讀 393評論 7 3