这章可以讨论行为型设计模式:观察者设计模式
创建型模式的工作原理是基于对象的创建机制的。由于这些模式隔离了对象的创建细节,所以使得代码能够与要创建的对象的类型相互独立。结构型模式用于设计对象和类的结构,从而使它可以相互协作以获得更大的结构。它们重点关注的是简化结构以及识别类和对象之间的关系
结构型模式用于设计对象和类的结构,从而使它们可以相互协作以获得更大的结构。重点在于简化结构以及识别类和对象之间的关系
行为型模式重点关注的是对象的责任。它们用来处理对象之间的交互,以实现更大的功能。行为型模式:对象之间应该能够彼此交互,同时还应该是松散耦合的
在观察者设计模式中,对象(主题)维护了一个依赖(观察者)列表,以便主题可以使用观察者定义的任何方法通知所有观察者它所发生的变化
观察者模式的主要目标:
观察者模式的应用场景:
Python3.x实现简单的观察者模式
class Subject:
def __init__(self):
self.__observers = []
def register(self, observer):
self.__observers.append(observer)
def notifyAll(self, *args, **kwargs):
for observer in self.__observers:
observer.notify(self, *args, **kwargs)
class Observer1:
def __init__(self, subject):
subject.register(self)
def notify(self, subject, *args):
print(type(self).__name__, ":: Got", args, "From", subject)
class Observer2:
def __init__(self, subject):
subject.register(self)
def notify(self, subject, *args):
print(type(self).__name__, ":: Got", args, "From", subject)
subject = Subject()
observer1 = Observer1(subject)
observer2 = Observer2(subject)
subject.notifyAll("notification")
运行结果:
Observer1 :: Got (‘notification’,) From <main.Subject object at 0x7f9f99fc6518>
Observer2 :: Got (‘notification’,) From <main.Subject object at 0x7f9f99fc6518>
主题:类Subject 需要了解Observer。Subject类具有许多方法,诸如 register()和 deregister()等,Observer可以通过这些方法注册到 Subject类中。因此,一个 Subject可以处理多个 Observer
观察者:它为关注主题的对象定义了一个接口。它定义了 Observer需要实现的各个方法,以便在主题发生变化时能够获得相应的通知
具体观察者(ConcreteObserver):它用来保存应该与 Subject的状态保持一致的状态。它实现了 Observer接口以保持其状态与主题中的变化相一致
我们以新闻机构为例展示观察者模式的现实世界场景
# 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)
def update(self):
print(type(self).__name__, self.publisher.getNews())
if __name__ == "__main__":
news_publisher = NewPublisher()
for Subscribers in [SMSSubscriber, EmailSubscriber, AnyOtherSubscriber]:
Subscribers(news_publisher) # 观察者,向主题订阅
print("\nSubscriber: ", news_publisher.subscribers())
news_publisher.addNews("Hello World!") # 增加消息
news_publisher.notifySubscribers() # 发布消息
print("\nDetached: ", type(news_publisher.detach()).__name__) # 删除订阅者
print("\nSubscribers: ", news_publisher.subscribers()) # 查看订阅列表
news_publisher.addNews("My second news") # 增加消息
news_publisher.notifySubscribers() # 发布消息
运行结果:
Subscriber: [‘SMSSubscriber’, ‘EmailSubscriber’, ‘AnyOtherSubscriber’]
SMSSubscriber (‘Got News:’, ‘Hello World!’)
EmailSubscriber (‘Got News:’, ‘Hello World!’)
AnyOtherSubscriber (‘Got News:’, ‘Hello World!’)
Detached: AnyOtherSubscriber
Subscribers: [‘SMSSubscriber’, ‘EmailSubscriber’]
SMSSubscriber (‘Got News:’, ‘My second news’)
EmailSubscriber (‘Got News:’, ‘My second news’)
松耦合是软件开发应该采用的重要设计原理之一
可能存在多个主题和观察者吗?
当一个软件应用程序建立多个主题和观察者时,是可能的。但是想要正常工作的话,需要通知观察者哪些主题发生了变化以及各个主题中发生了哪些变化
谁负责触发更新?
观察者模式可以在推模型和拉模型中工作。通常发生更新时,主题会触发更新方法,但有时可以根据应用程序需要,观察者也是可以触发通知。然而,需要注意是频率不应该太高,否则则可能导致性能下降,特别是当主题的更新不太频繁时
主题或观察者可以在任何其他用例中访问吗?
是的,这就是松散耦合的力量在观察者模式中的强大体现。主题和观察者是可以独立使用的