日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【转】第01课:生活中的监听模式——一坑爹的热水器

發布時間:2023/12/10 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【转】第01课:生活中的监听模式——一坑爹的热水器 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
      • 用程序來模擬生活
      • 從劇情中思考監聽模式
        • 監聽模式
      • 監聽模式的模型抽象
        • 代碼框架
        • 類圖
        • 基于框架的實現
        • 模型說明
          • 設計要點
          • 推模型和拉模型
      • 應用場景

【故事劇情】

剛剛大學畢業的 Tony 只身來到北京這個碩大的城市,開始了北漂的生活。但剛剛畢業的他身無絕技、包無分文,為了生活只能住在沙河鎮一個偏僻的村子里,每天坐著程序員專線(13號線)來回穿梭于昌平區與西城區……

在一個寒冷的冬天,下班之后要坐2個小時的地鐵+公交才能回到住處,Tony 拖著疲憊的身體回到家。準備洗一個熱水澡暖暖身體,耐何簡陋的房子中用的還是90年代的熱水器。因為熱水器沒有警報更沒有自動切換模式的功能,所以燒熱水必須得守著;不然時間長了燙死豬,時間短了又冷成狗。無奈的 Tony 背靠著墻,頭望著天花板,深夜中做起了白日夢:一定要努力工作,過兩個月我就可以自己買一個智能熱水器了:水燒好了就發一個警報,我就可以直接去洗操。還要能自己設定模式,既可以燒開了用來喝,可以燒暖了用來洗……

用程序來模擬生活

Tony 陷入白日夢中……他的夢雖然在現實世界里不能立即實現,但在程序世界里可以。程序來源于生活,下面我們就用代碼來模擬 Tony 的白日夢。

源碼示例:

  • class WaterHeater:

  • "熱水器:戰勝寒冬的有利武器"

  • ?
  • def __init__(self):

  • self.__observers = []

  • self.__temperature = 25

  • ?
  • def getTemperature(self):

  • return self.__temperature

  • ?
  • def setTemperature(self, temperature):

  • self.__temperature = temperature

  • print("current temperature is:", self.__temperature)

  • self.notifies()

  • ?
  • def addObserver(self, observer):

  • self.__observers.append(observer)

  • ?
  • def notifies(self):

  • for o in self.__observers:

  • o.update(self)

  • ?
  • ?
  • class Observer:

  • "洗澡模式和飲用模式的父類"

  • ?
  • def update(self, waterHeater):

  • pass

  • ?
  • ?
  • class WashingMode(Observer):

  • "該模式用于洗澡用"

  • ?
  • def update(self, waterHeater):

  • if waterHeater.getTemperature() >= 50 and waterHeater.getTemperature() < 70:

  • print("水已燒好,溫度正好!可以用來洗澡了。")

  • ?
  • ?
  • class DrinkingMode(Observer):

  • "該模式用于飲用"

  • ?
  • def update(self, waterHeater):

  • if waterHeater.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)

  • 輸出結果:

  • current temperature is: 40

  • current temperature is: 60

  • 水已燒好,溫度正好!可以用來洗澡了。

  • current temperature is: 100

  • 水已燒開!可以用來飲用了。

  • 從劇情中思考監聽模式

    這個代碼非常簡單,水燒到50-70度時,會發出警告:可以用來洗澡了!燒到100度也會發出警告:可以用來喝了!在這里洗澡模式和飲用模式扮演了監聽的角色,而熱水器則是被監聽的對象。一旦熱水器中的水溫度發生變化,監聽者都能及時知道并做出相應的判斷和動作。其實這就是程序設計中監聽模式的生動展現。

    監聽模式

    監聽模式又名觀察者模式,顧名思意就是觀察與被觀察的關系,比如你在燒開水得時時看著它開沒開,你就是觀察者,水就是被觀察者;再比如說你在帶小孩,你關注她是不是餓了,是不是喝了,是不是撒尿了,你就是觀察者,小孩就是被觀察者。

    觀察者模式是對象的行為模式,又叫發布-訂閱(Publish/Subscribe)模式、模型-視圖(Model/View)模式、源-監聽器(Source/Listener)模式或從屬者(Dependents)模式。當你看這些模式的時候,不要覺得陌生,它們就是觀察者模式。

    觀察者模式一般是一種一對多的關系,可以有任意個(一個或多個)觀察者對象同時監聽某一個對象。監聽的對象叫觀察者(后面提到監聽者,其實就指觀察者,兩者是等價的),被監聽的對象叫被觀察者(Observable,也叫主題 Subject)。被觀察者對象在狀態或內容發生變化時,會通知所有觀察者對象,使它們能夠做出相應的變化(如自動更新自己的信息)。

    監聽模式的模型抽象

    代碼框架

    上面的示例代碼還是相對比較粗糙,我們可以對它進行進一步的重構和優化,抽象出監聽模式的框架模型。

  • class Observer:

  • "觀察者的基類"

  • ?
  • def update(self, observer, 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)

  • 類圖

    上面的代碼框架可用類圖表示如下:

    addObserver,removeObserver 分別用于添加和刪除觀察者,notifyObservers 用于內容或狀態變化時通知所有的觀察者。因為 Observable 的 notifyObservers 會調用 Observer 的 update 方法,所有觀察者不需要關心被觀察的對象什么時候會發生變化,只要有變化就是自動調用 update,只需要關注 update 實現就可以了。

    基于框架的實現

    有了上面的代碼框架之后,我們要實現示例代碼的功能就會更簡單了。最開始的示例代碼我們假設它為 version 1.0,那么再看看基于框架的 version 2.0 吧。

  • 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("current temperature is:", self.__temperature)

  • self.notifyObservers()

  • ?
  • ?
  • class WashingMode(Observer):

  • "該模式用于洗澡用"

  • ?
  • def update(self, observable, object):

  • if isinstance(observable,

  • WaterHeater) and observable.getTemperature() >= 50 and observable.getTemperature() < 70:

  • print("水已燒好,溫度正好!可以用來洗澡了。")

  • ?
  • ?
  • class DrinkingMode(Observer):

  • "該模式用于飲用"

  • ?
  • def update(self, observable, object):

  • if isinstance(observable, WaterHeater) and observable.getTemperature() >= 100:

  • print("水已燒開!可以用來飲用了。")

  • 測試代碼不用變。自己跑一下,會發現輸出結果和之前的是一樣的。

    模型說明

    設計要點

    在設計觀察者模式的程序時要注意以下幾點:

  • 要明確誰是觀察者誰是被觀察者,只要明白誰是關注對象,問題也就明白了。一般觀察者與被觀察者之間是多對一的關系,一個被觀察對象可以有多個監聽對象(觀察者)。如一個編輯框,有鼠標點擊的監聽者,也有鍵盤的監聽者,還有內容改變的監聽者。
  • Observable 在發送廣播通知的時候,無須指定具體的 Observer,Observer 可以自己決定是否要訂閱 Subject 的通知。
  • 被觀察者至少需要有三個方法:添加監聽者、移除監聽者、通知 Observer 的方法;觀察者至少要有一個方法:更新方法,更新當前的內容,作出相應的處理。
  • 添加監聽者、移除監聽者在不同的模型稱謂中可能會有不同命名,如觀察者模型中一般,addObserver,removeObserver;在源-監聽器(Source/Listener)模型中一般是 attach/detach,應用在桌面編程的窗口中,還可能是 attachWindow/detachWindow,或 Register/UnRegister。不要被名稱迷糊了,不管他們是什么名稱,其實功能都是一樣的,就是添加/刪除觀察者。
  • 推模型和拉模型

    觀察者模式根據其側重的功能還可以分為推模型和拉模型。

    推模型:被觀察者對象向觀察者推送主題的詳細信息,不管觀察者是否需要,推送的信息通常是主題對象的全部或部分數據。一般這種模型的實現中,會把被觀察者對象中的全部或部分信息通過 update 的參數傳遞給觀察者 [update(Object obj) ,通過 obj 參數傳遞]。

    如某應用 App 的服務要在凌晨1:00開始進行維護,1:00-2:00期間所有服務將會暫停,這里你就需要向所有的 App 客戶端推送完整的通知消息:“本服務將在凌晨1:00開始進行維護,1:00-2:00期間所有服務將會暫停,感謝您的理解和支持!” 不管用戶想不想知道,也不管用戶會不會在這段期間去訪問,消息都需要被準確無誤地通知到。這就是典型的推模型的應用。

    拉模型:被觀察者在通知觀察者的時候,只傳遞少量信息。如果觀察者需要更具體的信息,由觀察者主動到被觀察者對象中獲取,相當于是觀察者從被觀察者對象中拉數據。一般這種模型的實現中,會把被觀察者對象自身通過 update 方法傳遞給觀察者 [update(Observable observable ),通過 observable 參數傳遞 ],這樣在觀察者需要獲取數據的時候,就可以通過這個引用來獲取了。

    如某應用 App 有新的版本推出,則需要發送一個版本升級的通知消息,而這個通知消息只會簡單地列出版本號和下載地址,如果你需要升級你的 App 還需要調用下載接口去下載安裝包完成升級。這其實也可以理解成是拉模型。

    推模型和拉模型其實更多的是語義和邏輯上的區別。我們上面的代碼框架,從接口 [update(self, observer, object)] 上你應該知道是可以同時支持推模型和拉模型的。推模型時,observer 可以傳空,推送的信息全部通常 object 傳遞;拉模型時,observer 和 object 都傳遞數據,或只傳遞 observer,需要更具體的信息時通過 observer 引用去取數據。

    應用場景

  • 對一個對象狀態或數據的更新需要其他對象同步更新,或者一個對象的更新需要依賴另一個對象的更新;
  • 對象僅需要將自己的更新通知給其他對象而不需要知道其他對象的細節,如消息推送。
  • 學習設計模式,更應該領悟其設計思想,不應該應該局限于代碼的層面。 觀察者模式還可以用于網絡中的客戶端和服務器,比如手機中的各種 App 的消息推送,服務端是被觀察者,各個手機 App 是觀察者,一旦服務器上的數據(如 App 升級信息)有更新,就會被推送到手機客戶端。在這個應用中你會發現服務器代碼和 App 客戶端代碼其實是兩套完全不一樣的的代碼,它們是通過網絡接口進行通迅的,所以如果你只是停留在代碼層面是無法理解的!

    總結

    以上是生活随笔為你收集整理的【转】第01课:生活中的监听模式——一坑爹的热水器的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 一区二区精品在线 | 无人在线观看高清视频 | 天天干,天天干 | 国产亚洲在线观看 | 男同激情视频 | 欧美一级做性受免费大片免费 | 欧美一级二级片 | 亚洲视频1 | 日本免费在线观看视频 | 日韩毛毛片 | 亚洲国产私拍精品国模在线观看 | 免费簧片在线观看 | 一直草 | 国产一区二区三区在线视频观看 | 日本h在线观看 | 久久精品视频播放 | 一级片视频免费观看 | 好吊色一区二区三区 | 一区二区成人在线观看 | 成人毛片视频在线观看 | 香蕉视频传媒 | 亚洲香蕉 | 亚洲色图2 | 亚洲精品色| 欧美aaaaa| 精品1区2区3区 | 成人av高清在线观看 | 成人女同av免费观看 | 国产久草av| chinese麻豆gay勾外卖 | 欧美午夜精品一区二区 | 久久久久极品 | 香蕉成人在线视频 | 国产一二三在线视频 | 精品国产99一区二区乱码综合 | 亚洲久久在线 | 涩涩视屏| 深夜视频在线观看免费 | 亚洲乱视频 | 又黄又爽又色的视频 | 原创av| 搡老熟女老女人一区二区 | 每日av在线 | 波多野结衣免费看 | 精品国产丝袜一区二区三区乱码 | 黄色xxxxxx| 久久婷婷国产麻豆91 | 亚洲一区在线视频 | 四虎影院在线观看免费 | 欧美久久久久久久久久久久久久 | 黄色一级大片在线免费看国产一 | 无码精品人妻一二三区红粉影视 | 国产精品mv | 中文字幕精品无码亚 | 九草在线视频 | 男女视频网站 | 国产精品久久久久影院色老大 | 成人18视频免费69 | 色中色在线视频 | 91久久国语露脸精品国产高跟 | www视频在线观看 | 国产伊人自拍 | 4438x亚洲最大 | 国产热| 国产xxx在线观看 | 女人扒开屁股让男人桶 | 欧洲精品久久一区二区 | 韩国成人在线 | av免费网 | 亚洲一区二区在线 | 亚洲精品66 | 国产一区二区精彩视频 | 国精产品一区一区三区 | 成人羞羞国产免费动态 | 午夜影院黄色 | 欧美成人综合网站 | 91高跟黑色丝袜呻吟在线观看 | 亚洲精华液一区二区 | yy4138理论片动漫理论片 | 一区二区三区有限公司 | 日韩午夜精品视频 | 日韩一区二区三区中文字幕 | 日韩中文字幕免费视频 | 国产精品蜜臀 | 亚洲综合小说 | 九草视频在线观看 | 亚洲av无码一区二区乱子仑 | 老司机免费视频 | 最好看的电影2019中文字幕 | 7色av| 无码aⅴ精品一区二区三区 精品久久在线 | 欧洲自拍一区 | 潘金莲性xxxxhd | av黄色在线播放 | 国产精品精品视频 | 乱子伦一区二区 | 天堂av一区二区三区 | www国产精品 | 啊av在线|