2016-07-11 2 views
0

Я написал программу, чтобы учиться и играть с шаблоном наблюдателя, но у меня возникают проблемы с правильно напечатанными данными. Он должен распечатать ввод данных в строках 7-9 в пасте, но вместо этого он просто печатает 0,0,0.Почему данные не принимаются правильно?

Основной класс

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

} 

Тема Класс

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 Класс

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

} 

ответ

2

Вы никогда не зарегистрировать наблюдателя с объектом, так notifyObserver не имеет своих наблюдателей для уведомления; тело цикла цикла никогда не выполняется.

Добавить:

weatherData.register(johnsIpad); 

перед вызовом notifyObserver(weatherData).

+0

Вы правы. Я добавил его в конструктор. В качестве побочного элемента, делая это либо так, как вы, или в конструкторе, имели бы другие последствия, в конструкторе означает, что он будет автоматически выполняться каждый раз, что может быть нежелательным. Однако, если это не в конструкторе, и вы не хотите его каждый раз, тогда было бы легко забыть его зарегистрировать. Вероятно, это зависит от того, как часто вы хотите, чтобы он был зарегистрирован для начала. – Supetorus

+0

Нет. Не добавляйте его в конструктор. Я прокомментировал выше несколько причин, почему это плохая идея. –

+0

(Когда я говорю «выше», я имею в виду [ответ OP] (http://stackoverflow.com/a/38316898/3788176)). –

0

Я добавил эту строку к конструктору класса Observer.

weatherData.register(this); 

Теперь это работает. Спасибо, что указали на это.

+0

Обратите внимание, что вам действительно не нужна ссылка «Subject» в классе: она создает циклическую ссылку (которая может повлиять на сбор мусора), и вы никогда ее не используете. Лучше свести к минимуму обязанности класса «Наблюдатель», зарегистрировав «Наблюдатель» с «Субъектом» внешне, а не в конструкторе. –

+0

Кроме того, это пример того, что называется * небезопасной публикацией *: вы используете ссылку на «Наблюдатель» до того, как она будет полностью построена. Это может привести к довольно непредсказуемым результатам, особенно в отношении безопасности потоков. –

+0

hmm, хороший пункт. Я просто сделал это так, потому что cuz derek banas сделал это в учебнике, которое я наблюдал. – Supetorus