0

I wrote a program to learn and play with the observer pattern, but I'm having trouble with the data being printed out correctly. It should print out the data input at lines 7-9 in the paste, but instead it just prints 0,0,0.

Main class

public class ObserverPattern {

    public static void main(String[] args) {
        Subject weatherData = new Subject();
        weatherData.setTemp(81);
        weatherData.setHumidity(14);
        weatherData.setWindSpeed(8);

        Observer johnsIpad = new Observer(weatherData);

        weatherData.notifyObserver();

        System.out.println(johnsIpad.toString());
    }

}

Subject Class

import java.util.ArrayList;

public class Subject {

    // fields
    ArrayList<Observer> observers;
    public double temp;
    public double humidity;
    public double windSpeed;

    // Constructor
    public Subject() {
        observers = new ArrayList<Observer>();
    }

    // Observer pattern methods
    public void register(Observer o) {
        observers.add(o);
    }

    public void unregister(Observer o) {
        observers.remove(observers.indexOf(o));
    }

    public void notifyObserver() {
        for (Observer observer : observers) {
            observer.update(temp, humidity, windSpeed);
        }
    }

    // set weather data
    public void setTemp(double temp) {
        this.temp = temp;
    }

    public void setHumidity(double humidity) {
        this.humidity = humidity;
    }

    public void setWindSpeed(double windSpeed) {
        this.windSpeed = windSpeed;
    }

}

Observer Class

public class Observer {

    double temp;
    double humidity;
    double windSpeed;

    Subject weatherData;

    Observer(Subject weatherDataSource) {
        weatherData = weatherDataSource;
    }

    public void update(double temp, double humidity, double windSpeed) {
        this.temp = temp;
        this.humidity = humidity;
        this.windSpeed = windSpeed;
    }

    public String toString() {
        return temp + "\n" + humidity + "\n" + windSpeed;
    }

}
takendarkk
  • 3,347
  • 8
  • 25
  • 37
Supetorus
  • 79
  • 2
  • 10

2 Answers2

2

You never register your observer with the subject, so notifyObserver has no observers to notify; the for loop body never executes.

Add:

weatherData.register(johnsIpad);

before you call notifyObserver(weatherData).

Andy Turner
  • 137,514
  • 11
  • 162
  • 243
  • You are correct. I added it to the constructor. As a sidenote, doing it either the way you did or in the constructor would have different consequences, in the constructor means it will automatically happen every time, which might not be desireable. However if it's not in the constructor and you don't want it every time then it would be easy to forget to register it. It probably depends on how often you want it to be registered to start with. – Supetorus Jul 11 '16 at 22:02
  • No. Don't add it to the constructor. I have commented above with several reasons why this is a bad idea. – Andy Turner Jul 11 '16 at 22:06
  • (When I say "above", I am referring to [OP's answer](http://stackoverflow.com/a/38316898/3788176)). – Andy Turner Jul 31 '16 at 08:07
0

I added this line to the constructor in the Observer class.

weatherData.register(this);

Now it works. Thanks for pointing that out to me.

Supetorus
  • 79
  • 2
  • 10
  • Note that you don't really want the `Subject` reference in the class: it creates a cyclical reference (which may affect garbage collection), and you never actually use it. It is better to minimize the responsibilities of the `Observer` class by registering the `Observer` with the `Subject` externally, not in the constructor. – Andy Turner Jul 11 '16 at 22:03
  • Additionally, this is an example of what is called *unsafe publication*: you are sharing a reference to the `Observer` before it is fully constructed. This can generally lead to rather unpredictable results, especially around thread safety. – Andy Turner Jul 11 '16 at 22:04
  • hmm, good point. I just did it that way cuz derek banas did it in the tutorial I was watching. – Supetorus Jul 11 '16 at 22:04