1. 設(shè)計(jì)模式之監(jiān)聽模式

        共 2757字,需瀏覽 6分鐘

         ·

        2023-05-14 03:25

        ??本文將會(huì)介紹設(shè)計(jì)模式中的監(jiān)聽模式。
        ??監(jiān)聽模式是一種一對多的關(guān)系,可以有任意個(gè)(一個(gè)或多個(gè))觀察者對象同時(shí)監(jiān)聽某一個(gè)對象。監(jiān)聽的對象叫觀察者(Observer),被監(jiān)聽的對象叫作被觀察者(Observable)。被觀察者對象在狀態(tài)或內(nèi)容(數(shù)據(jù))發(fā)生變化時(shí),會(huì)通知所有觀察者對象,使它們能夠做出相應(yīng)的變化。
        ??監(jiān)聽模式又名觀察者模式,顧名思義就是觀察與被觀察的關(guān)系。比如你在燒開水的時(shí)候看著它開沒開,你就是觀察者,水就是被觀察者;再比如你在帶小孩,你關(guān)注他是不是餓了,是不是渴了,是不是撒尿了,你就是觀察者,小孩就是被觀察者。觀察者模式是對象的行為模式,又叫發(fā)布/訂閱(Publish/Subscribe)模式、模型/視圖(Model/View)模式、源/監(jiān)聽器(Source/Listener)模式或從屬者(Dependents)模式。
        ??監(jiān)聽模式的核心思想就是在被觀察者與觀察者之間建立一種自動(dòng)觸發(fā)的關(guān)系。

        例子

        ??以家中常見的熱水器為例,需對水溫進(jìn)行監(jiān)控,當(dāng)水溫在50-70℃時(shí),會(huì)發(fā)出警告:可以用來洗澡了!當(dāng)水溫在100℃時(shí),會(huì)發(fā)出警告:可以用來飲水了!在這里洗澡模式和飲用模式扮演了監(jiān)聽的角色,而熱水器則是被監(jiān)聽的對象。一旦熱水器中的水溫度發(fā)生變化,監(jiān)聽者就能及時(shí)知道并做出相應(yīng)的判斷和動(dòng)作。
        ??UML類圖如下:

        608ea255dd0455c893958c97508f6d56.webp監(jiān)聽模式的類圖
        Python代碼如下:
              #?-*-?coding:?utf-8?-*-
        from?abc?import?ABCMeta,?abstractmethod


        #?觀察者的基類
        class?Observer(metaclass=ABCMeta):
        ????@abstractmethod
        ????def?update(self,?observable,?object):
        ????????pass


        #?被觀察者的基類
        class?Observable:
        ????def?__init__(self):
        ????????self.__observers?=?[]

        ????def?addObserver(self,?observer):
        ????????self.__observers.append(observer)

        ????def?removeObserver(self,?observer):
        ????????self.__observers.remove(observer)

        ????def?notifyObservers(self,?object=0):
        ????????for?o?in?self.__observers:
        ????????????o.update(self,?object)


        #?熱水器
        class?WaterHeater(Observable):
        ????def?__init__(self):
        ????????super().__init__()
        ????????self.__temperature?=?25

        ????def?getTemperature(self):
        ????????return?self.__temperature

        ????def?setTemperature(self,?temperature):
        ????????self.__temperature?=?temperature
        ????????print(f"當(dāng)前溫度是:{str(self.__temperature)}℃")
        ????????self.notifyObservers()


        #?洗澡模式
        class?WashingMode(Observer):
        ????def?update(self,?observable,?object):
        ????????if?isinstance(observable,?WaterHeater)?and?50?<=?observable.getTemperature()?<=?70:
        ????????????print("水已燒好!溫度正好,可以用來洗澡了。")


        #?飲用模式
        class?DrinkingMode(Observer):
        ????def?update(self,?observable,?object):
        ????????if?isinstance(observable,?WaterHeater)?and?observable.getTemperature()?>=?100:
        ????????????print("水以燒開!可以用來飲用了。")


        def?testWaterHeater():
        ????heater?=?WaterHeater()
        ????washingObser?=?WashingMode()
        ????drinkingObser?=?DrinkingMode()
        ????heater.addObserver(washingObser)
        ????heater.addObserver(drinkingObser)
        ????heater.setTemperature(40)
        ????heater.setTemperature(60)
        ????heater.setTemperature(100)


        if?__name__?==?'__main__':
        ????testWaterHeater()

        輸出結(jié)果如下:

              當(dāng)前溫度是:40℃
        當(dāng)前溫度是:60℃
        水已燒好!溫度正好,可以用來洗澡了。
        當(dāng)前溫度是:100℃
        水以燒開!可以用來飲用了。

        總結(jié)

        ??在設(shè)計(jì)監(jiān)聽模式的程序時(shí)需要注意以下幾點(diǎn):

        • 要明確誰是觀察者誰是被觀察者,只要明白誰是應(yīng)該關(guān)注的對象,問題也就明白了。一般觀察者與被觀察者之間是多對一的關(guān)系,一個(gè)被觀察對象可以有多個(gè)監(jiān)聽對象(觀察者)。

        • Observable在發(fā)送廣播通知的時(shí)候,無須指定具體的Observer,Observer可以自己決定是否訂閱Subject的通知。

        • 被觀察者至少需要有三個(gè)方法:添加監(jiān)聽者、移除監(jiān)聽者、通知Observer的方法。觀察者至少要有一個(gè)方法:更新方法,即更新當(dāng)前的內(nèi)容,做出相應(yīng)的處理。

        • 添加監(jiān)聽者和移除監(jiān)聽者在不同的模型稱謂中可能會(huì)有不同命名。


        瀏覽 128
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評論
        圖片
        表情
        推薦
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
          
          

            1. 一级特黄色大片 | 使劲操逼 | 女人18毛片AAA片水真多 一区二区三区成人 | 国产久久精品视频 | 陈好一级裸体毛片 |