编程基本知识--观察者模式
来源:互联网 发布:直销会员管理系统源码 编辑:程序博客网 时间:2024/06/05 08:41
观察者模式是我们经常使用的模式之一,那什么是观察者模式呢?观察者模式(有时又被称为发布-订阅Subscribe>模式是23种模式中的一种。在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实现事件处理系统。
我还是用比较通俗的方法来理解!比如:某人去邮局订了一本杂志,那么如果杂志有更新了,邮局就会通知他,因此这里面就会有两个重要的对象,一个就是某人(我们可以称为观察者),那另一个对象就是邮局(我们可以称为被观察对象或者叫主题),那么它的作用是什么?一般而言有两个作用:1.管理观察者,我们去订杂志的时候总会告诉邮局,邮局也一定会有记录的。2.通知观察者,当有新杂志到的时候,主题必须通知观察者有新的杂志到了。
我们可以进一步把上面的概念抽象成对象:
邮局:抽象成主题(Subject),它是管理者一般会有注册方法(regists),当然也有注销方法(unregists),还有一个通知观察者的方法(notify)。
某人:抽象成观察者(Observer),它是被通知的人,那肯定有一个更新的方法(update)。
我们一般都是面向接口编程,所以再一次把上面抽象成接口:
主题(Subject):它把所有观察者对象的引用保存到一个集合或者数组里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象。
抽象观察者(Observer):为所有的具体观察者定义一个接口,在得到主题通知时更新自己。
具体观察者(ConcreteObserver):实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题状态协调。
下面我们来简单实现一下:
一. 定义观察者接口:
package java.observer;public interface Observer { public void update(Subject subject,Object data);}二.主题的实现:这里我用arraylist集合来保存所有观察者对象。因为在项目中我们也是经常只有一个主题,所以这里我使用单例.
package java.observer;import java.util.ArrayList;import java.util.List;public class Subject { private static Subject mInstance; private List<Observer> observers = new ArrayList<Observer>(); private Subject() { } public static Subject getInstance() { if(mInstance == null) { mInstance = new Subject(); } return mInstance; } public void regists(Observer observer) { if(observer != null) { observers.add(observer); } } public void unregists(Observer observer) { if(observer != null) { observers.remove(observer); } } public void notify(Object object) { for(Observer observer : observers) { observer.update(this, object); } }}三.我们再来具体实现一个观察者:
package java.observer;public class ObserverImpl implements Observer { @Override public void update(Subject subject, Object data) { System.out.println((String)data); }}这里只是简单的打印,实际项目中肯定不会这么简单。
我还是简单的运行起来:
package javaObserver.myObserver;public class ObserverClient { public static void main(String[] args) { Subject obSubject = Subject.getInstance();// 获取主题 // 实例化一个观察者 ObserverImpl observer = new ObserverImpl(); // 注册观察者 obSubject.regists(observer); // 如果事件到来时,主题会主动更新 obSubject.notify("update all observer "); }}
到这里我们简单的观察者模式,基本已经完成。这只是在单线程的环境下面运行的,如果要想在多线程的环境下面运行,我们必须对上面几个部分进行修改:
第一.单例问题
public static Subject getInstance() { if(mInstance == null) { mInstance = new Subject(); } return mInstance; }这是不安全,我们必须改成线程安全的。可以改成下面:
private static class SubjectInner { public static Subject inner = new Subject(); } public static Subject getInstance() { return SubjectInner.inner; }第二,给regists,unregists 和 notify方法加上synchronized 关健字。这样相当对每个方法都加了锁,而且锁住的对象本身。
似乎这样已经是很好的,因为我们保证了每个方法都是同步,只有一个线程能操作,但这里就有一个效率上面的问题,如果观察者对象很多的时候,一个线程在遍历,而其他要注册或取消的进程就有可能进行长时间的等待。因此,我们一般只对regists,unregists加同步。
但如果没有对notify加同步的时候却产生了另外一个问题:concurrentmodificationexception ,这个异常是由于遍历集合的时候,同时有人在修改集合里面的数据。
要解决这个问题,我们一般有两种方法:
第一种:把上面的arraylist 改成用CopyOnWriteArrayList 集合,CopyOnWriteArrayList的原理很解决,每次写数据的时候都把原来的数据复制一份,所以也就不会有问题,但这样也会有一个问题,如果数据大的也会比较占空间,是一种用空间换时间的做法。
第二种:每次注册的时候,先去检测有没有在遍历,如果正在遍历则添加到临时集合里面,遍历完成之后再添加到原来的集合里面。本人比较偏向第二种方法。
- 编程基本知识--观察者模式
- 网络编程--观察者模式
- Java观察者模式编程
- Android编程:观察者模式设计
- 【编程素质】设计模式-观察者模式
- C++编程模式1--观察者模式
- 观察者模式在Java编程中的应用
- php面向对象编程 – 观察者模式
- 基于键值的观察者模式编程
- 面向对象编程思想-观察者模式
- 面向对象编程思想-观察者模式
- apue 中c/s模式编程的一些基本知识
- 如何看待编程模式 + 观察者模式含义解释
- C++ 编程实现 观察者模式--订阅模式-->初学者。
- PHP面向对象编程设计模式(四)观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- UVA 694 The Collatz Sequence
- Linux下格式化U盘
- POJ 3301 Texas Trip (三分)
- czmq(zmq)安装
- 最简单的使用MD5加密算法对数据进行加密
- 编程基本知识--观察者模式
- 去除inline和inline-block元素的间距的五个方法
- dblink的查看创建与删除
- Android生存指南:Eclipse快捷键
- 控件显示乱码
- LINUX中断机制与信号
- hdu 4002 - Find the maximum
- 【免费培训】云时代的IT运维,还有惊喜礼品哦~
- 《AN3137》stm8 ADC