监听器的实现原理

从某种角度来说,我们总是处于两种生活状态:观察者与被观察者。当处于观察者状态时,被观察的对象会向我们发出某种信息,使我们产生某种心理活动或行为状态的改变。当我们处于被观察者状态时,我们的行为活动又可以以信息的方式影响观察者。(大多数情况下是两种状态并存。)
作为一种面向对象的编程语言,java中的设计模式跟我们的生活模式十分相似,观察者模式也不例外。


一 观察者模式定义与组成

观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,让他们能够自动更新自己 。主要分为四部分:1.抽象主题角色 2.抽象观察者角色 3.具体主题角色 4.具体观察者角色

二 自定义观察者模式

/**抽象主题角色:
 * 把所有对观察者对象的引用保存在一个集合中,
 * 每个抽象主题角色都可以有任意数量的观察者。
 * 抽象主题提供一个接口,可以增加和删除观察者角色。
 * 一般用一个抽象类或接口来实现 
 */
public interface BeWatched {

    //增加一个观察者
    public void addWatcher(Watcher watcher);

    //删除一个观察者
    public void removeWatcher(Watcher watcher);

    //通知所有的观察者
    public void notifyWatchers(String str);

}
/**
 * 抽象观察者角色:为所有观察者定义一个接口,在接到主题角色的通知时更新自己
 * @author Administrator
 *
 */
public interface Watcher {

    //更新自己
    public void update(String str);

}
/**
 * 具体主题角色:
 * 实现抽象主题角色
 * @author Administrator
 *
 */
public class ConcreteWatched implements BeWatched{
    //创建一个队列来存储一个或多个观察者
    private ArrayList<Watcher> al= new ArrayList<Watcher>();
    @Override
    public void addWatcher(Watcher watcher) {
        al.add(watcher);//添加观察者到指定队列中
    }
    @Override
    public void removeWatcher(Watcher watcher) {
        al.remove(watcher);//从队列中删除观察者
    }
    @Override
    public void notifyWatchers(String str) {
        //遍历队列
        for(int i=0;i<al.size();i++){
            Watcher watcher = al.get(i);//获取队列中的观察者对象
            watcher.update(str);//调用它的update()方法
        }
    }
}
/**
 * 具体的观察者角色:
 * 实现抽象观察者角色
 * @author Administrator
 *
 */
public class ConcreteWatcher implements Watcher{
    @Override
    public void update(String str) {
        System.out.println("已经收到通知:"+str);
    }

}
/**
 * 测试类
 * @author Administrator
 *
 */
public class ClientTest {
    public static void main(String[] args){
        //创建被观察者对象
        ConcreteWatched watched = new ConcreteWatched();
        //创建观察者
        ConcreteWatcher watcher1 = new ConcreteWatcher();
        ConcreteWatcher watcher2 = new ConcreteWatcher();
        ConcreteWatcher watcher3 = new ConcreteWatcher();
        //添加多个观察者
        watched.addWatcher(watcher1);
        watched.addWatcher(watcher2);
        watched.addWatcher(watcher3);
        //通知观察者
        watched.notifyWatchers("你好!");
        //分割
        System.out.println("--------------------------------");
        //删除一个观察者
        watched.removeWatcher(watcher1);
        //再次通知观察者
        watched.notifyWatchers("很好!");

    }
}

结果:

已经收到通知:你好!
已经收到通知:你好!
已经收到通知:你好!
--------------------------------
已经收到通知:很好!
已经收到通知:很好!

三 对于java中的观察者模式

java中的内置观察者模式有两个类:一个是observable被观察者类,一个是observer观察者接口。大体上与自定义模式相同,我们编写程序时只需继承obervable类,具体实现observer接口就可以了。
值得注意的是:调用notifyObservers()方法之前,必须先调用setChanged()方法。这是因为observable类中把changed变量初始化为false,notifyObservers()方法会先检查该变量是否为true,如果不为ture,就不会调用update()方法,这就要我们调用notifyObservers()之前,先用setChanged()方法将changed变量设置为true。

import java.util.Observable;
import java.util.Observer;

class Observe extends Observable {
    // 程序的入口
    public static void main(String args[]) {
        Observe watched = new Observe();// 创建被观察对象
        FirstObserver watch = new FirstObserver();// 创建观察者对象(可以创建多个)
        watched.addObserver(watch);
        watched.toWatchers("你好!");
    }

    // 通知观察者的方法
    public void toWatchers(String str) {
            this.setChanged();// 被观察者发生变化,把changed设置为true
            this.notifyObservers(str);// 通知观察者
        }
}

class FirstObserver implements Observer {
    // 重写更新方法
    public void update(Observable o, Object arg) {
        System.out.println("被观察者发生变化,观察者已收到通知:"+arg);
    }
}

结果:

被观察者发生变化,观察者已收到通知:你好!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值