设计模式-19-观察者模式
个人github地址:HibisciDai
设计模式系列项目源码:HibisciDai/DesignPattern-LearningNotes-HibisciDai
processon在线UML类图:processon
[TOC]
设计模式-19-观察者模式
观察者模式(Observer Pattern)
意图
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖它的对象都得到通知并被自动更新。
define one-to-many dependency between objects so that when one objects changes state,all its dependents are notified and updated automatically.
主要解决
一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。
何时使用
一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。
关键代码
在抽象类里有一个 ArrayList 存放观察者们。
如何解决
使用面向对象技术,可以将这种依赖关系弱化。
应用实例
- 拍卖的时候,拍卖师观察最高标价,然后通知给其他竞价者竞价。
- 西游记里面悟空请求菩萨降服红孩儿,菩萨洒了一地水招来一个老乌龟,这个乌龟就是观察者,他观察菩萨洒水这个动作。
优点
- 观察者和被观察者是抽象耦合的。
- 建立一套触发机制。
缺点
- 如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
- 如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
- 观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
使用场景
- 一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。
- 一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度。
- 一个对象必须通知其他对象,而并不知道这些对象是谁。
需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制。
注意事项
- JAVA 中已经有了对观察者模式的支持类。
- 避免循环引用。
- 如果顺序执行,某一观察者错误会导致系统卡壳,一般采用异步方式。
案例1
教室里老师一来,学生会表现不同反应。
类图
代码
pattern19.observer.demo1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| public class BroodCast { ArrayList<Chat> chats = new ArrayList<Chat>(); String listenState;
BroodCast() { super(); add(new Chat("flower")); add(new Chat("stone")); add(new Chat("grosss")); }
void add(Chat c) { chats.add(c); }
public void setListenState(String listenState) { this.listenState = listenState; }
void notifyed() { System.out.println("BroadCast : " + listenState); for (Chat c : chats) { c.update(); } } }
public class Chat { String name; String state;
public Chat(String name) { super(); this.name = name; }
void update() { state = "good good study, day day up!"; System.out.println(name + " : " + state); } }
|
测试输出
1 2 3 4 5 6 7
| public class Main { public static void main(String[] args) { BroodCast b = new BroodCast(); b.setListenState("the teacher is coming"); b.notifyed(); } }
|
1 2 3 4
| BroadCast : the teacher is coming flower : good good study, day day up! stone : good good study, day day up! grosss : good good study, day day up!
|
案例1-优化
针对上述例子进行优化,添加高层接口。
类图
代码
pattern19.observer.demo2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| public interface INotifier { void notifyed();
void add(INoStudier ns);
void remove(INoStudier ns); }
public interface INoStudier { void update(); }
public class BroodCast implements INotifier { ArrayList<INoStudier> nss = new ArrayList<INoStudier>(); String listenState;
BroodCast() { super(); add(new Chat("flower")); add(new Chat("stone")); add(new Chat("grosss")); }
public void setListenState(String listenState) { this.listenState = listenState; }
@Override public void notifyed() { System.out.println("BroadCast : " + listenState); for (INoStudier c : nss) { c.update(); } }
@Override public void add(INoStudier ns) { nss.add(ns); }
@Override public void remove(INoStudier ns) { nss.remove(ns); } }
public class Chat implements INoStudier { String name; String state;
public Chat(String name) { super(); this.name = name; }
@Override public void update() { state = "good good study, day day up!"; System.out.println(name + " : " + state); } }
|