观察者模式(Observer)
2013-07-07 18:16
197 查看
@@@模式定义:
定义对象间的一种一对多的依赖关系。当一个对象的状态发生改变时,
所有依赖于它的对象都得到通知并被自动更新。
观察者模式又被称为发布——订阅模式。
@@@练习示例:
订阅报纸
@@@示例代码:
\src\pattern\Subject.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\src\pattern\Observer.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\src\pattern\NewsPaper.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\src\pattern\Reader.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\src\user\Client.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[---使用J***A自带的观察者模式---]
\src\pattern\NewsBook.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\src\pattern\BookReader.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\src\user\BookClient.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@@模式的实现:
1) 目标和观察者之间一般是一对多,也可以一对一;
2) 观察者可以观察多个目标,一般需要为每个目标定义不同的回调方法而不是在update方法中来区分;
3) 观察者模式有推模型和拉模型两种方式;
@@@模式的优点:
1) 观察者模式实现了观察者和目标对象之间的抽象耦合;
2) 观察者模式实现了动态联动;
3) 观察者模式支持广播通信;
@@@模式的缺点:
1) 可能会引起无谓的操作;
@@@模式的本质:
触发联动
@@@模式体现的设计原则:
NA
定义对象间的一种一对多的依赖关系。当一个对象的状态发生改变时,
所有依赖于它的对象都得到通知并被自动更新。
观察者模式又被称为发布——订阅模式。
@@@练习示例:
订阅报纸
@@@示例代码:
\src\pattern\Subject.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
package pattern; import java.util.ArrayList; import java.util.List; /** * 目标对象,作为被观察者 */ public class Subject { /** * 用来保存注册的观察者对象,也就是报纸的订阅者 */ private List<Observer> readers = new ArrayList<Observer>(); /** * 报纸的读者需要向报社订阅,先要注册 * @param reader 报纸的读者 */ public void attach(Observer reader) { readers.add(reader); } /** * 报纸的读者可以取消订阅 * @param reader 报纸的读者 */ public void detach(Observer reader) { readers.remove(reader); } /** * 当每期报纸印刷出来后,就要迅速主动地被送到读者的手中 * 相当于通知读者,让他们知道 */ protected void notifyObservers() { for (Observer reader : readers) { reader.update(this); } } }
\src\pattern\Observer.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
package pattern; /** * 观察者,比如报纸的读者 */ public interface Observer { /** * 被通知的方法 * @param subject 具体的目标对象,可以获取报纸的内容 */ public void update(Subject subject); }
\src\pattern\NewsPaper.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
package pattern; /** * 报纸对象,具体的目标对象 */ public class NewsPaper extends Subject { /** * 报纸的具体内容 */ private String content; /** * 获取报纸的具体内容 * @return 报纸的具体内容 */ public String getContent() { return content; } /** * 示意,设置报纸的具体内容,相当于要出版报纸了 * @param content 报纸的具体内容 */ public void setContent(String content) { this.content = content; // 内容有了,说明又出版报纸了,那就通知所有的读者 notifyObservers(); } }
\src\pattern\Reader.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
package pattern; /** * 真正的读者,为了简单就描述一下姓名 */ public class Reader implements Observer { /** * 读者的姓名 */ private String name; @Override public void update(Subject subject) { // 这里采用拉的方式 System.out.println(name + "收到报纸了,阅读它,内容是:" + ((NewsPaper)subject).getContent()); } public String getName() { return name; } public void setName(String name) { this.name = name; } }
\src\user\Client.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
package user; import pattern.NewsPaper; import pattern.Reader; public class Client { public static void main(String[] args) { // 创建一份报纸,作为被观察者 NewsPaper subject = new NewsPaper(); // 创建读者,也就是观察者 Reader reader1 = new Reader(); reader1.setName("张三"); Reader reader2 = new Reader(); reader2.setName("李四"); Reader reader3 = new Reader(); reader3.setName("王五"); // 注册读者 subject.attach(reader1); subject.attach(reader2); subject.attach(reader3); // 出版报纸 subject.setContent("本期的内容是观察者模式"); } }
[---使用J***A自带的观察者模式---]
\src\pattern\NewsBook.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
package pattern; /** * 报纸对象,具体的目标实现 */ public class NewsBook extends java.util.Observable { /** * 报纸的具体内容 */ private String content; /** * 获取报纸的具体内容 * @return 报纸的具体内容 */ public String getContent() { return content; } /** * 示意,设置报纸的具体内容,相当于要出版报纸了 * @param content 报纸的具体内容 */ public void setContent(String content) { this.content = content; // 内容有了,说明又出版报纸了,那就通知所有的读者 // 注意在使用Java中的Observer模式的时候,下面这句话不可少 this.setChanged(); // 然后主动通知,这里用的是推的方式 this.notifyObservers(this.content); // 如果用拉的方式,这么调用 // this.notifyObservers(); } }
\src\pattern\BookReader.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
package pattern; import java.util.Observable; /** * 真正的读者,为了简单就描述一下姓名 */ public class BookReader implements java.util.Observer { /** * 读者的姓名 */ private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public void update(Observable o, Object obj) { // 这里采用推的方式 System.out.println(name + "收到报纸了,阅读它,目标推过来的内容是:" + obj); // 这里获取拉的数据 System.out.println(name + "收到报纸了,阅读它,主动到目标对象去拉的内容是:" + ((NewsBook)o).getContent()); } }
\src\user\BookClient.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
package user; import pattern.BookReader; import pattern.NewsBook; public class BookClient { public static void main(String[] args) { // 创建一份报纸,作为被观察者 NewsBook subject = new NewsBook(); // 创建读者,也就是观察者 BookReader reader1 = new BookReader(); reader1.setName("张三"); BookReader reader2 = new BookReader(); reader2.setName("李四"); BookReader reader3 = new BookReader(); reader3.setName("王五"); // 注册读者 subject.addObserver(reader1); subject.addObserver(reader2); subject.addObserver(reader3); // 出版报纸 subject.setContent("本期的内容是观察者模式"); } }
@@@模式的实现:
1) 目标和观察者之间一般是一对多,也可以一对一;
2) 观察者可以观察多个目标,一般需要为每个目标定义不同的回调方法而不是在update方法中来区分;
3) 观察者模式有推模型和拉模型两种方式;
@@@模式的优点:
1) 观察者模式实现了观察者和目标对象之间的抽象耦合;
2) 观察者模式实现了动态联动;
3) 观察者模式支持广播通信;
@@@模式的缺点:
1) 可能会引起无谓的操作;
@@@模式的本质:
触发联动
@@@模式体现的设计原则:
NA
相关文章推荐
- DataSetObserver猜想观察者模式
- 我所理解的设计模式(C++实现)——观察者模式(Observer Pattern) (转)
- 设计模式之七 --- 观察者模式(Observer)
- 设计模式——观察者模式(Observer)
- 二十四种设计模式:观察者模式(Observer Pattern)
- C++实现观察者(Observer)模式
- 【软件编程】Observer观察者模式
- 责任型模式一:Observer(观察者)模式
- C#设计模式(4)——观察者模式(Observer Pattern)
- 设计模式——Observer观察者模式
- Design Pattern - Observer 观察者设计模式
- 行为型模式4:观察者模式(Observer Pattern)
- [C++设计模式]observer 观察者模式
- 设计模式之美:Observer(观察者)
- 【观察者模式】的故事来源(Observer Pattern)
- C#设计模式(17)——观察者模式(Observer Pattern)
- 设计模式学习笔记---观察者模式Observer pattern(Java版)
- 五、观察者模式Observer(行为型模式)
- 观察者模式observer
- 设计模式——行为型设计模之借助观察者模式(Observer Pattern)实现模块之间的解耦(四)