2016-07-11 17 views
0

Ich schrieb ein Programm, um mit dem Beobachtermuster zu lernen und zu spielen, aber ich habe Probleme damit, die Daten korrekt auszudrucken. Es sollte die Dateneingabe in den Zeilen 7-9 in der Paste ausdrucken, aber es druckt nur 0,0,0.Warum werden die richtigen Daten nicht empfangen?

Hauptklasse

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

} 

Gegenstand Klasse

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 Klasse

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

} 

Antwort

2

Sie nie Ihre Beobachter mit dem Thema registrieren, so hat notifyObserver keine Beobachter zu unterrichten; Der for-Schleifenkörper wird nie ausgeführt.

Anzahl:

weatherData.register(johnsIpad); 

bevor Sie notifyObserver(weatherData) nennen.

+0

Sie haben Recht. Ich habe es dem Konstruktor hinzugefügt. Als Nebenbemerkung, wenn Sie es entweder so machen, wie Sie es getan haben oder im Konstruktor, hätte das unterschiedliche Konsequenzen. Im Konstruktor bedeutet dies, dass es jedes Mal automatisch passiert, was nicht wünschenswert ist. Wenn es jedoch nicht im Konstruktor ist und Sie es nicht jedes Mal wollen, dann wäre es leicht zu vergessen, es zu registrieren. Es hängt wahrscheinlich davon ab, wie oft Sie es am Anfang registrieren möchten. – Supetorus

+0

Nein. Fügen Sie sie dem Konstruktor nicht hinzu. Ich habe oben mit mehreren Gründen gesagt, warum das eine schlechte Idee ist. –

+0

(Wenn ich "oben" sage, beziehe ich mich auf [OPs Antwort] (http://stackoverflow.com/a/38316898/3788176)). –

0

Ich habe diese Zeile zum Konstruktor in der Observer-Klasse hinzugefügt.

weatherData.register(this); 

Jetzt funktioniert es. Danke, dass du mir das gezeigt hast.

+0

Beachten Sie, dass Sie die Subject-Referenz in der Klasse nicht wirklich möchten: Sie erstellt eine zyklische Referenz (die sich auf die Garbage Collection auswirken kann) und Sie verwenden sie nie. Es ist besser, die Verantwortlichkeiten der Klasse "Beobachter" zu minimieren, indem der Beobachter mit dem Subjekt extern und nicht im Konstruktor registriert wird. –

+0

Außerdem ist dies ein Beispiel für die sogenannte * unsichere Veröffentlichung *: Sie teilen einen Verweis auf den 'Observer', bevor er vollständig erstellt wurde. Dies kann im Allgemeinen zu ziemlich unvorhersehbaren Ergebnissen führen, insbesondere im Hinblick auf die Fadensicherheit. –

+0

hmm, guter Punkt. Ich habe es einfach so gemacht, Cuz Derek Banas hat es in dem Tutorial getan, das ich mir angesehen habe. – Supetorus