3

In Observer design pattern, the observer observes the subject and/or the observable. Observer gets notified by their updates.

I am confused whether those two things (subject and the observable) are essentially the same things? Or is there a subtle difference between the two?

Haris Ghauri
  • 547
  • 2
  • 7
  • 27

4 Answers4

5

The Observer Design Pattern can be used whenever a subject has to be observed by one or more observers.

Observable - interface or abstract class defining the operations for attaching and de-attaching observers to the client. In the GOF book this class/interface is known as Subject.

They are essentially same.

2

Yes, both are same.

Subject is observable by observers. Subject keeps a list of observers, so that it can notify these observers any state changes.

Check below Python code, taken from 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

a3.14_Infinity
  • 5,653
  • 7
  • 42
  • 66
1

Subject and observer are two different entities(objects):

But with regards to your question,

the observer observes the subject or the observable

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

Subject maintains a list of observers and all observers register at Subject. So, whenever some event happens at subject, he notifies all observers.

Example:

Say you have a class called HTTPEngine which handles all HTTP related stuff(connection,data retreival etc).

For HTTPEngine to be reusable across different objects, It maintains a list of say IHTTPObserver.

So, any object wishing to use HTTPEngine, implements interface HTTPObserver, registers at HTTPEngine and then gets notified for events.

ex:

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

}

so, say a class by the name "client" wants to use HTTPENgine.

class client: public HTTPObserver
{
  void onEvent(){//got the event notification}
}

Now, HTTPENgine maintains a list of observers:

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

};
basav
  • 1,475
  • 12
  • 20
  • I am more confused now because I have two different answers now :D – Haris Ghauri Oct 01 '15 at 04:58
  • @HarisGhauri, I guess what basav was trying to tell was: Subject and observers are different, but your question was regarding: Whether Subject and Observable are same or not. – a3.14_Infinity Oct 01 '15 at 05:05
0

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.

Look at following UML diagram of observer design pattern.

enter image description here

  1. The Circle class is the main class. It has a special property observers which keeps all observer of the circle. It can attach (or reattach if needed) observers.
  2. The Observer class is super class of dependencies. It is an abstract class to provide common methods for Circle class.
  3. Child observer classes (AreaObserver and PerimeterObserver) are the dependents of main class (Circle)
  4. I used ObserverExample to test the example. It is not a content of Observer design pattern.

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

According to the output it seems all observers are updated when updating the main class.

Channa Jayamuni
  • 1,876
  • 1
  • 18
  • 29