观察者——对象行为模式
来源:互联网 发布:为什么中国网络要翻墙 编辑:程序博客网 时间:2024/06/06 06:37
意图
又被称为发布-订阅Subscribe模式、模型-视图View模式、源-收听者Listener模式或从属者模式。观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
动机
将一个系统分割成一个一些类相互协作的类有一个不好的副作用,那就是需要维护相关对象间的一致性。我们不希望为了维持一致性而使各类紧密耦合,这样会给维护、扩展和重用都带来不便。观察者就是解决这类的耦合关系的。
适用场景
当一个对象的改变需要给变其它对象时,而且它不知道具体有多少个对象有待改变时。
一个抽象某型有两个方面,当其中一个方面依赖于另一个方面,这时用观察者模式可以将这两者封装在独立的对象中使它们各自独立地改变和复用。
结构图
角色
抽象主题角色:把所有对观察者对象的引用保存在一个集合中,每个抽象主题角色都可以有任意数量的观察者。抽象主题提供一个接口,可以增加和删除观察者角色。一般用一个抽象类和接口来实现。
抽象观察者角色:为所有具体的观察者定义一个接口,在得到主题的通知时更新自己。
具体主题角色:在具体主题内部状态改变时,给所有登记过的观察者发出通知。具体主题角色通常用一个子类实现。
具体观察者角色:该角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调。通常用一个子类实现。如果需要,具体观察者角色可以保存一个指向具体主题角色的引用。
实现
//观察者,需要用到观察者模式的类需实现此接口public interface Observer{ void update(Object...objs);}//被观察者(一个抽象类,方便扩展)public abstract class Observable{ public finalArrayList<Class<?>> obserList = new ArrayList<Class<?>>(); /**AttachObserver(通过实例注册观察者) *<b>Notice:</b>obcan'tbenull,oritwillthrowNullPointerException **/ public<T> void registerObserver(Tob){ if(ob==null) throw new NullPointerException(); this.registerObserver(ob.getClass()); } /** *AttachObserver(通过Class注册观察者) *@paramcls */ public void registerObserver(Class<?>cls){ if(cls==null) throw new NullPointerException(); synchronized(obserList){ if(!obserList.contains(cls)){ obserList.add(cls); } } } /**UnattachObserver(注销观察者) *<b>Notice:</b> *<b>ItreverseswithattachObserver()method</b> **/ public<T>void unRegisterObserver(Tob){ if(ob==null) throw new NullPointerException(); this.unRegisterObserver(ob.getClass()); } /**UnattachObserver(注销观察者,有时候在未获取到实例使用) *<b>Notice:</b> *<b>ItreverseswithattachObserver()method</b> **/ public void unRegisterObserver(Class<?>cls){ if(cls==null) throw new NullPointerException(); synchronized(obserList){ Iterator<Class<?>>iterator=obserList.iterator(); while(iterator.hasNext()){ if(iterator.next().getName().equals(cls.getName())){ iterator.remove(); break; } } } } /**detachallobservers*/ public void unRegisterAll(){ synchronized(obserList){ obserList.clear(); } } /**Ruturnthesizeofobservers*/ public int countObservers(){ synchronized(obserList){ returnobserList.size(); } } /** *notify all observer(通知所有观察者,在子类中实现) *@paramobjs */ public abstract void notifyObservers(Object... objs); /** *notify one certain observer(通知某一个确定的观察者) *@paramcls *@paramobjs */ public abstract void notifyObserver(Class<?> cls, Object... objs); /** *notifyonecertainobserver *@paramcls *@paramobjs */ public abstract<T> void notifyObserver(T t, Object... objs);}//目标被观察者public class ConcreteObservable extends Observable{ private static ConcreteObservableinstance = null; private ConcreteObservable(){}; public static synchronized ConcreteObservablegetInstance(){ if(instance == null){ instance=newConcreteObservable(); } returninstance; } @Override public <T> void notifyObserver(T t, Object... objs){ if(t == null) throw new NullPointerException(); this.notifyObserver(t.getClass(), objs); } @Override public void notifyObservers(Object... objs){ for(Class<?>cls : obserList){ this.notifyObserver(cls, objs); } } //通过java反射机制实现调用 @Override public void notifyObserver(Class<?>cls, Object...objs){ if(cls == null) throw new NullPointerException(); Method[] methods = cls.getDeclaredMethods(); for(Method method : methods){ if(method.getName().equals("update")){ try{ method.invoke(cls,objs); break; }catch(IllegalArgumentException e){ e.printStackTrace(); }catch(IllegalAccessException e){ e.printStackTrace(); }catch(InvocationTargetException e){ e.printStackTrace(); } } } }}//使用(实现Observer接口)public class Text extends Activity implements Observer{ publicvoidonCreate(...){ ConcreteObservable.getInstance().registerObserver(Text.class); .... } //实现接口处理 publicvoidupdate(Object...objs){ //做操作,比如更新数据,更新UI等 }}
优缺点
优点
第一、观察者模式在被观察者和观察者之间建立一个抽象的耦合。被观察者角色所知道的只是一个具体观察者列表,每一个具体观察者都符合一个抽象观察者的接口。被观察者并不认识任何一个具体观察者,它只知道它们都有一个共同的接口。
第二、观察者模式支持广播通讯。被观察者会向所有的登记过的观察者发出通知,
缺点
第一、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
第二、如果在被观察者之间有循环依赖的话,被观察者会触发它们之间进行循环调用,导致系统崩溃。在使用观察者模式是要特别注意这一点。
第三、如果对观察者的通知是通过另外的线程进行异步投递的话,系统必须保证投递是以自恰的方式进行的。
第四、虽然观察者模式可以随时使观察者知道所观察的对象发生了变化,但是观察者模式没有相应的机制使观察者知道所观察的对象是怎么发生变化的。
- 观察者——对象行为模式
- 对象行为模式——观察者模式(Observer)
- 观察者模式——对象行为型模式
- 对象行为型模式——观察者模式(Observer Pattern)
- OBSERVER(观察者)——对象行为模式
- Observer(观察者)—对象行为型模式
- 观察者模式-对象行为模式
- Observer 观察者模式 ----对象行为型模式
- 设计模式——观察者模式(行为型模式)
- 设计模式——行为性——观察者模式
- 观察者模式——行为型设计模式之五
- 行为型模式之六——观察者模式
- 行为型模式:OBSERVER——观察者模式
- java行为设计模式——观察者模式
- 行为类模式—观察者模式(8)
- 【设计模式】—-(16)观察者模式(行为型)
- 行为模式-观察者模式
- 行为模式-观察者模式
- POSIX多线程程序设计(第7章:Real code)
- AngularJs中Factory和Service和Provide不同(写得很好)
- Excel VBA编程的常用代码(备用待查)
- QT 学习遇到的问题记录2—qml 调用qt c++
- SQLite3查询表结构
- 观察者——对象行为模式
- java socket编程学习笔记
- POSIX多线程程序设计(第8章:避免调试的提示)
- Windows 系统下设置Nodejs NPM全局路径
- C/C++的编译与运行
- IDEA工具类似Eclipse中Ctrl+O查找当前类中方法的快捷键
- UVALive 6838 (括号匹配x线段树)
- 【VBA研究】关闭保存工作簿时重新计算功能
- css中的float和相对定位,绝对定位,z-index