創(chuàng)新互聯(lián)公司是一家集網(wǎng)站建設(shè),華鎣企業(yè)網(wǎng)站建設(shè),華鎣品牌網(wǎng)站建設(shè),網(wǎng)站定制,華鎣網(wǎng)站建設(shè)報(bào)價(jià),網(wǎng)絡(luò)營(yíng)銷(xiāo),網(wǎng)絡(luò)優(yōu)化,華鎣網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強(qiáng)企業(yè)競(jìng)爭(zhēng)力。可充分滿(mǎn)足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時(shí)我們時(shí)刻保持專(zhuān)業(yè)、時(shí)尚、前沿,時(shí)刻以成就客戶(hù)成長(zhǎng)自我,堅(jiān)持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實(shí)用型網(wǎng)站。
觀察者模式上篇
觀察者模式原理:
大家好,歡迎來(lái)到污污彈公司,最近啊,污污彈接到氣象站的外包項(xiàng)目。
功能比較簡(jiǎn)單:
要對(duì)外提供天氣接口(溫度、氣壓、濕度)需要實(shí)時(shí)通知第三方;
還需要實(shí)時(shí)在市中心公告欄上發(fā)布天氣情況。
司小司接到任務(wù)開(kāi)始動(dòng)手干了。根據(jù)Java面向?qū)ο筇匦苑治龊蟮玫饺缦滦畔ⅲ?/p>
天氣對(duì)象:WeatherData
公告板對(duì)象:CurrentConditions
天氣更新時(shí)候,調(diào)用天氣對(duì)象的dataChange方法,得到數(shù)據(jù)后,然后將數(shù)據(jù)通過(guò)display()方法展示出來(lái)。
根據(jù)上面信息,我們可以創(chuàng)建以下兩個(gè)類(lèi):
天氣對(duì)象:
@Data public class?WeatherDataOO { ? ?public ?WeatherDataOO (){} ? ?public?WeatherDataOO( CurrentCoditionOO currentCoditionOO){ ? ? ? ?this.currentCoditionOO?= currentCoditionOO; ? ?} ? ?/** ? ? *?溫度 ? ? */ ? ?private float?temperatrue; ? ?/** ? ? *?氣壓 ? ? */ ? ?private float?pressure; ? ?/** ? ? *?濕度 ? ? */ ? ?private float?humidity; ? ?/** ? ? *?公告板對(duì)象 ? ? */ ? ?private?CurrentCoditionOO?currentCoditionOO; ? ?/** ? ? *?天氣變化時(shí)候方法 ? ? */ ? ?public void?dataChange(){ ? ? ? ?currentCoditionOO.update(this.getTemperatrue(),this.getPressure(),this.getHumidity()); ? ?} ? ?/** ? ? *?模擬氣象站數(shù)據(jù) ? ? */ ? ?public void?setData(float?temperatrue,float?pressure,float?humidity){ ? ? ? ?this.temperatrue?= temperatrue; ? ? ? ?this.pressure?= pressure; ? ? ? ?this.humidity?= humidity; ? ? ? ?dataChange(); ? ?} } |
公布欄對(duì)象具體內(nèi)容如下:
@Data public class?CurrentCoditionOO { ? ?/** ? ? *?溫度 ? ? */ ? ?private float?temperatrue; ? ?/** ? ? *?氣壓 ? ? */ ? ?private float?pressure; ? ?/** ? ? *?濕度 ? ? */ ? ?private float?humidity; ? ?/** ? ? *?更新天氣的 ? ? */ ? ?public void?update(float?temperatrue,float?pressure,float?humidity){ ? ? ? ?this.temperatrue?= temperatrue; ? ? ? ?this.pressure?= pressure; ? ? ? ?this.humidity?= humidity; ? ? ? ?display(); ? ?} ? ?/** ? ? *?對(duì)外展示天氣信息 ? ? */ ? ?public void?display(){ ? ? ? ?System.out.println("****今天天氣信息******"); ? ? ? ?System.out.println("****溫度:"+temperatrue); ? ? ? ?System.out.println("****氣壓:"+pressure); ? ? ? ?System.out.println("****濕度:"+humidity); ? ?} } |
我們進(jìn)行測(cè)試:
運(yùn)行方法:
數(shù)據(jù)輸出與預(yù)期的一致。就這么簡(jiǎn)單的完事了。司小司快樂(lè)的下班了,吃炸雞,喝啤酒。
正在嗨的時(shí)候,領(lǐng)導(dǎo)來(lái)電話(huà)了,說(shuō)有個(gè)新公司要對(duì)接天氣信息。司小司想,這個(gè)簡(jiǎn)單,要么新寫(xiě)個(gè)方法,要么在更新天氣時(shí)候,新增加。如下圖:
哇嘎嘎,搞定,接著嗨去??墒?,一會(huì)老板又打電話(huà),有30家要對(duì)接!
司小司一聽(tīng),慌亂。我勒個(gè)去,這要是來(lái)一百個(gè)對(duì)接,然后又有不合作的,需要去掉的。如果每次都修改代碼,重新上線,非瘋掉不可。無(wú)法動(dòng)態(tài)添加第三方公司,擴(kuò)展性很差,需要修改結(jié)構(gòu)了。
重構(gòu)思考:
哪些變化的?變化部分抽取出來(lái),做成接口,提供。哪些不變化的?經(jīng)過(guò)分析得到:
經(jīng)常會(huì)變化的部分:公告板對(duì)象、天氣變化方法
目前公告板一次性把溫度、濕度、氣壓等公告出來(lái)了。以后可能只有溫度或者只有濕度公告板或者多個(gè)組合的。所以,公告板對(duì)象一定會(huì)變化的。果斷提取出一個(gè)接口。
從上面,我們可以看出,新接入一家,dataChange方法就要修改一次。所以這個(gè)也要抽取出來(lái)。
這里司小司打算引進(jìn)觀察者模式來(lái)經(jīng)行處理。
先來(lái)看看什么是觀察者模式:
簡(jiǎn)單理解,觀察者模式就像我們?cè)趯W(xué)校訂閱雜志、報(bào)刊或者是定牛奶一樣,或者就像我們訂閱的公眾號(hào)一樣。先和提供方談好條件,留下聯(lián)系地址、聯(lián)系人等信息。每天或固定時(shí)間,將最新信息送到指定位置。就像公眾號(hào),每天推送消息一樣。
我們就以定牛奶業(yè)務(wù)為例來(lái)說(shuō)說(shuō)觀察者模式。
定奶業(yè)務(wù)有兩個(gè)角色:奶站(subject)、用戶(hù)(Observer)
來(lái)看看這個(gè)兩個(gè)角色主要功能:
subject:奶站,能夠登記注冊(cè)用戶(hù)信息(registerObserver)、刪除用戶(hù)信息(移除:removeObserver)和給用戶(hù)提供新的牛奶(通知:notifyObservers)
根據(jù)上面說(shuō)的,我們可以得到subject接口
對(duì)應(yīng)用戶(hù)來(lái)說(shuō),主要功能,就是接收奶站提供的牛奶。
Observer:接收輸入信息。
所以我們可以得到Observer接口:
舉例圖說(shuō):
通過(guò)上面舉例,我們知道明白了觀察者模式了吧。
總結(jié),觀察者模式:對(duì)象之間多對(duì)一依賴(lài)的一種設(shè)計(jì)方案,被依賴(lài)的對(duì)象為Subject,依賴(lài)的對(duì)象為Observer,兩者之間的關(guān)系:subject通知Observer變化。
根據(jù)上面觀察者模式的分析,司小司決定用觀察者模式重新設(shè)計(jì)方案類(lèi)圖。如下:
類(lèi)之間關(guān)系說(shuō)明:
subject:實(shí)現(xiàn)了subject接口的weatherDataSt(新天氣)對(duì)象。
observer:實(shí)現(xiàn)了observer的currentConditions(新公告板)對(duì)象。
其中,由新公告板指向新天氣對(duì)象的箭頭,表示observer向subject注冊(cè)或者申請(qǐng)注銷(xiāo)操作
由新天氣對(duì)象指向新公告板對(duì)象的箭頭,表示subject通知observer信息。
使用觀察者模式具體代碼實(shí)現(xiàn):
先看項(xiàng)目結(jié)構(gòu):
結(jié)構(gòu)說(shuō)明:
interfaceObj:存放接口的包
????Observer:observer接口對(duì)象
????Subject:subject接口對(duì)象
CurrentConditionSt:實(shí)現(xiàn)了Observer接口的公告板對(duì)象
ForcastConditionSt:另一個(gè)實(shí)現(xiàn)了Observer接口的公告板對(duì)象(預(yù)測(cè)公告板)
ObserverWeatherMainTest:觀察者模式的測(cè)試類(lèi)
WeatherDataSt:實(shí)現(xiàn)了Subject接口的天氣對(duì)象
Observer類(lèi)里面代碼:
Subject類(lèi)里面代碼:
CurrentConditionSt類(lèi)里面代碼:
ForcastConditionSt類(lèi)里面代碼:
新天氣對(duì)象代碼:
測(cè)試類(lèi)里面代碼:
運(yùn)行結(jié)果:
注冊(cè)了不同的公告板。打印出結(jié)果一不一樣。達(dá)到我們預(yù)期的結(jié)果了。
聯(lián)系凱哥--》凱哥Java(kaigejava)
個(gè)人博客:www.kaigejava.com
好了,本文就講解到這里。在下一篇文章中,我們將要講解的是:對(duì)觀察者模式總結(jié)及在Java中內(nèi)置的觀察者模式