使用觀察者模式處理業(yè)務(wù)回調(diào)

在業(yè)務(wù)開發(fā)中,可能會(huì)跟第三方平臺(tái)做對(duì)接败富,比如我們使用了騰訊云的第三方的功能。這個(gè)時(shí)候很多功能需要業(yè)務(wù)方自己處理事件回調(diào)赖临。騰訊云的實(shí)時(shí)音視頻會(huì)給我們業(yè)務(wù)后臺(tái)發(fā)送事件回調(diào)星立,比如包含了退出房間爽茴,進(jìn)入房間等等。這個(gè)時(shí)候绰垂,有人會(huì)用if到底的方式室奏,比如

@PostMapping("xxx")
public void callback(Event e) {
    if (e.eventType == 1) {
        //todo something
    }
    else if (e.eventType == 2) {
        //todo something
    }
}

這么寫也沒問(wèn)題,很多小公司小團(tuán)隊(duì)的要求就是能跑通劲装,需求方能看到結(jié)果胧沫。但如果這么寫的話,后面突然改版的話占业,需要處理其他事件绒怨,那么就需要繼續(xù)加if else,從代碼的質(zhì)量上看很難看纺酸,可擴(kuò)展性也很糟糕窖逗。其實(shí)這個(gè)時(shí)候可以通過(guò)加入設(shè)計(jì)模式處理各種不同事件。

1餐蔬、先定義一個(gè)抽象的事件處理器

public abstract class AbstractEventHandler<T extends TrtcEventParam> {

    /**
     * 獲取事件類型
     *
     * @return
     */
    public abstract Integer getEventType();

    /**
     * 處理事件
     *
     * @param t
     */
    public abstract void HandlerEvent(T t);

}

2碎紊、實(shí)現(xiàn)一個(gè)具體的事件處理器,這里比如處理退出房間事件

@Slf4j
@Component
public class ExitRoomEventHandler extends AbstractEventHandler<TrtcEventParam> {
    
    @Override
    public Integer getEventType() {
        return RoomEvent.EventType.EVENT_TYPE_EXIT_ROOM;
    }
    
    @Autowired
    private ApplicationContext applicationContext;
    
    
    @Override
    public void HandlerEvent(TrtcEventParam param) {
        if (StringUtils.startsWith(param.getEventInfo().getUserId(),                 properties.getUserIdPrefix())) {
            //這里使用了spring的事件發(fā)布機(jī)制樊诺,用來(lái)進(jìn)一步增加可擴(kuò)展性
            applicationContext.publishEvent(new ExitRoomEvent(this, param));
        }
    }
    

事件定義

public class ExitRoomEvent extends ApplicationEvent {    
    @Getter    
    private TrtcEventParam param;    
    public ExitRoomEvent(Object source, TrtcEventParam param) {        
        super(source);        
        this.param = param;    
    }
}

3仗考、定義一個(gè)簡(jiǎn)單工廠,當(dāng)初始化bean時(shí)把bean放入一個(gè)map中词爬,并對(duì)外提供根據(jù)事件碼獲取對(duì)應(yīng)處理器的的方法

@Component
public class EventHandlerFactory implements InitializingBean, ApplicationContextAware {
    
    private static final Map<Integer, AbstractEventHandler<TrtcEventParam>> EVENT_HANDLER_MAP = new HashMap<>();
    
    private ApplicationContext applicationContext;
    
   public AbstractEventHandler<TrtcEventParam> getHandler(Integer eventType) {
        return EVENT_HANDLER_MAP.get(eventType);
    }
    
    @Override
    public void afterPropertiesSet() throws Exception {
        applicationContext.getBeansOfType(AbstractEventHandler.class).values()
                .forEach(handler -> EVENT_HANDLER_MAP.put(handler.getEventType(), handler));
    }
    
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
    

4秃嗜、在處理回調(diào)的controller中調(diào)用

@PostMapping("/room/event/callback")
R execute(@RequestBody String body) {
    ...
    
    AbstractEventHandler handler = eventHandlerFactory.getHandler(param.getEventType());
    Optional.ofNullable(handler).ifPresent(h -> h.HandlerEvent(param));
    
    ...
}

5、在Observer中中監(jiān)聽事件通知

@Slf4j
@Component
public class ExitRoomEventObservers {
    
    //程序員1自己的業(yè)務(wù)
    @Order(1)
    @EventListener(ExitRoomEvent.class)
    public void method1(ExitRoomEvent event) {
        ...
    }
    
    //程序員2自己的業(yè)務(wù)
    @Order(2)
    @EventListener(ExitRoomEvent.class)
    public void method2(ExitRoomEvent event) {
        ...
    }
    
    //后來(lái)新增的業(yè)務(wù)處理
    @Order(3)
    @EventListener(ExitRoomEvent.class)
    public void method3(ExitRoomEvent event) {
        ...
    }
    
}
    

通過(guò)上述改造,如果后面需要增加新的事件處理時(shí)锅锨,加入新的事件處理器叽赊,并且發(fā)布事件就可以實(shí)現(xiàn)處理新增業(yè)務(wù)。當(dāng)然必搞,如果需要處理的業(yè)務(wù)跨了服務(wù)或者比較多的時(shí)候必指,還是建議使用mq,結(jié)合上面部分思路自行改造

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末恕洲,一起剝皮案震驚了整個(gè)濱河市塔橡,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌霜第,老刑警劉巖葛家,帶你破解...
    沈念sama閱讀 217,509評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異泌类,居然都是意外死亡癞谒,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門末誓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)扯俱,“玉大人,你說(shuō)我怎么就攤上這事喇澡⊙刚ぃ” “怎么了?”我有些...
    開封第一講書人閱讀 163,875評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵晴玖,是天一觀的道長(zhǎng)读存。 經(jīng)常有香客問(wèn)我,道長(zhǎng)呕屎,這世上最難降的妖魔是什么让簿? 我笑而不...
    開封第一講書人閱讀 58,441評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮秀睛,結(jié)果婚禮上尔当,老公的妹妹穿的比我還像新娘。我一直安慰自己蹂安,他們只是感情好椭迎,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著田盈,像睡著了一般畜号。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上允瞧,一...
    開封第一講書人閱讀 51,365評(píng)論 1 302
  • 那天简软,我揣著相機(jī)與錄音蛮拔,去河邊找鬼。 笑死痹升,一個(gè)胖子當(dāng)著我的面吹牛建炫,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播疼蛾,決...
    沈念sama閱讀 40,190評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼踱卵,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了据过?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,062評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤妒挎,失蹤者是張志新(化名)和其女友劉穎绳锅,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體酝掩,經(jīng)...
    沈念sama閱讀 45,500評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡鳞芙,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了期虾。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片原朝。...
    茶點(diǎn)故事閱讀 39,834評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖镶苞,靈堂內(nèi)的尸體忽然破棺而出喳坠,到底是詐尸還是另有隱情,我是刑警寧澤茂蚓,帶...
    沈念sama閱讀 35,559評(píng)論 5 345
  • 正文 年R本政府宣布壕鹉,位于F島的核電站,受9級(jí)特大地震影響聋涨,放射性物質(zhì)發(fā)生泄漏晾浴。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評(píng)論 3 328
  • 文/蒙蒙 一牍白、第九天 我趴在偏房一處隱蔽的房頂上張望脊凰。 院中可真熱鬧,春花似錦茂腥、人聲如沸狸涌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)杈抢。三九已至,卻和暖如春仑性,著一層夾襖步出監(jiān)牢的瞬間惶楼,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留歼捐,地道東北人何陆。 一個(gè)月前我還...
    沈念sama閱讀 47,958評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像豹储,于是被迫代替她去往敵國(guó)和親贷盲。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評(píng)論 2 354

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