1

I'm now learning about the Listener or Observer-Observable design patter, i tried to implement my own class using the supplied Java library Observer interface and Observable class.

My Observable subject is an empty class that extends Observable.

Here are my two Observer classes:

public class CatObserver implements Observer { private String status = "Sleeping..."; @Override public void update(Observable o, Object arg) { System.out.println("Updated!"); this.status = "Awake!"; } public void getStatus(){ System.out.println(status); } } public class DogObserver implements Observer { private String status = "Sleeping..."; @Override public void update(Observable o, Object arg) { this.status = "Awake!"; } public void getStatus(){ System.out.println(status); } } 

Here is my main program:

public class Listener { public static void main(String[] args) { AnimalSubject subject = new AnimalSubject(); CatObserver mitsy = new CatObserver(); DogObserver ozil = new DogObserver(); mitsy.getStatus(); ozil.getStatus(); subject.addObserver(mitsy); subject.addObserver(ozil); synchronized (subject){ subject.notifyAll(); } mitsy.getStatus(); ozil.getStatus(); } 

My output is 4 lines of "Sleeping...", when it should be 2 lines of "Sleeping..." and 2 lines of "Awake!".

When debugging it won't even go into the update() functions.

What am I doing wrong here?

0

1 Answer 1

1

Your code is only half done as you're not using the Observable class anywhere that we can see. The Observer/Observable interface/class pair don't work with Object's notifyAll(). Instead you must create a class that extends the Observable abstract class and then call the Observable's proper notify method, notifyObservers(...), when appropriate.

Edit: I now see that you are using Observable but you don't show the code, but rather state that it's empty. Show your code, and make it "non-empty" where in fact you call the method above when its state changes.

Something like...

import java.util.*; public class Listener { public static void main(String[] args) { AnimalSubject subject = new AnimalSubject("My Dog"); DogObserver ozil = new DogObserver(); ozil.getStatus(); subject.addObserver(ozil); subject.setStatus(Status.AWAKE); subject.setStatus(Status.EATING); ozil.getStatus(); } } class DogObserver implements Observer { private Status status = Status.ASLEEP; @Override public void update(Observable o, Object arg) { status = ((StatusEvent) arg).getNewValue(); getStatus(); } public void getStatus() { System.out.println("Status: " + status); } } class AnimalSubject extends Observable { private String name; private Status status = Status.ASLEEP; public AnimalSubject(String name) { this.name = name; } public void setStatus(Status status) { Status oldValue = this.status; Status newValue = status; if (oldValue.equals(newValue)) { return; } this.status = status; StatusEvent event = new StatusEvent(this, oldValue, newValue); setChanged(); notifyObservers(event); } public Status getStatus() { return status; } public String getName() { return name; } } enum Status { ASLEEP, AWAKE, EATING } class StatusEvent { private Object source; private Status oldValue; private Status newValue; public StatusEvent(Object source, Status oldValue, Status newValue) { this.source = source; this.oldValue = oldValue; this.newValue = newValue; } public Object getSource() { return source; } public Status getOldValue() { return oldValue; } public Status getNewValue() { return newValue; } } 
Sign up to request clarification or add additional context in comments.

2 Comments

I created an empty class (AnimalSubject) which only extends the Observable class, i thought that's all i need in order to have an Observable class..
@argamanza: no, it can't be empty. It has to notify its internal list of observers when its state changes. And get rid of that notifyAll() business as that is not doing what you think it's doing and regardless, even if it were, it's in the wrong place. All notification calls should be from within the Observable. Again your code is half done.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.