Observer patern (观察者模式) (オブザーバ・パターン)

【描述】
某一对象发生变化时,自动通知相关联对象,就叫响应对象吧。
(登场人物:观察对象,响应对象)

【使用场合】
1.核心数据(观察对象)发生变化时,需要及时通知使用这些数据的对象(响应对象),达到同步。
2.需要监测某事件时,比如鼠标点击事件,把该事件的响应处理登录到观察对象的列表里。

【实现步骤】
1.把这些响应对象的引用作为一个数组,保存成观察对象的变量。
2.当某一事件发生时,遍历响应对象的数组,逐个更新。
3.为了保证可扩展性,关联对象都实现了某一接口,而被观察对象只需要调用这个接口即可。

【代码】([i]可直接跳至【简洁版】[/i])


//观察对象
public class Subject{

//需要更新的对象的引用保存到一个数组里
List<Observer> observers = new ArrayList<Observer>();;

//通知所有关联对象
public void mynotify(){
for(Observer obs : observers){
obs.Update();
}
}

//更新对象追加
public void attach(Observer observer){
observers.add(observer);
}

//更新对象删除
public void detach(Observer observer){
observers.remove(observer);;
}
}

//所有响应事件都实现这一接口
public interface Observer {
void Update();
}

//响应事件
public class ObserverItem1 implements Observer {
@Override
public void update() {
//观察对象更新引起的处理
}
}

//测试
public class run {
public static void main(String[] args) {
Subject sb = new Subject();
pr.detach(new ObserverItem1());
pr.mynotify("123");
}
}



【延伸】
响应处理(ObserverItem1的update)在执行的过程中,可能会用到观察对象Subject的一些数据,这时候我们就有几种解决方案。
1.在ObserverItem1的update里增加参数,比较直观,但是参数类型和数量很难确定,不利于扩展。
2.在ObserverItem1里增加Subject对象的一个引用,Subject公开的所有属性都可以访问到。

class Observer1 implements Observer {
Subjectb subject;

public Observer1(Subjectb subject){
this.subject = subject;
}

public void Update(){
//观察对象更新引起的处理
//这里可以随时访问subject的属性
}
}

缺点是双向引用很难理解,比如下面的代码

Subject sb = new Subject();
sb.attach(new ObserverItem1(sb)); //有点SB


3.结合上面两种方案,把Subject对象作为参数传给ObserverItem1。


public class Subject{

//需要更新的对象的引用保存到一个数组里
List<Observer> observers = new ArrayList<Observer>();;

//通知所有关联对象
public void mynotify(){
for(Observer obs : observers){
obs.Update(this);
}
}

//更新对象追加
public void attach(Observer observer){
observers.add(observer);
}

//更新对象删除
public void detach(Observer observer){
observers.remove(observer);;
}
}

//所有响应事件都实现这一接口
public interface Observer {
public void Update(Subject subject);
}

//响应事件
public class ObserverItem1 implements Observer {
@Override
public void update(Subject subject) {
//观察对象更新引起的处理
//这里可以随时访问subject的属性
}
}

//测试
public class run {
public static void main(String[] args) {
Subject sb = new Subject();
pr.detach(new ObserverItem1());
pr.mynotify();
}
}


【最终版】
使用java.util提供的接口


import java.util.Observable;
public class Subject extends Observable {
//通知所有关联对象
public void mynotify(){
//设置变化点
setChanged();
notifyObservers();//
}
}

//响应事件
import java.util.Observer;
public class ObserverItem1 implements Observer{
public void update(Observable o, Object arg) {
Subject subject = (Subject)o;
//观察对象更新引起的处理
//这里可以随时访问subject的属性
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值