新知识:两个对象同等地位,并不依赖对方而且可以互相交流
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')