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

发布于 2024-12-12 09:31:12 字数 2800 浏览 0 评论 0原文

这是我一直在研究的一些代码,其灵感来自于 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 ...

}

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

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

2024-12-19 09:31:12

观察者模式没有说明它必须如何实现,它只是意味着谁在观看和谁被观看之间存在关系。没有什么规定不能在实现中使用多种模式。

这种类型的实现的一个问题是,除非对象生命周期被非常仔细管理,否则您最终会得到大量对没人关心的对象的引用。

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.

染墨丶若流云 2024-12-19 09:31:12

在Java中,习惯用法是使用“Listeners”。您应该有一个名为 XListener 的接口。它将定义类似您的更新方法的内容。然后,您只需使用 addXListener(Xlistener)removeXListener(XListener) 方法即可获得可观察值。他们维护一个可以通知的侦听器列表(未设置)。可观察对象可以多次拥有相同的侦听器。没有什么是静态的。查看 java.beans.PropertyChangeSupport 和 java.beans.PropertyChangeListener。

您所拥有的两个主要问题是:

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

In Java, the idiom is to use "Listeners". You should have an interface called XListener. It will define something like your update method. Then you just have your observables with methods addXListener(Xlistener) and removeXListener(XListener). They maintain a List (not set) of the listeners which can be notified. The observable object can have the same listener more than once. Nothing is static. Check out java.beans.PropertyChangeSupport and java.beans.PropertyChangeListener.

The two main problems with what you have are:

  1. The static stuff in the observable. Why static? If you need only one observable object of that class, then you could use the Singleton pattern. But you should use dependency injection instead.
  2. Strong coupling between the Observable and Observer. The XListener interface should
    not know about the observables that you will have. Otherwise, you
    introduce a circular dependency and you are no longer programming to
    an interface instead of an implementation.
墟烟 2024-12-19 09:31:12

它是一个单例观察者

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

确保小心添加和删除观察者以避免内存泄漏。

It is a Singleton and Observer.

Global event handlers can work this way, e.g. registering listeners for any key event in swing.

Make sure you add and remove observers carefully to avoid a memory leak.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文