1

I am implementing the Observer / Observable pattern using Java. However, I am encountering a problem in the Observer portion of my code.

Observable

public class Model extends Observable {

   public void notify() {
       this.setChanged();
       this.notifyObservers(new ArrayList<A>());
       this.notifyObservers(new ArrayList<B>());
   }
}

Observer

public class View implements Observer {

    @Override
    public void update(Observable observable, Object object) {
        // TODO: If object is ArrayList<A>?
        System.out.println("A");
        // TODO: If object is ArrayList<B>?
        System.out.println("B");
    }
}

How would I fill in the TODO comments to check for the generic on the ArrayList? Is this even possible? (I would prefer to do it without implementing more classes, if possible.)

sdasdadas
  • 23,917
  • 20
  • 63
  • 148
  • 2
    not sure this is possible because of erasure. You cannot tell the type during run time. See this on erasure http://docs.oracle.com/javase/tutorial/java/generics/erasure.html – RNJ Aug 24 '12 at 16:33

2 Answers2

2

You could use instanceof to see what type is your object but you are misusing the pattern.
The idea is that the Observable has a well defined interface and all the Observer needs to know is to use the API to pass the notification.
Logic to know what exactly is the Observable should not be mixed in the code.
From your question sounds to me you have 2 Observable and they should keep their own listeners interested specifically in them for notification. Not one combined

Cratylus
  • 52,998
  • 69
  • 209
  • 339
  • can you use instanceof? I dont think you can The array lists are typed and this information is lost. (I agree though on the misuse of the pattern) – RNJ Aug 24 '12 at 16:34
  • 1
    Why does Java allow the passing of an Object to the observers? What should I pass (if anything) in the object field? – sdasdadas Aug 24 '12 at 16:35
  • @user846476:You are right. You can only see if `instanceof List`.He could check the elements if are `instanceof A` but even if he could he is missing the pattern – Cratylus Aug 24 '12 at 16:36
  • 2
    @sdasdadas:You can pass in a custom `Object` that your listeners knows how to cast back.Essentially is the notification object (has information related to the reason of the notification) – Cratylus Aug 24 '12 at 16:41
2

An Observable should send one and only one type of data.

public class ModelA extends Observable {

   public void notify() {
       this.setChanged();
       this.notifyObservers(new ArrayList<A>());
   }
}

public class ModelB extends Observable {

   public void notify() {
       this.setChanged();
       this.notifyObservers(new ArrayList<B>());
   }
}

Your other alternative is to put ArrayList<A> and ArrayList<B> into a class. You can notify your observers with that class.

Gilbert Le Blanc
  • 50,182
  • 6
  • 67
  • 111
  • Thank you - I'll break my model up into better sub-divisions. A side question: is it better to pass a controller as the object? – sdasdadas Aug 24 '12 at 16:41
  • @sdasdadas: It depends on what you need. I've been using the Listener model from Swing when I need an observer / observable pattern. That way, I can decide what methods are needed in the equivalent of the observer. – Gilbert Le Blanc Aug 24 '12 at 16:47