在观察者设计模式中,Subject和Observable是一样的东西吗?

在观察者设计模式中,Subject和Observable是一样的东西吗?

问题描述:

在观察者设计模式中,观察者观察主体或观察者。它会通过更新得到通知。我很困惑这两件事是否是一回事?或者两者之间存在细微差别?在观察者设计模式中,Subject和Observable是一样的东西吗?

的观测器的设计模式采取可用于每当受试者必须通过一个或多个观察者来观察。

Observable - 定义了将观察者附加到客户端和从客户端上去除操作的接口或抽象类。在GOF书中,这个类/接口被称为主题

它们本质上是相同的。

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

但是至于你的问题,

观察者所观察对象或受可观察

的另一个名字是可观察到,所以它们是相同的

对象维护观察者列表和所有观察者注册在 学科。 因此,每当某个事件发生在主题上时,他都会通知所有观察者。

例子:

假设你有一个叫HTTPEngine类处理所有HTTP相关的东西(连接,数据retreival等)。

对于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();} 

}; 
+0

我现在更困惑了,因为我现在有两个不同的答案:D –

+0

@HarisGhauri,我猜想basav试图告诉的是:主体和观察者不同,但您的问题是关于:Subject和Observable是否相同或不。 –

是的,都是一样的。

对象可以被观察者观察到。 主体保留观察者列表,以便它可以通知这些观察者任何状态改变。

检查下面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') 

enter image description here

观察者设计模式是使用一对多的关系 何时以及是否更新了主object.Observer 图案是用于行为设计patters一个例子来更新依赖对象使用。它有三个 演员这样的主要类,从属超类和它的子类。

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

enter image description here

  1. Circle类是主类。它有一个保留所有观察者的特殊属性观察者。它可以附加(或重新附加,如果需要的话)观察者。
  2. Observer类是超类依赖关系。为类Circle提供常用方法是一个抽象类。
  3. 儿童观察者类(AreaObserverPerimeterObserver)是
  4. 我用ObserverExample测试示例主类(Circle)的家属。它不是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); 
    } 
} 

OUTPUT:

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 

根据似乎所有的观察者更新更新,当输出迈n级。