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职责。
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);
}
以上代码都是用于个人项目,没有经过大规模验证,纯粹是为实现个人思想而作,还有很多纰漏。仅供大家参考娱乐
分享到:
相关推荐
Java内置的Observable类和Observer接口提供了基本的观察者模式功能,你可以通过继承Observable类和实现Observer接口来使用
观察者模式介绍:Observable和Observer原理分析,手动实现简单MyObservable和MyObserver
可以有任意多个观察者观察同一个目标。 提供注册和删除观察者对象的接口。 2.Observer(观察者) 为那些在目标发生改变时需获得通知的对象定义一个更新接口。 3.ConcreteSubject(具体目标) 将有关状态存入...
从Observer到Observable:使用Functional Swift提升复杂iOS项目的可维护性
从Observer到Observable:使用Functional Swift提升复杂iOS项目的可维护性.pdf
observer观察者模式
这是最简单的一个MVC实例,通过它你可以了解MVC的基本工作原理。
设计模式C++学习之观察者模式(Observer)
这样一来 当一个对象改变状态时 依赖它的对象都会收到通知并自动跟新 Java已经提供了对观察者Observer模式的默认实现 Java对观察者模式的支持主要体现在Observable类和Observer接口 ">观察者 Observer 模式定义:在...
观察者(Observer)和被观察者(Listener)也是这种关系,Observer将自己attach到Listener中,当Listener触发时Notify所有Observer. 作用 在观察者模式中,被观察者维护观察者对象的集合,当被观察者对象变化时,它...
Observer (观察者模式) 又叫做发布/订阅(Publish/Subscribe)模式。 当一个对象的改变同时会影响其他对象的行为的时候,可以使用此设计模式。 l 主题对象 :一个需要被关注的主题对象,这个主题对象改变会影响...
观察者模式(Observer Pattern)是一种对象行为型设计模式,它定义了对象之间的一对多依赖关系。 当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。这种模式通常用于实现分布式事件处理系统...
观察者模式示例 观察者模式示例 观察者模式示例 观察者模式示例 观察者模式示例 观察者模式示例
观察者模式Observer: 以手机号码为例,老师的手机号码存在学生的手机里,若老师的手机号改变,她会发一条短信通知每个学生自己手机号变了
Observer模式定义对象间的一对多的依赖关系,当一个对象(被观察者)的状态发生改变...从名字上可以清楚的看出两者在Observer 设计模式中分别扮演的角色:Observer是观察者角色,Observable是被观察目标(subject)角色。
Observer and Reactor 观察者和recator的比较。想从菜鸟变高手,请下载,只要5分钟,看一下。
我们说学习Java应该从Swing开始,那么学习Swing最重要的思想就是对于观察者模式的理解(Observer Pattern)。因为,该设计模式在Java Swing框架中贯穿了始终。对于C#的委托、代理概念所使用的Callback(回调模式--...
主要介绍了 Java观察者设计模式(Observable和Observer)的相关资料,需要的朋友可以参考下
C#实现的基于观察者模式的事件机制,unity可用。分2个文件,事件和事件中心。事件中心保存有对所有事件(Observer)的引用,事件中心负责对这些事件进行分发,这样每个事件就可以通过回调函数的方式进行更新(传递...
observer-pattern-demo 观察者模式示例