这是观察者模式还是其他什么?

时间:2011-10-27 16:51:08

标签: java design-patterns singleton observer-pattern

这是我一直在研究的一些代码,它受到了Singleton和Observer的启发,但实际上并非如此。这是其他一些模式还是只是一个笨蛋?这个上下文是一个Android应用程序,其中几个Activity对象可能对与特定帐户绑定的对象感兴趣。它在第一个Activity注册自身时加载数据,并在没有更多观察者时让数据继续运行。

我想知道,例如,使用类变量和方法管理这些对象和观察者是否是一个可怕的想法。无论欢迎什么反馈。

这个问题最初是关于何时通知观察者它注册的对象是否已经存在的问题。当我输入问题时,我意识到在纯Observer中,Observable 有趣的东西,并且不涉及静态方法。

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 ...

}

3 个答案:

答案 0 :(得分:2)

观察者模式没有说明必须如何实施,只是意味着谁在观看,谁在观看。没有人说在实现中不能使用多个模式。

这种类型的实现存在的一个问题是,除非对象生命周期非常进行了仔细管理,否则最终会有很多对无人关心的对象的引用。

答案 1 :(得分:1)

在Java中,成语是使用“Listeners”。您应该有一个名为XListener的界面。它将定义类似于更新方法的内容。然后,您只需使用方法addXListener(Xlistener)removeXListener(XListener)创建可观察对象。它们维护一个可以通知的侦听器的List(未设置)。可观察对象可以多次拥有相同的侦听器。没有什么是静态的。查看java.beans.PropertyChangeSupportjava.beans.PropertyChangeListener

你遇到的两个主要问题是:

  1. 可观察的静态内容。静电为什么?如果只需要该类的一个可观察对象,则可以使用Singleton模式。但是你应该使用依赖注入。
  2. Observable和Observer之间的强耦合。 XListener接口应该 不知道你将拥有的可观测量。否则,你 引入一个循环依赖,你不再编程 接口而不是实现。

答案 2 :(得分:0)

这是SingletonObserver

全局事件处理程序可以这种方式工作,例如为摇摆中的任何关键事件注册听众。

请确保仔细添加和删除观察者以避免内存泄漏。