在观察者设计模式中,Subject 和 Observable 是一回事吗?

In Observer Design pattern, are Subject and Observable the same thing?

在Observer设计模式中,观察者观察subject and/or the observable。观察者会收到更新通知。

我很困惑这两个东西(主体和可观察对象)是否本质上是同一件事?或者两者之间有细微的差别?

主体和观察者是两个不同的实体(客体):

但是关于你的问题,

the observer observes the subject or the observable

another name for subject would be observable, so they are same

Subject 维护一个观察者列表,所有观察者都在 Subject 注册。 因此,每当主题发生某些事件时,他都会通知所有观察者。

Example:

假设您有一个名为 HTTPEngine 的 class,它处理所有与 HTTP 相关的内容(连接、数据检索等)。

为了使 HTTPEngine 可以跨不同的对象重用,它维护了一个列表,比如 IHTTPObserver。

因此,任何希望使用 HTTPEngine 的对象都实现接口 HTTPObserver,在 HTTPEngine 上注册,然后收到事件通知。

例如:

class HTTPObserver
{
 public:
 virtual void onEvent() = 0;

}

所以,说一个叫 "client" 的 class 想使用 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();}

};

是的,两者是一样的。

对象可以被观察者观察到。 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')

只要一个对象必须由一个或多个观察者观察,就可以使用观察者设计模式。

Observable - 接口或抽象 class 定义将观察者附加和取消附加到客户端的操作。在 GOF 书中,这个 class/interface 被称为 Subject.

本质上是一样的

Observer design pattern is used when using an one-to-many relationship and to update dependent objects if updated the main object.Observer patter is an example for behavioral design patters. It has three actors such main class, dependent super class and it's child classes.

看下面的观察者设计模式UML图

  1. Circle class 是主要的class。它有一个 特殊的 属性 观察者,让所有观察者都在圈子里。它可以附加(或在需要时重新附加)观察者。
  2. Observer class 是超 class 的依赖。 class 为Circle class.
  3. 提供通用方法的抽象class
  4. 儿童观察员 classes(AreaObserverPerimeterObserver)是主要 class(Circle
  5. 的家属
  6. 我用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();
        }
    }
}

Observer.java

public abstract class Observer {

    protected Circle circle;

    public Observer(Circle circle) {
        this.circle = circle;
    }

    public abstract void update();
}

面积Observer.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());
    }
}

周长Observer.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

根据输出,似乎所有观察者都在更新主 class 时更新。