读《研磨设计模式》-代码笔记-观察者模式

[b]声明:
本文只为方便我个人查阅和理解,详细的分析以及源代码请移步 原作者的博客[url]http://chjavach.iteye.com/[/url][/b]




import java.util.ArrayList;
import java.util.List;
import java.util.Observable;
import java.util.Observer;

/**
* “观察者”这个说法有歧义,听来好像是观察者在主动监控,其实只是被动的等通知,并不能感知到目标有变化
* 个人觉得观察者模式实现的关键,其实不在观察者而在被观察者,也就是Subject(目标):
* Subject类负责通知观察者,负责观察者的加入和移除;而观察者只是被动的等待通知
*
* 这样,实现的思路也就清晰了:
* 1.Subject类持有一个Observer的列表(Observer可能有多个),并提供add和delete功能
* 2.Observer如何接收通知呢:
* 可以接收整个Subject,如update(Subject subject);可以只接收“通知”,例如update(String message)
* 前者是拉模式,后者是推模式
*
*/
class Subject{

private List<IObserver> observers = new ArrayList<IObserver>();

public void attach(IObserver observer) {
observers.add(observer);
}

public void detach(IObserver observer) {
observers.remove(observer);
}

//拉模式。整个Subject传递过去,由Observer决定取Subject的哪部分内容
//notifyObservers()不需要传递参数
//可以对观察者作更精细的控制,例如只通知一部分观察者
public void notifyObservers() {
for (IObserver observer : observers) {
observer.update(this);
}
}

//推模式。直接推送Subject的详细信息,相当于广播。对应的Observer.update()也要更改
//notifyObservers()传递参数:String content
/*
public void notifyObservers(String content) {
for (IObserver observer : observers) {
observer.update(content);
}
}
*/

}


interface IObserver{
void update(Subject subject);
}


class PaperSubject extends Subject {

private String content;

public void setContent(String content) {
this.content = content; //先更新内容,后通知
notifyObservers();
}

public String getContent() {
return this.content;
}

}


class ReaderObserver implements IObserver {

private String name;

ReaderObserver(String name) {
this.name = name;
}

//拉模式
public void update(Subject subject) {
PaperSubject s = (PaperSubject)subject;
System.out.println(name + " got paper: " + s.getContent());
}

//推模式
/*
public void update(String content) {
System.out.println(name + " got paper: " + content);
}
*/

}


/**
* 利用JDK里面的Observable(目标)和Observer(观察者)实现观察者模式
* 查看Observable的源码发现和上面的思路是一样的,不过Observable兼容了推模式和拉模式
*/
class PaperObservable extends Observable {

private String content;

public String getContent() {
return content;
}

public void setContent(String content) {
this.content = content;
setChanged();
notifyObservers(); //拉模式 源码里其实就是调用:notifyObservers(null)->update(this, null)
setChanged(); //调用notifyObservers后会clearChanged
notifyObservers(this.content); //推模式->update(this, this.content)
}

}

class ReaderObserver2 implements Observer {

//如果observable提供公有方法可获取到obj,那有重复传递参数的嫌疑;但实际应用中可传递其他值
public void update(Observable observable, Object obj) {
if (obj == null) {
PaperObservable o = (PaperObservable)observable;
System.out.println("拉模式,自己动手获取:" + o.getContent());
} else {
System.out.println("推模式:" + obj);
}
}

}


public class ObserverPattern {
public static void main(String[] args) {
/*IObserver reader = new ReaderObserver("Tom");
PaperSubject paper = new PaperSubject();
paper.attach(reader);
paper.setContent("paper new content!");*/

Observer reader = new ReaderObserver2();
PaperObservable paper = new PaperObservable();
paper.addObserver(reader);
paper.setContent("paper new content!");
}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值