黑马程序员技术交流社区

标题: 【大武汉校区】Android中常见通知机制之_观察者设计模式 [打印本页]

作者: 曹老师    时间: 2017-7-20 22:44
标题: 【大武汉校区】Android中常见通知机制之_观察者设计模式
本帖最后由 武汉-就业部 于 2017-7-28 10:00 编辑

Android 中通知机制之_观察者设计模式

Android 中常用的通知机制有哪些?
1.        接口回调                                 一对一
2.        handler机制                           一对一
3.        广播                                       一对多
4.        观察者设计模式                      一对多
5.        第三方 --> EventBus              一对多


什么是观察者设计模式?
        当一个对象发生变化时,其它依赖该对象的对象都会收到通知,并且随着变化。
对象之间是一种一对多的关系。
      顾名思义,它需要两个角色. 一个是观察者,一个是被观察者. 其中观察者订阅消息,被观察者发送消息.观察者接受消息.

Java 中观察者设计模式:
class Observable   -->  被观察者  -->  发布消息
   常用方法:     addObserver(Observer)  添加观察者到观察者集合中                                            deleteObserver(Observer)  从观察者集合中移除观察者
                      setChanged( )  标记消息已经发生改变
                      notifyObservers( )  通知所有的观察者消息已经发生改变

interface Observer  -->  观察者   -->订阅消息
   常用方法:   update( )   接收被观察者发出的消息

案列代码演示:

    1. 定义被观察者,当消息改变时候, 通知观察者
        public class Boss extends Observable{
         /**
           * 模拟发布消息
         */
         public String  message;
         public void publishMessage(String message) {
         //赋值
         this.message = message;
        //标记消息已经改变, 用的比较少,
         setChanged();
        //通知所有的观察者,消息已经发生改变
         notifyObservers();
    }
}
    2. 定义观察者,用来接受消息.
        public class Staff implements Observer{
         //有指令过来, 就会回调到这个方法
        @Override
        public void update(Observable o, Object arg) {
                // TODO Auto-generated method stub
                    Boss boss = (Boss) o;
                String message = boss.message;
                System.out.println(this.getClass().getSimpleName() + " 收到 " + message);
           }
        }
    3. 创建类Test 类测试:
        public class Test {
          public static void main(String[] args) {
                // TODO Auto-generated method stub
            Boss boss=new Boss();
            Staff staff=new Staff();
            boss.addObserver(staff);
            boss.publishMessage("这是老板发布的一条指令");
           }

  }

4. 运行Test , 输出日志消息:

   

观察者设计模式的原理:
就是使用一个集合,保存所有的观察者(接口对象),当有新的消息需要发布时,遍历集合,通知每个观察者对象官方.
观察者设计模式的弊端: 必须继承Observable和Observer类。这样的话,当我们的Activity或者Fragment想使用Java API来实现观察者模式时,就无法实现了。因此接下来, 我们来自定义观察者设计模式.

自定义观察者设计模式:
案例代码演示:
定义SalaryManger 管理 类
说明: 为了确保Salary 类只有一个实例,. 我们采用单例设计模式中的双重检查加锁模式保证它只有一个实例.
         public class SalaryManger {
         private static SalaryManger instance;
         private SalaryManger() {}
           public static SalaryManger getInstance() {
                //双重检查加锁机制
                if (instance == null) {
                    synchronized (SalaryManger.class) {
                        if (instance == null) {
                            instance = new SalaryManger();
                        }
                    }
                }
                return instance;
            }
              interface SalaryObserver{
                   void GetSalaryInfoChanged(int monkey);
        }      
        //定义集合保存 接口对象
        public List<SalaryObserver> observers = new ArrayList<>();   
        //常见方法-->添加观察者到观察者集合中
          public synchronized void addObserver(SalaryObserver o) {
               if (o == null)
                throw new NullPointerException();
              if (!observers.contains(o)) {
                observers.add(o);
              }
          }
        //常见方法-->从观察者集合中移除观察者
        public synchronized void deleteObserver(SalaryObserver o) {
            observers.remove(o);
        }
        //常见方法-->通知所有的观察者消息已经发生改变
        public void notifyObservers(int money) {
           // LogUtils.s("observers.size-->"+observers.size());
            for (SalaryObserver o : observers) {
                o.GetSalaryInfoChanged(money);
            }
        }

}


定义: 两个观察者类 StaffOne StaffTwo 实现观察者接口,重写方法
StaffOne 类
        public class StaffOne implements SalaryObserver{
        @Override
              public void GetSalaryInfoChanged(int monkey) {
                // TODO Auto-generated method stub
                System.out.println(StaffOne.class.getSimpleName()+"的薪水是"+monkey);
             }

    }


StaffTwo 类
        public class StaffTwo implements SalaryObserver{
             @Override
              public void GetSalaryInfoChanged(int monkey) {
                // TODO Auto-generated method stub
                System.out.println(StaffTwo.class.getSimpleName()+"的薪水是"+monkey);
              }
           }

定义测试类Boss
        public class Boss {
              public static void main(String[] args) {
                    SalaryManger msalary=new SalaryManger();
                    msalary.addObserver(new StaffOne());
                    msalary.addObserver(new StaffTwo());
                    msalary.notifyObservers(10000);
                }

     }

打印结果:



总结:

自定义一个观察者管理类, 在类中定义观察者接口, 以及声明几个必要的方法: 添加观察者,移除观察者, 通知所有观察者消息发生改变. 定义一个集合管理所有的观察者. 遵循的原理: 遍历集合,通知所有的观察者  一对多的关系. 为了保证单一实例子, 我们使用双重检查加锁的机制,保证观察者管理类在使用的时候只有一个实例.
其实,细心的人应该发现, 上述写法, 就类似于接口回调. 观察者实现了观察者接口的方法, 因此在消息发生改变后, 被通知, 再对应的实现方法中可以获取数据, 进行相应的操作.








作者: feiling    时间: 2017-7-21 07:07
继续加油!+1+1+1+1不错





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2