这是观察者模式还是其他模式?
这是我一直在研究的一些代码,其灵感来自于 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
观察者模式没有说明它必须如何实现,它只是意味着谁在观看和谁被观看之间存在关系。没有什么规定不能在实现中使用多种模式。
这种类型的实现的一个问题是,除非对象生命周期被非常仔细管理,否则您最终会得到大量对没人关心的对象的引用。
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.
在Java中,习惯用法是使用“Listeners”。您应该有一个名为
XListener
的接口。它将定义类似您的更新方法的内容。然后,您只需使用addXListener(Xlistener)
和removeXListener(XListener)
方法即可获得可观察值。他们维护一个可以通知的侦听器列表(未设置)。可观察对象可以多次拥有相同的侦听器。没有什么是静态的。查看 java.beans.PropertyChangeSupport 和 java.beans.PropertyChangeListener。您所拥有的两个主要问题是:
不知道您将拥有的可观察结果。否则,你
引入循环依赖,您不再需要编程
接口而不是实现。
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 methodsaddXListener(Xlistener)
andremoveXListener(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 outjava.beans.PropertyChangeSupport
andjava.beans.PropertyChangeListener
.The two main problems with what you have are:
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.
它是一个
单例
和观察者
。全局事件处理程序可以以这种方式工作,例如为 swing 中的任何关键事件注册侦听器。
确保小心添加和删除观察者以避免内存泄漏。
It is a
Singleton
andObserver
.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.