Search code examples
javadesign-patternssingletonobserver-pattern

Is this the Observer pattern or something else?


This is some code that I've been working on that is inspired by Singleton and by Observer but is really neither. Is this is some other pattern or is it just a mutt? The context for this is an Android app where several Activity objects may be interested in an object that is tied to a particular account. It loads the data when the first Activity registers itself and lets the data go once there are no more observers.

I'd like to know if, for example, it's a horrible idea to use class variables and methods to manage these objects and observers. Whatever feedback is welcome.

This question started out as a question about when to notify an Observer if the object it's registering for already exists. As I was typing the question, I realized that in pure Observer the Observable is the interesting thing and static methods are not involved.

public class MyObserver{
    public MyObserver(String id){
        MyObservable.addObserver(this, id);
    }

    public void update(MyObservable myObservable){
        ... do something with myObservable ...
            ... maybe based on myObservable.id ...
    }
}

public class MyObservable{

    /*********************************
     * Object management static code *
     *********************************/
    private static Map<String,Set<MyObserver>> observers;
    static{
        observers = new Map<String,Set<MyObserver>>();
    }

    private static Map<String,MyObservable> instances;
    static{
        instances = new HashMap<String,MyObservable>();
    }

    private static void addObserver(MyObserver myObserver, String id){
        Set<MyObserver> myObservers = observers.get(id);
        if(myObservers==null){
            myObservers = new Set<MyObserver>();
            observers.put(myObservers);
        }
        myObservers.add(id);

        MyObservable instance = instances.get(id);
        if(instance!=null){
            myObserver.update(instance);
        } else {
            loadData(id);
        }
    }

    private static void removeObserver(MyObserver myObserver, String id){
        Set<MyObserver> myObservers = observers.get(id);
        if(myObservers!=null){
            myObservers.remove(myObserver);
            if(myObservers.isEmpty()){
                instances.remove(id);
            }
        }
    }

    private static void loadData(String id){
        MyObservable  myObservable = ... asynchronous code to load myObservable ...
        ... callback will call MyObservable.set(id,  myObservable); ...
    }

    private static void set(MyObservable myObservable){
        String id=myObservable.getId();
        instances.put(id, myObservable);
        Set<MyObserver> myObservers = observers.get(id);
        if(myObservers!=null){      
            for(MyObserver myObserver:myObservers){
                myObserver.update(myObservable);
            }       
        }
    }

    /**********************************************
     * Data Object instance variables and methods *
     **********************************************/
    public MyObservable(String id){
        myId=id;
    }

    private string myId;
    private String myData1;
    private String myData2;
    private String myData3;
    ... getters and setters ...

}

Solution

  • Nothing about the observer pattern says how it must be implemented, it just means there's a relationship between who's watching, and who's being watched. Nothing says multiple patterns can't be used in an implementation.

    One problem with this type of implementation is that unless object lifecycle is very carefully managed you'll end up with a lot of references to objects that nobody cares about anymore.