觀察者設(shè)計(jì)模式—你瞅啥,瞅你咋地
最近比較煩,比較煩,比較煩,產(chǎn)品經(jīng)理總把我為難。。。
最近在做一個(gè)線上培訓(xùn)的項(xiàng)目,費(fèi)了九牛二虎之力開發(fā)完了,這時(shí)產(chǎn)品經(jīng)理笑嘻嘻的跑過來告訴我,那啥,改個(gè)需求,線上培訓(xùn)的學(xué)員支持移除,移除了要把獲取到的相應(yīng)學(xué)分扣除掉。我冷冷的看了她一眼,心想要不是看你是個(gè)女同志并且長(zhǎng)得還行,天王老子來了也沒得商量。找到負(fù)責(zé)學(xué)分的同事A,加了一個(gè)扣除學(xué)分的接口,我這邊移除學(xué)員后調(diào)用他的接口,忙活半天,算是搞定了。
第二天,產(chǎn)品經(jīng)理又笑嘻嘻的跑過來說,那啥,昨天跟你說的那個(gè)需求,不僅要扣除學(xué)分,還要標(biāo)記缺勤。我尼瑪,你昨天咋不一起說,這不昨天沒想起來嘛,嘿嘿。沒辦法,又找到考勤的同事B,加了一個(gè)標(biāo)記缺勤的接口,我這邊移除學(xué)員后調(diào)用他的接口,忙活半天,也算OK了。
第三天,產(chǎn)品經(jīng)理又笑嘻嘻的跑過來說,那啥,昨天那個(gè)還得。。。
生氣歸生氣,需求總還是要實(shí)現(xiàn)的,這點(diǎn)基本的職業(yè)素養(yǎng)還是有的。
其實(shí)想一想,這算是一個(gè)比較典型的業(yè)務(wù)場(chǎng)景,當(dāng)一個(gè)對(duì)象的改變需要同時(shí)改變其它對(duì)象,且它不知道具體有多少對(duì)象有待改變的時(shí)候,觀察者模式,是一個(gè)比較好的選擇。
觀察者模式,定義對(duì)象間一種一對(duì)多的依賴關(guān)系,使得每當(dāng)一個(gè)對(duì)象改變狀態(tài),則所有依賴于它的對(duì)象都會(huì)得到通知并自動(dòng)更新,也叫做發(fā)布訂閱模式Publish/Subscribe,屬于行為型設(shè)計(jì)模式的一種。
上述的業(yè)務(wù)場(chǎng)景,移除學(xué)員是一個(gè)行為的發(fā)起者,同事A和B是行為的觀察者,當(dāng)然可以根據(jù)你的業(yè)務(wù)場(chǎng)景增加同事C、D、E等等。當(dāng)有移除學(xué)員的動(dòng)作發(fā)生的時(shí)候,A進(jìn)行相應(yīng)的扣除學(xué)分操作,B進(jìn)行相應(yīng)的標(biāo)記缺勤操作,C進(jìn)行。。。
下面我們用代碼來實(shí)現(xiàn)產(chǎn)品經(jīng)理小姐姐的變態(tài)需求。
1、定義行為觸發(fā)類
首先定義行為觸發(fā)的類,這個(gè)類中有一個(gè)行為移除學(xué)員的方法,當(dāng)我們移除學(xué)員的時(shí)候調(diào)用這個(gè)方法。
然后可以定義它的實(shí)現(xiàn)類,重寫成員變更的方法,這個(gè)方法的實(shí)現(xiàn)邏輯無非就是通知跟它有關(guān)的對(duì)象:我要移除學(xué)員了。
那誰能收到通知呢?
2、新增觀察者
這里的觀察者就是上述場(chǎng)景中的同事A與同事B,他們都想要收到學(xué)員變更的通知。這里的實(shí)現(xiàn)很簡(jiǎn)單,你要接收通知,把你的信息注冊(cè)過來,我這邊存儲(chǔ)一下,需要通知的時(shí)候,我把所有注冊(cè)者的信息拿出來,一一的進(jìn)行通知;如果你不想接收通知了,注銷一下注冊(cè)信息,我把你的信息從存儲(chǔ)中刪掉,這樣再通知的時(shí)候,就不會(huì)通知你了。
回到代碼中,我們用一個(gè)list進(jìn)行存儲(chǔ)所有注冊(cè)者的信息,list集合中是一個(gè)接口,要求所有觀察者都必須實(shí)現(xiàn)這個(gè)接口才能注冊(cè)進(jìn)來,接口中會(huì)有指定的方法,所有觀察者也必須實(shí)現(xiàn)這個(gè)方法,這個(gè)方法就是各個(gè)觀察者在收到通知時(shí)要進(jìn)行的操作,對(duì)應(yīng)上述場(chǎng)景中,A同事更新學(xué)分,B同事標(biāo)記缺勤等。這個(gè)接口可以自己定義,java也提供了Observer工具類供大家使用。代碼如下:
3、觀察者定義
這里觀察者的定義就比較簡(jiǎn)單了,實(shí)現(xiàn)Observer接口,重寫update方法,在類初始化的時(shí)候把自己的信息注冊(cè)進(jìn)去成為觀察者,就OK了。
4、測(cè)試
可以看到我們調(diào)用學(xué)員變更方法后,同事A和同事B都收到了通知,并執(zhí)行了相應(yīng)的操作。