NC業(yè)務規(guī)則和業(yè)務事件

在NC二開中峻贮,經(jīng)常要在保證系統(tǒng)核心業(yè)務不變的情況下儿子,對系統(tǒng)的業(yè)務邏輯進行擴展腌紧,這些行為統(tǒng)稱為“后端擴展”贱枣。
對于單據(jù)而言监署,“業(yè)務規(guī)則擴展”和“業(yè)務事件擴展”是兩種最常見的擴展方式。這兩種方式并不沖突纽哥,可以同時使用钠乏,下面我們就來一步一步探索這兩種方式。
我們知道所有的單據(jù)都會走單據(jù)動作腳本N_XX春塌,一般來說晓避,動作腳本會調(diào)用相應Service的增刪改查方法,方法里會調(diào)用諸如InsertAction之類的動作只壳。一些單據(jù)沒有自己的action俏拱,會調(diào)用使用泛型編程的公共action,我們就以其中一個為例來分析吼句,先看代碼:

public class InsertAction<T extends IBill> {
    // ...
    public T[] processAction(T[] billVOs) {
        // 業(yè)務規(guī)則處理類
        AroundProcesser<T> processor = new AroundProcesser<T>(this.point);
        // 添加業(yè)務規(guī)則
        addInnerRule(processor);
        // 派發(fā)動作前業(yè)務事件
        fireBeforeBusinessEvent(billVOs);
        // 執(zhí)行動作前業(yè)務規(guī)則
        billVOs = processor.before(billVOs);
        // 由于支持FilterRule锅必,所以返回的billVOs可能是null
        if (billVOs == null || billVOs.length == 0) {
            return null;
        }
        // 新增保存
        T[] resultVOs = this.insert(billVOs);
        // 執(zhí)行動作后業(yè)務規(guī)則
        resultVOs = processor.after(resultVOs);
        return resultVOs;
    }
    /**
    * 添加業(yè)務規(guī)則
    */
    protected void addInnerRule(AroundProcesser<T> processor) {
        for (IRule<T> rule : beforeRule) {
            processor.addBeforeRule(rule);
        }
        for (IFilterRule<T> rule : beforeFilterRule) {
            processor.addBeforeRule(rule);
        }
        for (IRule<T> rule : afterRule) {
            processor.addAfterRule(rule);
        }
        for (IFilterRule<T> rule : afterFilterRule) {
            processor.addAfterRule(rule);
        }
    }
    /**
    * 動作前業(yè)務事件
    */
    protected void fireBeforeBusinessEvent(T[] billVOs) {
        try {
            EventDispatcherDelegate.fireEvent(IPMEventType.TYPE_INSERT_BEFORE, billVOs);
        } catch (BusinessException e) {
            ExceptionUtils.wrappException(e);
        }
    }

    /**
    * 動作后業(yè)務事件
    */
    protected void fireAfterBusinessEvent(T[] billVOs) {
        try {
            EventDispatcherDelegate.fireEvent(IPMEventType.TYPE_INSERT_AFTER, billVOs);
        } catch (BusinessException e) {
            ExceptionUtils.wrappException(e);
        }
    }
    // ...
}

其實說到底,所謂的“業(yè)務規(guī)則”和“業(yè)務事件”惕艳,不過是在代碼里預留位置執(zhí)行的一段邏輯搞隐。通過分析上面的代碼,我們可以發(fā)現(xiàn)他們是如何被觸發(fā)的:

  • 業(yè)務規(guī)則
    通過業(yè)務規(guī)則處理類例如AroundProcesser執(zhí)行远搪,并且可以通過業(yè)務規(guī)則處理類的addBeforeRule()addAfterRule()方法直接在代碼里添加前后規(guī)則劣纲。
  • 業(yè)務事件
    通過EventDispatcherDelegatefireEvent()進行事件派發(fā)。

“后端擴展”要保證系統(tǒng)核心業(yè)務不變谁鳍,理論上來說在代碼里直接為AroundProcesser等業(yè)務規(guī)則處理類的add方法添加業(yè)務規(guī)則是不規(guī)范的癞季,因為他還是改動了源碼。但是在實際的二開中倘潜,如果能獲取源碼的話绷柒,改源碼是最方便快捷的方式,下面我們來說說標準的擴展方式:

  • 業(yè)務規(guī)則
    在數(shù)據(jù)表pub_pluginitem里注冊涮因,下面的SQL語句中出現(xiàn)的字段是必須的废睦。
    insert into pub_pluginitem (pk_pluginitem, vmodulename, vcomponentname, vextendpointname, veventtype, vextendtype, vruleclass) values ('主鍵', '模塊名', '組件名', '業(yè)務規(guī)則擴展點', '擴展事件類型(before、after)', '擴展類型(addAfter蕊退、addBefore郊楣、replace)', '擴展規(guī)則類');
  • 業(yè)務事件
    在NC的“業(yè)務插件注冊”模塊里注冊,事件源ID為單據(jù)對應元數(shù)據(jù)中的主表ID瓤荔,事件類型編碼需要與代碼中EventDispatcherDelegate.fireEvent()的首個參數(shù)對應净蚤。

講了業(yè)務規(guī)則和業(yè)務事件的使用方式,最后來看他們自身的代碼實現(xiàn):

  • 業(yè)務規(guī)則
    實現(xiàn)IRule输硝、ICompareRule或者IFilterRule接口今瀑。
  • 業(yè)務事件
    實現(xiàn)IBusinessListener接口,與業(yè)務規(guī)則能直接獲取到VO不同,業(yè)務事件能直接獲取到的是IBusinessEvent類型的業(yè)務事件event橘荠,通過event.getEventType()可以獲取到事件類型編碼屿附。獲取編碼的意義在于,我們可以將一個業(yè)務事件配置到業(yè)務插件注冊里的不同事件類型下哥童,然后通過代碼判斷執(zhí)行不同的邏輯挺份。這樣可以讓不同事件類型共享同一段代碼,避免代碼冗余贮懈。
    至于VO如何獲取匀泊,最好是通過debug分析參數(shù)IBusinessEvent的實例,因為可能獲取到不同的事件類型朵你,獲取VO方式也不同各聘,一般來說event.getUserObject()是第一步。
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末抡医,一起剝皮案震驚了整個濱河市躲因,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌忌傻,老刑警劉巖大脉,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異芯勘,居然都是意外死亡箱靴,警方通過查閱死者的電腦和手機腺逛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進店門荷愕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人棍矛,你說我怎么就攤上這事安疗。” “怎么了够委?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵荐类,是天一觀的道長。 經(jīng)常有香客問我茁帽,道長玉罐,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任潘拨,我火速辦了婚禮吊输,結果婚禮上,老公的妹妹穿的比我還像新娘铁追。我一直安慰自己季蚂,他們只是感情好,可當我...
    茶點故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著扭屁,像睡著了一般算谈。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上料滥,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天然眼,我揣著相機與錄音,去河邊找鬼葵腹。 笑死罪治,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的礁蔗。 我是一名探鬼主播觉义,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼浴井!你這毒婦竟也來了晒骇?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤磺浙,失蹤者是張志新(化名)和其女友劉穎洪囤,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體撕氧,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡瘤缩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了伦泥。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片剥啤。...
    茶點故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖不脯,靈堂內(nèi)的尸體忽然破棺而出府怯,到底是詐尸還是另有隱情,我是刑警寧澤防楷,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布牺丙,位于F島的核電站,受9級特大地震影響复局,放射性物質(zhì)發(fā)生泄漏冲簿。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一亿昏、第九天 我趴在偏房一處隱蔽的房頂上張望峦剔。 院中可真熱鬧,春花似錦龙优、人聲如沸羊异。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽野舶。三九已至易迹,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間平道,已是汗流浹背睹欲。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留一屋,地道東北人窘疮。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像冀墨,于是被迫代替她去往敵國和親闸衫。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,472評論 2 348

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

  • ??JavaScript 與 HTML 之間的交互是通過事件實現(xiàn)的。 ??事件虫腋,就是文檔或瀏覽器窗口中發(fā)生的一些特...
    霜天曉閱讀 3,474評論 1 11
  • 國家電網(wǎng)公司企業(yè)標準(Q/GDW)- 面向?qū)ο蟮挠秒娦畔?shù)據(jù)交換協(xié)議 - 報批稿:20170802 前言: 排版 ...
    庭說閱讀 10,919評論 6 13
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴謹 對...
    cosWriter閱讀 11,090評論 1 32
  • JavaScript 程序采用了異步事件驅(qū)動編程模型骄酗。在這種程序設計風格下,當文檔悦冀、瀏覽器趋翻、元素或與之相關的對象發(fā)...
    劼哥stone閱讀 1,252評論 3 11
  • 最近再看阮一峰的一篇博客提到了一本書《Software Architecture Patterns》(PDF),寫...
    卓_然閱讀 7,713評論 0 22