Python设计模式----观察者模式

 

新知识:两个对象同等地位,并不依赖对方而且可以互相交流

class A:
    def __init__(self,B):
        self.B = B
        self.B.attach(self)

class B:
    def __init__(self):
        self.x = []
        pass

    def attach(self,A):
        self.x.append(A)
b = B()
a = A(b)

import sys
print(sys.getsizeof(b))

关键点:

任务:一个出版社对象,三个用户对象,出版社对象观察三个用户对象,向三个用户发送消息。

关系:出版社和三个用户是相互独立的关系,只是出版社和每一个用户具有交流的功能。

代码的对象结构

# coding:utf-8
from abc import abstractmethod, ABCMeta

# 主题:
class NewPublisher:
    def __init__(self):
        self.__subscribers = []
        self.__latestNews = None

    # 提供注册,就是关注每一个用户,将这个用户添加到自己的列表中。这个方法是给用户使用的
    # 用户使用其他类的成员函数。
    def attch(self, subscriber):
        self.__subscribers.append(subscriber)

    # 提供注销
    def detach(self):
        return self.__subscribers.pop()

    # 返回已经订户列表
    def subscribers(self):
        return [type(x).__name__ for x in self.__subscribers]

    # 返回注册的所有用户
    def notifySubscribers(self):
        for sub in self.__subscribers:
            sub.update()

    # 创建新消息
    def addNews(self, news):
        self.__latestNews = news

    # 返回最新消息
    def getNews(self):
        return "Got News:", self.__latestNews


# 观察者:用户
class Subscriber(metaclass=ABCMeta):
    @abstractmethod
    def update(self):
        pass


# 具体观察者:SMS用户
class SMSSubscriber:
    def __init__(self, publisher):
        self.publisher = publisher
        self.publisher.attch(self)

    def update(self):
        print(type(self).__name__, self.publisher.getNews())


# 具体观察者:邮件用户
class EmailSubscriber:
    def __init__(self, publisher):
        self.publisher = publisher
        self.publisher.attch(self)

    def update(self):
        print(type(self).__name__, self.publisher.getNews())


# 具体观察者:其他用户
class AnyOtherSubscriber:
    def __init__(self, publisher):
        self.publisher = publisher
        self.publisher.attch(self) # 将自己本身这个用户关注到这个publisher,就是添加到人家列表中

    def update(self):
        print(type(self).__name__, self.publisher.getNews())


if __name__ == "__main__":
    news_publisher = NewPublisher()
    '''
    下面这种写法很独特,注意分析啊!
    Subscribers(news_publisher) : 创建一个用户对象SMSSubscriber,将news_publisher这个对象传进去,使得SMSSubscriber这个对象成为用户对象的成员属性,
    但是现实生活中,用户对象和出版社对象并不是从属关系,谁包含谁的关系,也就是说一个对象里面有个成员变量是另一个对象,并不是从属关系,
    非要说从属关系,应该是继承吧。
    两个独立对象相互交流怎么做? 就像本代码所示这样:比如用户和出版社如何交流:应该是互相都有对方的成员变量。
    
    SMSSubscriber 类里面有 publisher 对象,很容易,但是怎样让 publisher 里面还有 SMSSubscriber 呢? self.publisher.attch(self)
    class SMSSubscriber:
    def __init__(self, publisher):
        self.publisher = publisher
        self.publisher.attch(self) # 将自己传进去
    
    # 将SMSSubscriber 自己传进去,使得SMSSubscriber在publisher里面,只不过不是self的形式而已。
    def attch(self, subscriber):
        self.__subscribers.append(subscriber)
    '''
    for Subscribers in [SMSSubscriber, EmailSubscriber, AnyOtherSubscriber]:
        Subscribers(news_publisher)   # 观察者,向主题订阅
    print("\nSubscriber: ", news_publisher.subscribers()) #打印出来新闻出版社关注的用户
    # Subscriber: ['SMSSubscriber', 'EmailSubscriber', 'AnyOtherSubscriber']

    news_publisher.addNews("Hello World!") # 增加消息
    news_publisher.notifySubscribers()     # 向每一个关注的用户发布消息
    # SMSSubscriber('Got News:', 'Hello World!')
    # EmailSubscriber('Got News:', 'Hello World!')
    # AnyOtherSubscriber('Got News:', 'Hello World!')
    # =================================================================================================
    print("\nDetached: ", type(news_publisher.detach()).__name__)  # 删除订阅者
    #Detached:  AnyOtherSubscriber
    print("\nSubscribers: ", news_publisher.subscribers())         # 查看订阅列表
    # Subscribers: ['SMSSubscriber', 'EmailSubscriber']
    # SMSSubscriber('Got News:', 'My second news')
    # EmailSubscriber('Got News:', 'My second news')
    # ================================================================================================
    news_publisher.addNews("My second news") # 增加消息
    news_publisher.notifySubscribers()       # 发布消息
    # SMSSubscriber('Got News:', 'My second news')
    # EmailSubscriber('Got News:', 'My second news')


 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值