《人人都懂设计模式》-监听模式

最近在撸这本书,

作个记录。

from abc import ABCMeta, abstractmethod
# 引入ABCMeta和abstractmethod来定义抽象类和抽象方法
import time

"""

# version 1.0
class WaterHeater:
    # 热水器, 战胜寒冬的有利武器

    def __init__(self):
        self.__observers = []
        self.__temperature = 25

    def get_temperature(self):
        return self.__temperature

    def set_temperature(self, temperature):
        self.__temperature = temperature
        print("当前温度是:" + str(self.__temperature) + " C")
        self.notifies()

    def notifies(self):
        for o in self.__observers:
            o.update(self)

    def add_observer(self, observer):
        self.__observers.append(observer)

class Observer(metaclass=ABCMeta):
    # 洗澡模式和饮用模式的父类

    @abstractmethod
    def update(self, water_heater):
        pass

class WashingMode(Observer):
    # 该模式用于洗澡

    def update(self, water_heater):
        if 50 <= water_heater.get_temperature() < 70:
            print("水已烧好,温度正好,可以来洗澡了。")

class DrinkingMod(Observer):
    # 该模式用于饮用
    def update(self, water_heater):
        if water_heater.get_temperature() >= 100:
            print("水已烧开,可以来饮用了。")
"""

# version 2.0
class Observable:
    # 被观察者的基类

    def __init__(self):
        self.__observers = []

    def add_observer(self, observer):
        self.__observers.append(observer)

    def remove_observer(self, observer):
        self.__observers.remove(observer)

    def notify_observers(self, observer=0):
        for o in self.__observers:
            o.update(self, observer)

class WaterHeater(Observable):
    # 热水器, 战胜寒冬的有利武器

    def __init__(self):
        super().__init__()
        self.__temperature = 25

    def get_temperature(self):
        return self.__temperature

    def set_temperature(self, temperature):
        self.__temperature = temperature
        print("当前温度是:" + str(self.__temperature) + " C")
        self.notify_observers()

class Observer(metaclass=ABCMeta):
    # 观察者的基类

    @abstractmethod
    def update(self, observable, observer):
        pass

class WashingMode(Observer):
    # 该模式用于洗澡

    def update(self, observable, observer):
        if isinstance(observable, WaterHeater) and 50 <= observable.get_temperature() < 70:
            print("水已烧好,温度正好,可以来洗澡了。")

class DrinkingMod(Observer):
    # 该模式用于饮用
    def update(self, observable, observer):
        if isinstance(observable, WaterHeater) and observable.get_temperature() >= 100:
            print("水已烧开,可以来饮用了。")

def test_water_heater():
    heater = WaterHeater()
    washing_observer = WashingMode()
    drinking_observer = DrinkingMod()
    heater.add_observer(washing_observer)
    heater.add_observer(drinking_observer)
    heater.set_temperature(20)
    heater.set_temperature(40)
    heater.set_temperature(60)
    heater.set_temperature(80)
    heater.set_temperature(100)

test_water_heater()

# 实践应用:登陆异常的检测与提醒
class Account(Observable):

    def __init__(self):
        super().__init__()
        self.__latest_ip = {}
        self.__latest_region = {}

    def __get_region(self, ip):
        ip_regions = {
            ‘101.47.18.9‘: ‘浙江省杭州市‘,
            ‘67.218.147.69‘: ‘美国洛彬矶‘
        }
        region = ip_regions.get(ip)
        return ‘‘ if region is None else region

    def __is_long_distance(self, name, region):
        latest_region = self.__latest_region.get(name)
        return latest_region is not None and latest_region != region

    def login(self, name, ip, login_time):
        region = self.__get_region(ip)
        if self.__is_long_distance(name, region):
            self.notify_observers({‘name‘: name, ‘ip‘: ip, ‘region‘: region, ‘time‘: login_time})
        self.__latest_region[name] = region
        self.__latest_ip[name] = ip

class SmsSender(Observer):
    def update(self, observable, observer):
        print("[短信发送] {} 您好,检测到您的帐户可能登陆异常,最近一次登陆信息:\n 登陆地区:{} 登陆ip: {} 登陆时间:{}"
              .format(observer["name"], observer["region"], observer["ip"], observer["time"]))

class MailSender(Observer):
    def update(self, observable, observer):
        print("[邮件发送] {} 您好,检测到您的帐户可能登陆异常,最近一次登陆信息:\n 登陆地区:{} 登陆ip: {} 登陆时间:{}"
              .format(observer["name"], observer["region"], observer["ip"], observer["time"]))

def test_login():
    account = Account()
    account.add_observer(SmsSender())
    account.add_observer(MailSender())
    account.login("Tony", ‘101.47.18.9‘, time.time())
    account.login("Tony", ‘67.218.147.69‘, time.time())
    account.login("Tony", ‘101.47.18.9‘, time.time())

test_login()
C:\Python36\python.exe C:/Users/Sahara/PycharmProjects/test/python_search.py
当前温度是:20 C
当前温度是:40 C
当前温度是:60 C
水已烧好,温度正好,可以来洗澡了。
当前温度是:80 C
当前温度是:100 C
水已烧开,可以来饮用了。
[短信发送] Tony 您好,检测到您的帐户可能登陆异常,最近一次登陆信息:
 登陆地区:美国洛彬矶 登陆ip: 67.218.147.69 登陆时间:1565402412.372697
[邮件发送] Tony 您好,检测到您的帐户可能登陆异常,最近一次登陆信息:
 登陆地区:美国洛彬矶 登陆ip: 67.218.147.69 登陆时间:1565402412.372697
[短信发送] Tony 您好,检测到您的帐户可能登陆异常,最近一次登陆信息:
 登陆地区:浙江省杭州市 登陆ip: 101.47.18.9 登陆时间:1565402412.372697
[邮件发送] Tony 您好,检测到您的帐户可能登陆异常,最近一次登陆信息:
 登陆地区:浙江省杭州市 登陆ip: 101.47.18.9 登陆时间:1565402412.372697

Process finished with exit code 0

原文地址:https://www.cnblogs.com/aguncn/p/11330652.html

时间: 2024-10-08 14:55:51

《人人都懂设计模式》-监听模式的相关文章

&lt;人人都懂设计模式&gt;-单例模式

这个模式,我还是了解的. 书上用了三种不同的方法. class Singleton1: # 单例实现方式1 __instance = None __is_first_init = False def __new__(cls, name): if not cls.__instance: Singleton1.__instance = super().__new__(cls) return cls.__instance def __init__(self, name): if not self.__

设计模式之监听模式(观察者模式与监听模式区别)

一,类的四大基本关系:  a.关联关系:如A类调用B类. b.继承关系:如A类是B类的父类. c.聚合关系:如装橘子的箱子,箱子是否存在与里面装没装橘子没有任何关系,也就是说橘子不会影响箱子的存在. d.组合关系:如一个小组,小组是否存在与小组中是否有组员是息息相关的,如果没有组员,小组就不存在了. 监听器模式:事件源经过事件的封装传给监听器,当事件源触发事件后,监听器接收到事件对象可以回调事件的方法 观察者模式:观察者(Observer)相当于事件监听者,被观察者(Observable)相当于

Kali2.0在使用aircrack-ng破解无线密码时网卡监听模式问题

在使用Kali2.0 aircrack-ng破解需先密码时执行以下命令后会发现无法启用网卡的监听模式airmon-ng start wlan0执行以下命令后报错airodump-ng mon0 出现以上问题原因是因为系统本身问题,网卡并未进入监听模式 解决办法: ifconfig wlan0 down iwconfig wlan0 monitor ifconfig wlan0 up 再次执行 airmon-ng start wlan0 airodump-ng mon0 网卡进入监听模式

密歇根大学 - 人人都懂的编程课(Python)

人人都懂的编程课(Python) Week03 Exercise Rewrite your pay program using try and except so that your program handles non-numeric input gracefully. Enter Hours: 20 Enter Rate: nine Error, please enter numeric input

Aircrack-ng设置监听模式异常

Aircrack-ng设置监听模式异常 aircrack-ng 在某些情况下,用户使用Aircrack-ng工具集中的airmon-ng命令,将无线网卡设置为监听模式时,会出现异常.如SIOCSIFFLA65:Name not unique on network等.此时,用户可以尝试使用iwconfig来设置.具体设置方法如下所示: (1)关闭无线网卡.执行如下命令: ifconfig wlan0 down (2)设置监听模式.执行命令如下所示: iwconfig wlan0 mode moni

观察者模式和事件监听模式的区别

事件监听模式更像是观察者模式的进阶. 观察者模式中,'主题'会在特定逻辑下通知所有'观察者'.如果这个通知不包含任何信息,那么这种实现就是通常的观察者模式. 如果'主题'通知'观察者'的过程带有一些<其他信息>.那么'主题'本身已经上升成为了'事件源',而通知中带有的<其他信息>经过封装就成为了事件. 事件监听模式的优势:在很多应用场景中,通知中附带的<其他信息>是必不可少的,事件Event则对这些<信息>进行了封装,使它本身拥有了多态的特性.每个事件对象就

RabbitMQ confirm的确认监听模式

添加确认监听需要开启确认监听模式 实现 addConfirmListener方法confirm模式最大的好处在于他是异步的,一旦发布一条消息,生产者应用程序就可以在等信道返回确认的同时继续发送下一条消息,当消息最终得到确认之后,生产者应用便可以通过回调方法来处理该确认消息,如果RabbitMQ因为自身内部错误导致消息丢失,就会发送一条nack消息,生产者应用程序同样可以在回调方法中处理该nack消息: 消费者: package com.flying.rabbitmq.api.confirm; i

从程序员到项目经理(4):程序员加油站 -- 不是人人都懂的学习要点

学习是一种基础性的能力.然而,“吾生也有涯,而知也无涯.”,如果学习不注意方法,则会“以有涯随无涯,殆矣”. 一.学习也是一种能力 看到这个标题,有人会说:“学习,谁不会?”的确,学习就像吃饭睡觉一样,是人的一种本能,人人都有学习的能力.我们在刚出生的时候,什么也不知道,是一张真正的白纸,我们靠学习的本能,学会了走路.说话.穿衣服…后来,我们上学了,老师把书本上的知识一点一点灌输到我们的脑子里,我们掌握的知识越来越多,与此同时,我们学习能力却好像越来越差了,习惯了被别人喂饱,似乎忘记了怎么来喂自

从程序员到项目经理之程序员加油站 -- 不是人人都懂的学习要点(转发)

学习是一种基础性的能力.然而,“吾生也有涯,而知也无涯.”,如果学习不注意方法,则会“以有涯随无涯,殆矣”. 一.学习也是一种能力 看到这个标题,有人会说:“学习,谁不会?”的确,学习就像吃饭睡觉一样,是人的一种本能,人人都有学习的能力.我们在刚出生的时候,什么也不知道,是一张真正的白纸,我们靠学习的本能,学会了走路.说话.穿衣服…后来,我们上学了,老师把书本上的知识一点一点灌输到我们的脑子里,我们掌握的知识越来越多,与此同时,我们学习能力却好像越来越差了,习惯了被别人喂饱,似乎忘记了怎么来喂自