学校放学铃声响了...3分钟理解【观察者模式】

描述

观察者模式定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新,也称发布-订阅(Publish/Subscribe)模式,这是一种行为型模式(Behavioral),主要用于描述类或对象怎样交互以及怎样分配职责。观察者模式中通常包括观察目标和观察者两个继承层次结构,可实现观察者和目标之间的抽象耦合,同时实现了对象之间的动态联动。

文字太抽象?可以先不管,直接往下看案例,回过头来再看定义,就很简单了:

场景举例

通过学校放学打铃,所有在校人员听到后,做出反应,可以比较形象的理解观察者模式,如下图:

观察者模式在类设计的时候会用到四个内容:

代码案例

案例源码

https://gitee.com/sujianfeng/design-pattern

被观察者抽象类:学校铃声

public abstract class AbstractSchoolBell {
    /**
     * 增加观察者
     * @param schoolPerson 入校人员
     */
    abstract void attach(AbstractSchoolPerson schoolPerson);
    /**
     * 剔除观察者
     * @param schoolPerson 离校人员
     */
    abstract void detach(AbstractSchoolPerson schoolPerson);
    /**
     * 广播通知(铃声)
     */
    abstract void notifyBell();

}

被观察者:放学铃声

public class LeveSchoolBell extends AbstractSchoolBell {

    private List<AbstractSchoolPerson> schoolPersonList = new ArrayList<>();

    @Override
    public void attach(AbstractSchoolPerson schoolPerson) {
        schoolPersonList.add(schoolPerson);
    }

    @Override
    public void detach(AbstractSchoolPerson schoolPerson) {
        schoolPersonList.remove(schoolPerson);
    }

    @Override
    public void notifyBell() {
        //广播通知所有在校人员
        for (AbstractSchoolPerson schoolPerson : schoolPersonList){
            schoolPerson.listenBell(this);
        }
    }
}

观察者抽象类:在校人员

public abstract class AbstractSchoolPerson {
    /**
     * 监听铃声
     */
    abstract void listenBell(AbstractSchoolBell abstractSchoolBell);
}

观察者:学生

public class Student extends AbstractSchoolPerson {
    @Override
    public void listenBell(AbstractSchoolBell schoolBell) {
        System.out.println("收拾书包!");
    }
}

观察者:老师

public class Teacher extends AbstractSchoolPerson {
    @Override
    public void listenBell(AbstractSchoolBell schoolBell) {
        System.out.println("收拾教案!");
    }
}

观察者:门卫

public class Guard extends AbstractSchoolPerson {
    @Override
    public void listenBell(AbstractSchoolBell schoolBell) {
        System.out.println("打开学校大门!");
    }
}

单元测试

public class ObserverTest {

    @Test
    public void test(){
        //放学铃声
        LeveSchoolBell leveSchoolBell = new LeveSchoolBell();
        //学生
        Student student = new Student();
        //老师
        Teacher teacher = new Teacher();
        //门卫
        Guard guard = new Guard();
        //学校人员
        leveSchoolBell.attach(student);
        leveSchoolBell.attach(teacher);
        leveSchoolBell.attach(guard);
        //下课铃声响了
        leveSchoolBell.notifyBell();
    }
}

Java自带的观察者模式

在java.util包中包含有基本的Observer接口和Observable抽象类.功能上和SchoolBell 接口和SchoolPerson 接口类似.不过在使用上,就方便多了,因为许多功能比如说注册,删除,通知观察者的那些功能已经内置好了。使用javaAPI的观察者模式需要明白这么几件事情:

如何使对象变为观察者?

实现观察者接口(java.util.Observer),然后调用Observable对象的addObserver()方法.不想再当观察者时,调用deleteObserver()就可以了.

被观察者(主题)如何发出通知?

第一步:先调用setChanged()方法,标识状态已经改变的事实.

第二步:调用notifyObservers()方法或者notifyObservers(Object arg),这就牵扯到推(push)和拉(pull)的方式传送数据.如果想用push的方式"推"数据给观察者,可以把数据当做数据对象传送给notifyObservers(Object arg)方法,其中的arg可以为任意对象,意思是你可以将任意对象传送给每一个观察者.如果调用不带参数的notifyObserver()方法,则意味着你要使用pull的方式去主题对象中"拉"来所需要的数据.

观察者如何接收通知?

观察者只需要实现一个update(Observable o,Object arg)方法,第一个参数o,是指定通知是由哪个主题下达的,第二个参数arg就是上面notifyObserver(Object arg)里传入的数据,如果不传该值,arg为null.

思考

观察者模式的意义是什么?观察者模式比较简单,大家理解后,就可以很轻松的回答这个问题,这里就不写了,留给大家自己总结。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值