博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式-行为型模式,观察者模式(13)
阅读量:7047 次
发布时间:2019-06-28

本文共 3063 字,大约阅读时间需要 10 分钟。

当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知它的依赖对象。观察者模式属于行为型模式。

有时,我们希望在一个对象的状态改变时更新另外一组对象。

 

class Publisher:    def __init__(self):        self.observers = []    def add(self, observer):        if observer not in self.observers:            self.observers.append(observer)        else:            print('Failed to add: {}'.format(observer))    def remove(self, observer):        try:            self.observers.remove(observer)        except ValueError:            print('Failed to remove: {}'.format(observer))    def notify(self):        [o.notify(self) for o in self.observers]class DefaultFormatter(Publisher):    def __init__(self, name):        Publisher.__init__(self)        self.name = name        self._data = 0    def __str__(self):        return "{}: '{}' has data = {}".format(type(self).__name__, self.name, self._data)    @property    def data(self):        return self._data    @data.setter    def data(self, new_value):        try:            self._data = int(new_value)        except ValueError as e:            print('Error: {}'.format(e))        else:            self.notify()class HexFormatter:    def notify(self, publisher):        print("{}: '{}' has now hex data = {}".format(type(self).__name__,                                                      publisher.name, hex(publisher.data)))class BinaryFormatter:    def notify(self, publisher):        print("{}: '{}' has now bin data = {}".format(type(self).__name__,                                                      publisher.name, bin(publisher.data)))def main():    df = DefaultFormatter('test1')    print(df)    print()    hf = HexFormatter()    df.add(hf)    df.data = 3    print(df)    print()    bf = BinaryFormatter()    df.add(bf)    df.data = 21    print(df)    print()    df.remove(hf)    df.data = 40    print(df)    print()    df.remove(hf)    df.add(bf)    df.data = 'hello'    print(df)    print()    df.data = 15.8    print(df)if __name__ == '__main__':    main()

 

1、发布者中有个方法添加所有观察(订阅)者对象,当发布某个东西(例子中的data变化)时,调用所有已添加的订阅者的某个方法。

 

2、这个模式也是以一个十分重要的模式,java python里面的日志管理都是使用了观察者模式。具体就是logger和handler就是发布者和订阅者的关系,当logger添加了stremhandler,那么日志就可以显示到控制台,添加了filehandler那么就可以记录到文件,添加了smtphandler就可以把日志发送到邮箱。十分的方便解耦,可以选择日志记录到某一个地方或者几个地方或者所有地方。如果日志想要记录到mongo redis什么的,只需要继承handler基类,自己实现emit方法就可以了,如果不理解这个关系,就很难自己写日志扩展,或者是只能照葫芦画瓢,不知道为什么要那么写,为什么添加了handler就可以把日志记录到相关地方。如果使用print并且实现以上这些扩展那要写很多东西,还不如使用日志。如果生产项目全部直接使用裸print,这样写代码真的是很垃圾小学生水平,因为项目跑起来后,文件引用一环套一环根本不知道哪里print的,而且print要想扩展那又是成了自己发明logging模块了。

 

3、再顺便说下logging日志使用logger.debug 和logging.debug有什么区别?我从不使用logging.debug。包括所有三方包绝对都不会直接这么去使用。logging.debug的debug是一个函数,直接这么写那么日志的命名空间是root根日志,如果想禁用这个日志,那么是removerhandler还是直接设置级别为critical来禁用日志?两种都不好,对根日志操作打击面积太大误伤率太高,万一有的地方的日志你就是想记录呢。而且logging定制性不高,你想把某个日志记录到a文件,某个日志记录到b文件,某个日志只发邮件,就必须用更小命名空间的logger了。logging.debug实际是  logging.getLogger(None).debug(),   logger.debug是logging.getLogger(‘yourname’).debug(),一般yourname可以设置成__name__方便快捷,所以可以对单独命名空间的日志进行定制handler或者移除handler或者对某类型日志设置最高级别。例如使用urllib时候,可以单独的操纵connectionpool命名空间的日志,设置显示他或者不显示他,设置他的级别为error级别完全不会影响到别的命名空间下的日志的级别设置。

 

转载地址:http://tazol.baihongyu.com/

你可能感兴趣的文章
从本人做的安卓项目浅谈蓝牙(如有缺漏错误,还请指正)
查看>>
windows10 安装 vim +spf13
查看>>
bugfree中保存用例失败
查看>>
python学习笔记4-数据类型-数字
查看>>
nagios监控check_mysql报错:libmysqlclient.so.18: cannot open shared object file
查看>>
系统架构随笔 - 设计好每一款应用
查看>>
安装mysql过程
查看>>
/etc/profile和/etc/skel
查看>>
useradd命令中的-d参数不好用
查看>>
UIScrollView、UIPageControl的练习
查看>>
使用SHA-1摘要算法和证书链签名的软件包将不再被接受
查看>>
除百度、Google外其他蜘蛛IP封锁脚本
查看>>
迅雷面试行
查看>>
戴尔EqualLogic主机软件:新意何在?为何值得我关注?
查看>>
自制应用层协议的编写
查看>>
Python - 关于Python的变量
查看>>
解决exp无法导出问题
查看>>
XML(eXtensible Markup Language)速成
查看>>
自建框架-mf
查看>>
Unix删除文件的找回方法
查看>>