观察者设计模式
观察者设计模式:
百度百科定义:
观察者模式(有时又被称为模型(Model)-视图(View)模式、源-收听者(Listener)模式或从属者模式)是软件设计模式的一种。在此模式中,一个目标物件管理所有相依于他的观察者物件,并且在他本身的状态改变时主动发出通知。这通常投过呼叫各种观察者所提供的方法来实现。此种模式通常被用来实现时间处理系统。
思维导图:
什么是观察者设计模式:
观察者模式(Observer)是软件设计模式的一种,定义了对象之间一种一对多的关系,也就是当一个对象数据发生变化时,会通知与之依赖的其他对象,以相应其数据变化,这种当目标对象数据发生变化时,与之对应的观察者对象数据随之发生变化的,具有一对多通知关系的设计模式叫做观察者设计模式。
关键概念理解:
观察者:指观察者对象,也就是消息的订阅者;
被观察者:指要观察的目标对象,也就是消息的发布者;
通知观察者的方式:
推:消息以类似广播的形式通知观察者,观察者只能被动、无条件的接受;
拉:接受到被观察者的通知,可以自主决定获取消息;
两种方式的比较:
1)推模型时假定主题对象知道观察者需要的数据;而拉模型是主题对象不知道观察者具体需要什么数据,没有办法的情况下,干脆把自身传递给观察者,让观察者自己去按需要取值。
2)推模型可能会使得观察者对象难以服用,因为观察者的updata()方法是按需要定义的参数,可能无法兼顾没有考虑到的使用情况。这就意味着出现新情况的时候,就可能提供新的updata()方法,或者是干脆重新实现观察者;而拉弄下就不会造成这样的情况,以为拉模型下,updata()方法的参数是主题对象本身,这剧本上是主题对象能传递的最大数据集合了,基本上可以适应各种情况的需要。
- 手写观察者模式:
首先创建被观察者,具体如下:
/** * 观察者要观察的目标对象 * @author jzman */ public abstract class Subject { protected ArrayList<Observer> observerList = new ArrayList<>(); //表示观察者对目标对象(被观察者)开始观察 public void registerObserver(Observer obs) { observerList.add(obs); } //表示取消某观察者对目标对象(被观察者)的观察 public void unRegisterObserver(Observer obs) { observerList.remove(obs); } //当目标对象(被观察者)的状态发生变化时,及时更新观察者的状态 public void notifyAllObserver(){ for (Observer observer : observerList) { observer.update(this); } } }
创建具体的被观察者,具体如下:
/** * 具体的目标对象(被观察者) * @author jzman */ public class ConcreteSubject extends Subject{ private int state; public int getState() { return state; } public void setState(int state) { this.state = state; //当数据发生变化时通知其他的观察者 notifyAllObserver(); } }
然后,为了统一方便,定义观察者接口,具体如下:
/** * 观察者统一接口 * @author jzman */ public interface Observer { void update(Subject subject); }
然后,创建具体的观察者,具体如下:
/** * 具体的观察者 * @author jzman */ public class ConcreteObserver implements Observer{ private int state; public int getState() { return state; } public void setState(int state) { this.state = state; } @Override public void update(Subject subject) { //获取目标对象的数据变化,同时更新当前观察者 ConcreteSubject concreteSubject = (ConcreteSubject)subject; state = concreteSubject.getState(); } }
最后,测试观察者设计模式,具体如下:
/** * Main * @author jzman */ public class Client { public static void main(String[] args) { //创建具体的目标对象(被观察者) ConcreteSubject concreteSubject = new ConcreteSubject(); //创建多个具体的观察者 ConcreteObserver obs1 = new ConcreteObserver(); ConcreteObserver obs2 = new ConcreteObserver(); ConcreteObserver obs3 = new ConcreteObserver(); //让观察者观察目标对象(被观察者)的数据变化 concreteSubject.observerList.add(obs1); concreteSubject.observerList.add(obs2); concreteSubject.observerList.add(obs3); //改变某个目标对象(被观察者)的数据 concreteSubject.setState(10); //观察者数据是否与被观察者数据变化一致 System.out.println("观察者obs1:"+obs1.getState()); System.out.println("观察者obs2:"+obs2.getState()); System.out.println("观察者obs3:"+obs3.getState()); } }
执行结果如下:
观察者obs1:10 观察者obs2:10 观察者obs3:10
通过对目标对象数据的改变,更显了与之相对应的观察者的数据,实现了消息的订阅和发送。
2.Java API 提供的观察者设计模式
Java API 提供的观察者设计模式主要通过Observer 和 Observeable 来实现,首先创建一个类继承Observeable 作为被观察者,具体如下:
/** * 被观察者(目标对象) * @author jzman */ public class ConcreteSubject extends Observable{ private int state; public int getState() { return state; } public void setState(int state) { this.state = state; //表示数据已经发生变化 setChanged(); //具体的目标对象数据变化的时候通知观察者 notifyObservers(state); } }
然后,创建一个类继承Observer 作为观察者,具体如下:
/** * 观察者 * @author jzman */ public class ConcreteObserver implements Observer{ private int state; public int getState() { return state; } public void setState(int state) { this.state = state; } @Override public void update(Observable arg0, Object arg1) { ConcreteSubject concreteSubject = (ConcreteSubject) arg0; //根据目标对象(被观察者)的数据变化更新当前观察者的数据 this.state = concreteSubject.getState(); } }
测试观察者设计模式,具体如下:
/** * 测试观察者设计模式 * @author jzman */ public class Client { public static void main(String[] args) { ConcreteSubject concreteSubject = new ConcreteSubject(); ConcreteObserver obs1 = new ConcreteObserver(); ConcreteObserver obs2 = new ConcreteObserver(); ConcreteObserver obs3 = new ConcreteObserver(); concreteSubject.addObserver(obs1); concreteSubject.addObserver(obs2); concreteSubject.addObserver(obs3); concreteSubject.setState(100); System.out.println("观察者obs1:"+obs1.getState()); System.out.println("观察者obs2:"+obs2.getState()); System.out.println("观察 3ff7 者obs3:"+obs3.getState()); } }
执行结果如下:
观察者obs1:100 观察者obs2:100 观察者obs3:100
观察者设计模式的优缺点:
优点:****观察者与被观察者抽象耦合,可定义一种稳定的消息出发机制。
缺点:如果被观察者有多个间接的观察者,消息的传递将消耗更多时间,如果观察者与被观察之间循环依赖,最终会导致系统崩溃。
使用场景:
如游戏、聊天等过程中消息的从服务端转发给客户端的过程。
Android中的广播机制以及ListView 中通知数据发生变化时也是观察者设计模式。
订阅相关的系统,如订阅的主题有更新,订阅者就会同步订阅的文章。
- 马士兵设计模式2之观察者模式模拟AWT
- 设计模式总结之Observer Pattern(观察者模式)
- C#设计模式之Observer观察者模式解决牛顿童鞋成绩问题示例
- Java设计模式之Observer(观察者)模式
- (转)设计模式——观察者模式
- js与设计模式----观察者模式
- 设计模式之19 - 观察者模式Observer
- Java设计模式之观察者模式
- .NET简谈设计模式之(观察者模式)
- 设计模式学习笔记(二)之观察者模式(Observer)
- 设计模式理解 - 伟大的【Observer 观察者模式】
- 设计模式——观察者模式
- 设计模式笔记之五:观察者模式
- 设计模式之观察者模式
- 设计模式之Observer(观察者)模式
- 设计模式基础——观察者模式
- 观察者设计模式
- 【白话设计模式二】观察者模式(Observer)
- 游戏服务器设计之观察者模式