基于Observer及Observable实现更易用的观察者模型
2017-10-09 23:33
411 查看
java提供了Observer接口和Observable类,可以很容易实现一个对象对另一个对象的观察。但同时也存在一些问题,至少个人是这么认为的:
observer对observable的观察行为是由前者发出,而原生java中的这种关系是由Observable的addObserver方法来建立的。虽然观察者模型中大概就是这么描述的,但总感觉有些别扭。比如我要看一个美女,总不能由她来确定我是否可以观察她吧。
原生的被观察者需要继承Observable类,但是被观察者也需要继承其他类时就会出现冲突。如果把Observable实例作为一个属性,因为setChange方法是protect无法调用,会导致notifyObservers方法执行失败。当然总有解决办法,这个不得不说是一个问题。
在observer和observable建立关系后,需要observer的update方法来响应observable的行为。update方法有两个参数Observable o, Object arg,当observable存在多个不同场合触发动作时,observer只能通过第二个参数来判断动作类型以做响应,不太方便。
为了解决以上问题,基于Observer接口和Observable类实现了一套观察者模式的代码。先贴一下使用方法:
被观察者。需要定义一个observable属性,用以执行Observable职责。
观察者。同样需要定义一个observer属性,用以执行Observer职责。
以下依次介绍所使用的代码:
Event类。封装了被观察者信息及自定义属性,用以替换原版中的notifyObservers方法中第二个参数Object arg。
Observable接口。专门用于触发操作的接口。
Observables类。用于集中管理被观察者的,其中包含ObservableBridge内部类,扩展优化了原始Observable并实现了上边的Observable接口。
Obsever类。专门用于执行observe操作的一个中间类。
Obsevers类。结合上边的Obsever类及其内部类ObseverBridge实现了观察者observe方法和update方法的分离和扩展。
ObseverSupport接口。专门执行观察者update方法的接口。
以上代码都是用于个人项目,没有经过大规模验证,纯粹是为实现个人思想而作,还有很多纰漏。仅供大家参考娱乐
observer对observable的观察行为是由前者发出,而原生java中的这种关系是由Observable的addObserver方法来建立的。虽然观察者模型中大概就是这么描述的,但总感觉有些别扭。比如我要看一个美女,总不能由她来确定我是否可以观察她吧。
原生的被观察者需要继承Observable类,但是被观察者也需要继承其他类时就会出现冲突。如果把Observable实例作为一个属性,因为setChange方法是protect无法调用,会导致notifyObservers方法执行失败。当然总有解决办法,这个不得不说是一个问题。
在observer和observable建立关系后,需要observer的update方法来响应observable的行为。update方法有两个参数Observable o, Object arg,当observable存在多个不同场合触发动作时,observer只能通过第二个参数来判断动作类型以做响应,不太方便。
为了解决以上问题,基于Observer接口和Observable类实现了一套观察者模式的代码。先贴一下使用方法:
被观察者。需要定义一个observable属性,用以执行Observable职责。
package com.hulkdeng.test; import com.hulkdeng.observe.Observable; import com.hulkdeng.observe.Observables; import java.util.HashMap; import java.util.Map; public class ObservableDemo { private Observable observable; public ObservableDemo() { //注册可名为hulk的可观察对象 observable = Observables.register("hulk", this); } public void smash() { Map<String, Object> props = new HashMap<String, Object>(); //为事件添加属性 props.put("power", 100000); //触发名为smash的事件,并携带props参数 observable.fire("smash", props); } }
观察者。同样需要定义一个observer属性,用以执行Observer职责。
package com.hulkdeng.test; import com.hulkdeng.observe.*; //观察者需要实现ObserveSupport接口 public class ObserverDemo implements ObserverSupport { private Observer observer; public ObserverDemo() { //注册观察者 observer = Observers.register(this); //观察名为hulk的对象 observer.observe("hulk"); } @Override public void update(Event event) { //sourceName为被观察者的注册名(hulk),eventName是当前事件名称(smash) String sourceName = event.getSourceName(), eventName = event.getEventName(); //获取事件的属性 Integer power = event.getProp("power"); //获取被观察对象 ObservableDemo observableDemo = Observables.getSource("hulk"); } }
以下依次介绍所使用的代码:
Event类。封装了被观察者信息及自定义属性,用以替换原版中的notifyObservers方法中第二个参数Object arg。
package com.hulkdeng.observe; import java.util.Map; public class Event { private String sourceName; private String eventName; private Map<String, Object> props; public Event(String sourceName, String eventName) { this.sourceName = sourceName; this.eventName = eventName; } public Event(String sourceName, String eventName, Map<String, Object> props) { this.sourceName = sourceName; this.eventName = eventName; this.props = props; } public String getSourceName() { return sourceName; } public String getEventName() { return eventName; } public <T> T getProp(String key) { return props != null ? (T) props.get(key) : null; } }
Observable接口。专门用于触发操作的接口。
package com.hulkdeng.observe; import java.util.Map; public interface Observable { void fire(String name); void fire(String name, Map<String, Object> props); }
Observables类。用于集中管理被观察者的,其中包含ObservableBridge内部类,扩展优化了原始Observable并实现了上边的Observable接口。
package com.hulkdeng.observe; import java.util.HashMap; import java.util.Map; public class Observables { private static Map<String, ObservableBridge> observableObjects = new HashMap<String, ObservableBridge>(); public static Observable register(String name, Object source) { ObservableBridge bridge = new ObservableBridge(name, source); observableObjects.put(name, bridge); return bridge; } public static java.util.Observable get(String name) { return observableObjects.get(name); } public static <T> T getSource(String name) { return (T) observableObjects.get(name).getSource(); } public static boolean contains(String name) { return observableObjects.containsKey(name); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public static class ObservableBridge extends java.util.Observable implements Observable { private String sourceName; private Object source; private ObservableBridge(String sourceName, Object source) { this.sourceName = sourceName; this.source = source; } public String getSourceName() { return sourceName; } public Object getSource() { return source; } @Override public void fire(String name) { setChanged(); notifyObservers(new Event(sourceName, name)); } @Override public void fire(String name, Map<String, Object> props) { setChanged(); notifyObservers(new Event(sourceName, name, props)); } } }
Obsever类。专门用于执行observe操作的一个中间类。
package com.hulkdeng.observe; public class Observer { private Observers.ObserverBridge observerBridge; public Observer(ObserverSupport observer) { this.observerBridge = new Observers.ObserverBridge(observer); } public void observe(String name) { if (Observables.contains(name)) { Observables.get(name).addObserver(observerBridge); } } }
Obsevers类。结合上边的Obsever类及其内部类ObseverBridge实现了观察者observe方法和update方法的分离和扩展。
package com.hulkdeng.observe; import java.util.Observable; public class Observers { public static Observer register(ObserverSupport observer) { return new Observer(observer); } public static class ObserverBridge implements java.util.Observer { private ObserverSupport observer; public ObserverBridge(ObserverSupport observer) { this.observer = observer; } /** * This method is called whenever the observed object is changed. An * application calls an <tt>Observable</tt> object's * <code>notifyObservers</code> method to have all the object's * observers notified of the change. * * @param o the observable object. * @param arg an argument passed to the <code>notifyObservers</code> */ @Override public void update(Observable o, Object arg) { observer.update((Event) arg); } } }
ObseverSupport接口。专门执行观察者update方法的接口。
package com.hulkdeng.observe; public interface ObserverSupport { void update(Event event); }
以上代码都是用于个人项目,没有经过大规模验证,纯粹是为实现个人思想而作,还有很多纰漏。仅供大家参考娱乐
相关文章推荐
- 利用观察者(Observer)和被观察者(Observable)实现监听操作
- 观察者模式之----Observable和Observer是怎么实现奇妙的通知功能的
- 利用Observable、Observer实现观察者模式
- Java 语言使用 Observer/Observable 实现简单的观察者模式
- Java 语言使用 Observer/Observable 实现简单的观察者模式
- [置顶] Java Observer与Observable实现观察者模式
- Observer,Observable实现观察者模式
- Rx_java(2) 使用java中的类(Observable与Observer)实现观察者模式
- 【设计模式】设计模式C++编程实现之观察者模式(ObserverPattern)
- 基于Python的Xgboost模型实现
- 基于CPU实现的Cook-Torrance光照模型(Cg语言实现)
- 基于Scikit-learn实现回归模型——房价预测
- 我所理解的设计模式(C++实现)——观察者模式(Observer Pattern)
- 《GOF设计模式》—观察者(OBSERVER)—Delphi源码示例:推模型(push model)
- tensorflow38《TensorFlow实战》笔记-07-02 TensorFlow实现基于LSTM的语言模型 code
- Java_观察者模式(Observable和Observer) -转
- OpenJDK源码研究笔记(六)--观察者模式工具类(Observer和Observable)和应用示例
- 我所理解的设计模式(C++实现)——观察者模式(Observer Pattern)
- 深度学习之六,基于RNN(GRU,LSTM)的语言模型分析与theano代码实现
- 基于Spark MLlib平台和基于模型的协同过滤算法的电影推荐系统(二)代码实现