在观察者设计模式中,观察者观察主体和/或观察者。观察者会收到更新通知。
我很困惑这两件事(主题和可观察的)是否基本相同?或者这两者之间有细微差别吗?
答案 0 :(得分:6)
只要一个或多个观察者必须观察一个主体,就可以使用观察者设计模式。
Observable - 定义将观察者附加到客户端和取消附加操作的接口或抽象类。在GOF书中,此类/界面称为主题。
它们基本相同。
答案 1 :(得分:2)
是的,两者都相同。
观察者可以观察到主体。 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')
答案 2 :(得分:1)
主题和观察者是两个不同的实体(对象):
但关于你的问题,
观察者观察主体或可观察的
主题的另一个名称是可观察的,因此它们是相同的
主题维护一个观察者列表,所有观察者都在主题处注册。 因此,无论何时某个事件发生在主题上,他都会通知所有观察者。
示例:
假设您有一个名为HTTPEngine的类,它处理所有与HTTP相关的内容(连接,数据撤销等)。
为了让HTTPEngine可以在不同的对象之间重用,它维护了一个说IHTTPObserver的列表。
因此,任何希望使用HTTPEngine的对象都实现接口HTTPObserver,在HTTPEngine上注册,然后收到事件通知。
例如:
class HTTPObserver
{
public:
virtual void onEvent() = 0;
}
所以,请说一个名为"客户"的课程。想要使用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();}
};
答案 3 :(得分:0)
使用一对多关系时使用观察者设计模式 并且如果更新了主对象,则更新依赖对象.Observer patter是行为设计模式的一个例子。它有三个 演员这样的主要类,依赖超类和它的子类。
请查看以下观察者设计模式的UML图。
Circle
类是主类。它有一个
特殊属性观察员,保持所有观察者的圈子。它可以附加(或根据需要重新附加)观察者。Observer
类是超类依赖项。它是一个抽象类,为Circle
类提供常用方法。AreaObserver
和PerimeterObserver
)是主要班级(Circle
)ObserverExample
来测试示例。它不是Observer设计模式的内容。 <强> 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();
}
}
}
<强> Observer.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
根据输出,似乎所有观察者在更新主类时都会更新。