zoukankan      html  css  js  c++  java
  • Android设计模式—观察者模式

    装载请标明出处:https://www.cnblogs.com/tangZH/p/11175120.html 

    更多精彩文章: http://77blogs.com/?p=279

    观察者模式

    说白了,就是一个对发生改变,所有依赖于它的对象也发生改变,这是一对多的关系。

    比如对象A,对象B,对象C。B与C依赖于A,那么A发生改变,B与C也将发生改变。此时A是被观察者,B与C是观察者。

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

    UML图:

     角色说明:

    Subject(抽象主题):被观察者的一个抽象类,它会把所有观察者的引用保存在一个集合里。抽象主题提供一个接口,可以增加和删除观察者对象。

    ConcreteSubject(具体主题):具体的被观察者。当具体被观察者的状态发生改变的时候,会给每一个注册过的观察者发送通知。

    Observer(抽象观察者):所有具体观察者的一个抽象类,为所有的具体观察者定义了一个接口:得到主题的通知时候更新自己。

    ConcrereObserver(具体观察者):抽象观察者的具体实现。

    我们看一下具体的例子:

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

    1、定义一个抽象主题:

        该抽象主题定义了一些通用的方法,即具体主题里面需要实现的。

    //抽象被观察者
    public interface Observable {
        //添加观察者
        void addObserver(Observer observer);
    
        //移除观察者
        void deleteObserver(Observer observer);
    
        //通知观察者
        void notifyObserver(String msg);
    }

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

    public class AlarmClock implements Observable {
        //保存观察者对象
        List<Observer> list = new ArrayList<>();
    
        @Override
        public void addObserver(Observer observer) {
            list.add(observer);
        }
    
        @Override
        public void deleteObserver(Observer observer) {
            list.remove(observer);
        }
    
        /**
         * 通知观察者
         * @param msg
         */
        @Override
        public void notifyObserver(String msg) {
            for (Observer observer : list) {
                observer.action(msg);
            }
        }
    }

    3、创建抽象观察者:

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

    //抽象观察者
    public interface Observer {
        void action(String msg);
    }

    4、创建具体观察者:

    public class Students implements Observer {
    
        String name;
    
        public Students(String name) {
            this.name = name;
        }
    
        @Override
        public void action(String msg) {
            System.out.println(msg + name + "开始听课");
        }
    }
    public class Teacher implements Observer {
        @Override
        public void action(String msg) {
            System.out.print(msg + "老师开始讲课");
        }
    }

    6、实现:

    Observable alarmClock = new AlarmClock();
    
    Observer student1 = new Students("小屁孩");
    Observer student2 = new Students("大屁孩");
    Observer teacher = new Teacher();
    
    //注册观察者
    alarmClock.addObserver(student1);
    alarmClock.addObserver(student2);
    alarmClock.addObserver(teacher);
    
    //被观察者通知已经注册的观察者
    alarmClock.notifyObserver("上课铃声已经响了");

    7、结果:

    到这里我们便实现了观察者模式。

    应用场景

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

    优点

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

     缺点

    • 依赖关系并未完全解除,抽象主题仍然依赖抽象观察者。
    • 使用观察者模式时需要考虑一下开发效率和运行效率的问题,程序中包括一个被观察者、多个观察者,开发、调试等内容会比较复杂,而且在Java中消息的通知一般是顺序执行,那么一个观察者卡顿,会影响整体的执行效率,在这种情况下,一般会采用异步实现。
    • 可能会引起多余的数据通知。

    JDK内部也内置了Observable(抽象被观察者),Observer(抽象观察者)这两个类,我们也可以直接拿来用,具体可以去看看源码。
     
    Android中有很多地方也用到了观察者模式:
    • 点击事件
    • listView的刷新
    • 广播等等
     
  • 相关阅读:
    html、css、js文件加载顺序及执行情况
    python之路_前端基础之jQuery入门3
    python之路_前端基础之jQuery入门2
    python之路_前端基础之jQuery入门1
    python之路_前端基础之JS5
    python之路_前端基础之JS4
    python之路_前端基础之CSS布局3
    python之路_前端基础之JS(3)
    python之路_前端基础之JS(2)
    python之路_前端基础之JS(1)
  • 原文地址:https://www.cnblogs.com/tangZH/p/11175120.html
Copyright © 2011-2022 走看看