zoukankan      html  css  js  c++  java
  • 设计模式-行为型模式,观察者模式(13)

    当对象间存在一对多关系时,则使用观察者模式(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级别完全不会影响到别的命名空间下的日志的级别设置。

  • 相关阅读:
    HDU 4278 Faulty Odometer 8进制转10进制
    hdu 4740 The Donkey of Gui Zhou bfs
    hdu 4739 Zhuge Liang's Mines 随机化
    hdu 4738 Caocao's Bridges tarjan
    Codeforces Gym 100187M M. Heaviside Function two pointer
    codeforces Gym 100187L L. Ministry of Truth 水题
    Codeforces Gym 100187K K. Perpetuum Mobile 构造
    codeforces Gym 100187J J. Deck Shuffling dfs
    codeforces Gym 100187H H. Mysterious Photos 水题
    windows服务名称不是单个单词的如何启动?
  • 原文地址:https://www.cnblogs.com/ydf0509/p/8526100.html
Copyright © 2011-2022 走看看