设计模式之--观察者模式
来源:互联网 发布:mac pro怎么安装双系统 编辑:程序博客网 时间:2024/06/16 16:10
设计模式之--观察者模式
网上对设计模式的分享和笔记已经很多了,我依然在此写这一篇十分没有新意的东西,这主要是一来记录下自己最近一段时间的学习生活,另一来是希望通过这篇博文来重新启动一下自己的博客灌水生活,很久没有写东西了,看着尘封已久的博客、回首那段记忆空白的日子,有点惶恐的感觉,这么长的时间我竟连一点痕迹都没留下,我这样的存在实在是太过于环保了。好吧,废话就此打住,让我们进入主题。
1.什么是观察者模式
按照《Head First Design Pattern》的定义,观察者模式用于定义一种对象之间的一对多的关系,使得其中的某一个对象发生变化时,其他对此感兴趣的对象能被通知,并自动更新状态。
在观察者模式中,有一个被观察主体(Subject)用于发布(Publish)状态(State),此外还有多个观察者对象(Observer Object)。观察者对象通过向被观察主体注册或者订阅(Register or Subscribe)表示自己对Subject发布的状态感兴趣。Subject对象定时(根据自身状态的改变)主动将状态信息告知Observer对象(push方式)或者通知观察者对象取其所感兴趣的信息(pull方式)。
观察者模式中,Subject不关心Observer的实现方式,不关心Observer的加入和退出;Observer对象也不关心Subject的实现方式,只要求其实现了特定的接口,能提供其感兴趣的信息。
2. 应用场景
观察者模式又名发布者模式,顾名思义这种模式主要运用在当一种对象需要对外发布状态时,主要运用在对象之间存在多对一的依赖关系时候,让多个观察者对象能够根据被观察主体状态的改变自动更新(update)自己。
3. 实现方式
在观察者模式的设计实现中,由于要求彼此之间的松耦合,彼此不再关心对方的具体实现,只要求对方实现特定的接口即可。因此,要求观察者主体(Subject)具体实现类必须实现Subject接口,而观察者对象(Observer)具体实现类必须Observer接口。原谅我没有找到画类图的工具,所以我借用网上的一张图片以表示这种关系。
(观察者模式结构,引自supercrsky)
Subject接口定义了三个方法,分别是attatch(向Subject注册观察者)、detach(从注册的观察表中删除)、notifyObservers(通知观察者对象)。Observer接口定义了一个方法update,用于接收Subject的更新调用。在Subject具体类的实现中因为需要维持观察者的信息,所以需要定义一个List用于保存所有的观察者对象引用。
下面通过一个简单的例子向大家讲一下观察者模式的具体实现,在本例子中被观察者主体在感知到自身的状态(message)发生变化之后,将消息发送给所有的观察者对象。本例中定义了三种不同的观察者实现类,他们以不同的方式展现接收到的消息,分别是原样展示、转化成大写展示,转换成小写展示。
---------------- Subject.java
- package cn.ac.ict.chengenbao;
- public interface Subject {
- public void registerObserver(Observer obj);
- public void removeObserver(Observer obj);
- public void notifyObservers();
- }
----------------- Observer.java
- package cn.ac.ict.chengenbao;
- public interface Observer {
- public void update(String message);
- }
--------------------- SubjectImpl.java
- package cn.ac.ict.chengenbao;
- import java.util.ArrayList;
- import java.util.List;
- public class SubjectImpl implements Subject {
- private List<Observer> observerList = null;
- private String msg = null;
- public SubjectImpl() {
- observerList = new ArrayList<Observer>();
- }
- public void registerObserver(Observer obj) {
- // TODO Auto-generated method stub
- observerList.add(obj);
- }
- public void removeObserver(Observer obj) {
- // TODO Auto-generated method stub
- observerList.remove(obj);
- }
- public void notifyObservers() {
- // TODO Auto-generated method stub
- for( Observer o : observerList) {
- o.update(msg);
- }
- if ( observerList.size() == 0 ) {
- System.out.println("There is no observers in the list.");
- }
- }
- public void changeMessage(String message) {
- msg = message;
- this.notifyObservers();
- }
- }
------------------------ OriginOutputer.java
- package cn.ac.ict.chengenbao;
- public class OriginOutputer implements Observer {
- private Subject subject = null;
- public OriginOutputer(Subject s) {
- subject = s;
- s.registerObserver(this);
- }
- public void update(String message) {
- // TODO Auto-generated method stub
- this.display(message);
- }
- private void display(String message) {
- System.out.println(this.getClass().getName() + ":" + message);
- }
- public void leave() {
- this.display("I remove myself from the ObserverList...");
- subject.removeObserver(this);
- }
- }
----------------------- UpperOutputer.java
- package cn.ac.ict.chengenbao;
- public class UpperOutputer implements Observer {
- private Subject subject = null;
- public UpperOutputer(Subject s) {
- subject = s;
- s.registerObserver(this);
- }
- public void update(String message) {
- // TODO Auto-generated method stub
- this.display(message);
- }
- private void display(String message) {
- System.out.println(this.getClass().getName() + ":" + message.toUpperCase());
- }
- public void leave() {
- this.display("I remove myself from the ObserverList...");
- subject.removeObserver(this);
- }
- }
---------------------------- LowerOutputer.java
- package cn.ac.ict.chengenbao;
- public class LowerOutputer implements Observer {
- private Subject subject = null;
- public LowerOutputer(Subject s) {
- subject = s;
- s.registerObserver(this);
- }
- public void update(String message) {
- // TODO Auto-generated method stub
- this.display(message);
- }
- private void display(String message) {
- System.out.println(this.getClass().getName() + ":" + message.toLowerCase());
- }
- public void leave() {
- this.display("I remove myself from the ObserverList...");
- subject.removeObserver(this);
- }
- }
------------------------ Test.java
- package cn.ac.ict.chengenbao;
- public class Test {
- public static void main(String[] args) {
- SubjectImpl subject = new SubjectImpl();
- LowerOutputer lowerOuter = new LowerOutputer(subject);
- UpperOutputer upperOuter = new UpperOutputer(subject);
- OriginOutputer originOuter = new OriginOutputer(subject);
- subject.changeMessage("Message1");
- originOuter.leave();
- subject.changeMessage("Message2");
- lowerOuter.leave();
- subject.changeMessage("Message3");
- upperOuter.leave();
- subject.changeMessage("Message4");
- }
- }
运行结果:
4. JDK API 对观察者模式的支持
JDK API 中提供了对观察者模式的原生支持。在 java.util 包中,包含Observer接口和Observable类,开发者可以通过实现Observer接口和继承Observable类来实现观察者模式。
使用JAVA自带的观察者模式会受到以下限制:
1) java.util.Observable是个类而不是接口,这使得要实现的Subject类不能继承其他的类,从而使得一些原有的类不能迁移至观察者模式。同时,通过继承实现Subject模式也违背了我们“Program to the interface”的一贯原则。
2)Observable实现中对一些关键的方法进行了访问保护,比如说setChanged方法,只有继承自Observable的类才能调用该方法。
原文:http://blog.csdn.net/chengenbao/article/details/17585881
- 设计模式之-观察者
- 设计模式之观察者
- 设计模式之观察者
- 设计模式之观察者
- 设计模式之观察者
- 设计模式之观察者
- 设计模式之观察者
- 设计模式之观察者
- 设计模式之观察者
- 设计模式之观察者
- 设计模式之观察者
- 设计模式之观察者模式
- 设计模式之观察者模式
- 设计模式之观察者模式
- 设计模式之观察者模式
- 设计模式之观察者模式
- 设计模式之观察者模式
- 设计模式之观察者模式
- 关于使用c#调用python脚本文件,脚本文件需要传递参数
- linux下安装jdk
- cocos2D-x关于精灵框架的实现
- alsa sample rate跟踪 <3>
- unity3d开发2d游戏:自动寻路Navmesh入门
- 设计模式之--观察者模式
- jQuery api .next()
- nginx非root用户安装
- OnQueryEndSession 与 OnEndSession
- android中多个applicaiton类需要注册的问题
- 香港成为北京IT服务外包贸易主要地区
- javascript 判断 history.back() 起作用了没
- 避开并购的IT陷阱
- 使用PowerDesigner 15.2对Oracle进行反向工程