设计模式——观察者模式

一 简介

观察者模式

说白了,就是一个对发生改变,所有依赖于它的对象也发生改变,这是一对多的关系。
比如对象A,对象B,对象C。B与C依赖于A,那么A发生改变,B与C也将发生改变。此时A是被观察者,B与C是观察者。

观察者模式又被称作发布/订阅模式,主要是为了让观察者与被观察者之间进行解耦。

二 UML图

在这里插入图片描述
角色说明:

  1. Subject(抽象主题):被观察者的一个抽象类,它会把所有观察者的引用保存在一个集合里。抽象主题提供一个接口,可以增加和删除观察者对象。
  2. ConcreteSubject(具体主题):具体的被观察者。当具体被观察者的状态发生改变的时候,会给每一个注册过的观察者发送通知。
  3. Observer(抽象观察者):所有具体观察者的一个抽象类,为所有的具体观察者定义了一个接口:得到主题的通知时候更新自己。
  4. ConcrereObserver(具体观察者):抽象观察者的具体实现。

三 代码实例

3.1 背景

上课铃声响起时候,老师与学生们的不同反应。

3.2 定义一个抽象主题

该抽象主题定义了一些通用的方法,即具体主题里面需要实现的。
    //抽象被观察者
interface  Observable {

    fun addObserver(observer:Observer)
    fun deleteObserver(observer:Observer)
    fun notifyObserver(msg:String)
}

3.2、创建一个具体主题(上课铃声)

class AlarmClock : Observable {

    var list = ArrayList<Observer>()

    override fun addObserver(observer: Observer) {
        list.add(observer)
    }

    override fun deleteObserver(observer: Observer) {
        list.remove(observer)
    }

    override fun notifyObserver(msg: String) {
        for(observer in list){
            observer.runaction(msg)
        }
    }

}

3.3、创建抽象观察者

定义了所有具体观察者需要实现的方法,听到铃声后的行为//抽象观察者

interface Observer {
    var name:String
    fun runaction(msg:String)
}

3.4 创建具体观察者

class Students(override var name: String) : Observer {

    override fun runaction(msg: String) {
        System.out.println(msg + name + "开始听课");
        Log.d("jack",msg + name + "开始听课")
    }


class Teachers(override var name: String) : Observer {
    override fun runaction(msg: String) {
        Log.d("jack",msg +name+ "老师开始讲课")
    }
}

3.5 实现

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)


        val alarmClock: Observable = AlarmClock()

        val student1: Observer = Students("小屁孩")
        val student2: Observer = Students("大屁孩")
        val teacher: Observer = Teachers("十佳教师")

        //注册观察者
        //注册观察者
        alarmClock.addObserver(student1)
        alarmClock.addObserver(student2)
        alarmClock.addObserver(teacher)

        //被观察者通知已经注册的观察者
        //被观察者通知已经注册的观察者
        alarmClock.notifyObserver("上课铃声已经响了")


    }

3.6 结果

 D/jack: 上课铃声已经响了小屁孩开始听课
 D/jack: 上课铃声已经响了大屁孩开始听课
 D/jack: 上课铃声已经响了十佳教师老师开始讲课

四 应用场景

  1. 当一个对象的改变需要通知其它对象改变时,而且它不知道具体有多少个对象有待改变时。
  2. 当一个对象必须通知其它对象,而它又不能假定其它对象是谁
  3. 跨系统的消息交换场景,如消息队列、事件总线的处理机制。

优点

  1. 解除观察者与主题之间的耦合。让耦合的双方都依赖于抽象,而不是依赖具体。从而使得各自的变化都不会影响另一边的变化。
  2. 易于扩展,对同一主题新增观察者时无需修改原有代码。

缺点

  1. 依赖关系并未完全解除,抽象主题仍然依赖抽象观察者。

  2. 使用观察者模式时需要考虑一下开发效率和运行效率的问题,程序中包括一个被观察者、多个观察者,开发、调试等内容会比较复杂,而且在Java中消息的通知一般是顺序执行,那么一个观察者卡顿,会影响整体的执行效率,在这种情况下,一般会采用异步实现。

  3. 可能会引起多余的数据通知。

五 android源码应用

  1. 点击事件

  2. listView的刷新

  3. 广播等等

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值