在观察者设计模式中,观察者观察主题和/或可观察对象。观察者收到他们的更新通知。
我很困惑这两个东西(主题和可观察的)是否本质上是相同的东西?还是两者之间有细微的差别?
在观察者设计模式中,观察者观察主题和/或可观察对象。观察者收到他们的更新通知。
我很困惑这两个东西(主题和可观察的)是否本质上是相同的东西?还是两者之间有细微的差别?
只要一个或多个观察者必须观察一个主题,就可以使用观察者设计模式。
Observable - 定义将观察者附加和解除附加到客户端的操作的接口或抽象类。在 GOF 书中,这个类/接口被称为Subject。
它们本质上是相同的。
是的,两者都是一样的。
观察者可以观察到对象。Subject 保存了一个观察者列表,以便它可以通知这些观察者任何状态变化。
检查下面的 Python 代码,取自Wikipedia
class Observable:
def __init__(self):
self.__observers = []
def register_observer(self, observer):
self.__observers.append(observer)
def notify_observers(self, *args, **kwargs):
for observer in self.__observers:
observer.notify(self, *args, **kwargs)
class Observer:
def __init__(self, observable):
observable.register_observer(self)
def notify(self, observable, *args, **kwargs):
print('Got', args, kwargs, 'From', observable)
subject = Observable()
observer = Observer(subject)
subject.notify_observers('test')
主体和观察者是两个不同的实体(对象):
但是关于你的问题,
观察者观察主体或可观察物
可以观察到主题的另一个名称,因此它们是相同的
Subject 维护着一个观察者列表,所有观察者都在 Subject 上注册。因此,每当主题发生某些事件时,他都会通知所有观察者。
例子:
假设您有一个名为 HTTPEngine 的类,它处理所有与 HTTP 相关的内容(连接、数据检索等)。
为了使 HTTPEngine 可以跨不同对象重用,它维护了一个说 IHTTPObserver 的列表。
因此,任何希望使用 HTTPEngine 的对象,实现接口 HTTPObserver,在 HTTPEngine 注册,然后收到事件通知。
前任:
class HTTPObserver
{
public:
virtual void onEvent() = 0;
}
因此,假设一个名为“client”的类想要使用 HTTPENgine。
class client: public HTTPObserver
{
void onEvent(){//got the event notification}
}
现在,HTTPENgine 维护了一个观察者列表:
class HTTPEngine
{
private:
vector<IHTTPObserver*> clients;
public:
void register(IHTTPObserver* client){clients.push_back(client);}
void notifyclients(){
for(it=vector.begin();it!=Vector.end();it++)
(*it)->notifyEvent();}
};
当使用一对多关系时使用观察者设计模式,如果更新主对象,则更新依赖对象。观察者模式是行为设计模式的一个示例。它具有三个参与者,例如主类、依赖超类和子类。
查看以下观察者设计模式的 UML 图。
Circle
类是主类。它有一个特殊的属性observers,可以让所有的观察者保持在圈子里。它可以附加(或在需要时重新附加)观察者。Observer
是依赖的超类。它是一个抽象类,为类提供通用方法Circle
。AreaObserver
和PerimeterObserver
) 是主类 ( Circle
)的依赖项ObserverExample
测试过这个例子。它不是观察者设计模式的内容。Circle.java
public class Circle {
private List<Observer> observers;
private double radius;
public Circle() {
observers = new ArrayList<>();
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
notifyObservers();
}
/**
* attach an observer to the circle
*/
public void attach(Observer observer) {
observers.add(observer);
}
/**
* notify all observers on update
*/
public void notifyObservers() {
for (Observer observer : observers) {
observer.update();
}
}
}
观察者.java
public abstract class Observer {
protected Circle circle;
public Observer(Circle circle) {
this.circle = circle;
}
public abstract void update();
}
AreaObserver.java
public class AreaObserver extends Observer {
public AreaObserver(Circle circle) {
super(circle);
}
@Override
public void update() {
System.out.printf("New area is: %f\n", Math.PI * circle.getRadius() * circle.getRadius());
}
}
PerimeterObserver.java
public class PerimeterObserver extends Observer {
public PerimeterObserver(Circle circle) {
super(circle);
}
@Override
public void update() {
System.out.printf("New Perimeter is: %f\n", 2 * Math.PI * circle.getRadius());
}
}
ObserverExample.java
public class ObserverExample {
public static void main(String[] args) {
Circle circle = new Circle();
PerimeterObserver perimeterObserver = new PerimeterObserver(circle);
circle.attach(perimeterObserver);
AreaObserver areaObserver = new AreaObserver(circle);
circle.attach(areaObserver);
System.out.println("Set radius: 7.0");
System.out.println("---------------");
circle.setRadius(7.0);
System.out.println();
System.out.println("Set radius: 5.0");
System.out.println("---------------");
circle.setRadius(5.0);
}
}
输出:
Set radius: 7.0
---------------
New Perimeter is: 43.982297
New area is: 153.938040
Set radius: 5.0
---------------
New Perimeter is: 31.415927
New area is: 78.539816
根据输出,更新主类时似乎所有观察者都更新了。