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

    #设计模式--观察者模式

    概念

    • 形象化概念:你订阅了报纸!之后只要有新的报纸!报社都会发给你!让你及时收到报纸!这里的 报社 就是主题, 就是订阅者!当然  也可以取消订阅这个行为
    • 抽象化定义:定义了一系列类之间一对多的依赖!这样当该类改变或者更新的时候 他的所有的依赖都会更新改变!!

    现在我用一张图来描述一下观察者模式
    图

    (画的丑陋!见谅见谅!如果大家有好的工具给你推荐一下!Mac下的)

    ===

    具体实现

    自己做

    从上一节我们中我们讲到,观察者模式中有两个单位:一个是主题(可被订阅的),另外一个是订阅者。在主题中可以增加订阅者,取消订阅者还有一个就是通知订阅者。那么在订阅者中只有一个那就是更新。说到这里了!那么大家请看一下我的类图吧!
    类图
    (同样是画的不好!大家将就这看啊!!嘿嘿)

    从图中大家可以看出,我定义了两个接口来分别表示主题和订阅者。当用户使用的时候 只需要分别继承这两个接口来实现相应的主题和订阅者就可以了现在我直接上代码
    两个接口定义
    主题

    public interface Subject {
    void addObserver(Observer observer);
    void removeObserver(Observer observer);
    void notificatedObserver(Subject arg);
    void notificatedObserver();
    }

    订阅者

    public interface Observer {
    void update();
    void update(Subject subject);
    }

    主题类的实现

    public class MySubject implements Subject {
    private List<Observer> observerList;
    private String name;
    private int age;
    
    public void setName(String name) {
        this.name = name;
    }
    
    public void setAge(int age) {
        this.age = age;
    }
    
    public String getName() {
        return name;
    }
    
    public int getAge() {
        return age;
    }
    
    public MySubject() {
        observerList=new ArrayList<Observer>();
    }
    
    @Override
    public void addObserver(Observer observer) {
             observerList.add(observer);
    }
    
    @Override
    public void removeObserver(Observer observer) {
          observerList.remove(observer);
    }
    
    @Override
    public void notificatedObserver(Subject arg) {
       synchronized (this){
           int size=observerList.size();
           for (int i=0;i<size;i++){
               observerList.get(i).update(arg);
           }
       }
    }
    
    @Override
    public void notificatedObserver() {
        synchronized (this){
            int size=observerList.size();
            for (int i=0;i<size;i++){
                observerList.get(i).update();
            }
        }
    }
    
    public void send(){
        notificatedObserver(this);
    }
    }

    大家从这个类中可以看到我定义了订阅者集合 这个集合就是用删除和添加订阅者的容器。当用户调用主题的 send()方法的时候就会通知所有的订阅者来更新信息。这里通知的时候我把主题本身也传给了订阅者了!这样做的原因是:一个订阅者可以订阅好多个主题!传递过去是为了让订阅者知道是谁(主题)发送过来的信息。从而做出相依的动作!当让这里用户也可以不定义 send() 方法!直接在 setName() 和setAge() 中通知订阅者(即调用notificatedObserver(Subject arg) 这个方法)!

    好了现在我么来看一下订阅者是如何实现的

    public class MyObserver implements Observer {
    private Subject subject;
    
    public MyObserver(Subject subject) {
        this.subject = subject;
        this.subject.addObserver(this);
    }
    
    @Override
    public void update() {
    
    }
    
    @Override
    public void update(Subject subject) {
        if (subject instanceof MySubject){
            MySubject my= (MySubject) subject;
            System.out.printf("姓名:"+my.getName()+"年龄:"+my.getAge());
        }
    }
    }

    在这里的 update(Subject subject) 方法中就对主题做了相依的判断,从而实现处理多个不同主题的需求!

    好了至此,就差不多了!那么现在让我来运行他们吧!

    public class Main  extends Observable{
    
    public static void main(String[] args) {
        MySubject mySubject=new MySubject();
        mySubject.setName("LikeAndroid");
        mySubject.setAge(23);
        MyObserver observer=new MyObserver(mySubject);
        mySubject.send();
    }
    } 

    结果:
    结果

    Java中自带的

    说完了自定义的观察者!那么我们现在来看那看 java 中自带的吧!Observer 订阅者和Observable被订阅者!java自带的与我们的区别就是 Observable 是类,不是接口!我认为这样存在一个问题就是:java中只能继承一个类不能同时继承多个类!还有个问题当你注备通知订阅者时候,你得先调用 setChanged() 至于为什么?请去看源码吧!这个我就用代码展现了!很简单!!

    还有些细节

    在观察者模式中其实还存在两种方式:拉和推。那这两种是什么意思呢?请听我慢慢到来!!1

    • 推:主题一股脑儿的把所有的数据全部通知到订阅者哪儿!他不管订阅者需不需要这个信息!这种做法不怎么可取!原因是不同的订阅者需要不同的消息!他们应该根据自己的需求来获取!这就我下面说的了。
    • 拉:订阅者从主题那儿自己获取自己想要的信息!主题只是通知订阅者我这儿有信息来了啊!要的话自己来拿啊!!这样做的话,就比较人性化了!!

    如果你要问怎么实现的?我在 自己做 这一节中的代码中已经写出啦!还不明白的童鞋!请再去看一下吧!!!

    ====

  • 相关阅读:
    学习Jammendo代码的心路历程(二)ViewFlipper数据的填充
    学习Jammendo代码的心路历程(一)简单的淡出效果实现
    面向对象的一小步:添加ActiveRecord的Scope功能
    关于token和refresh token
    一个极为简单的方法实现本地(离线)yum安装rpm包
    Yii2基本概念之——生命周期(LifeCycle)
    一篇文章说透Nginx的rewrite模块
    PHP Session 常用的函数
    Session 的原理及最佳实践
    Yii2基本概念之——配置(Configurations)
  • 原文地址:https://www.cnblogs.com/laughingQing/p/4568124.html
Copyright © 2011-2022 走看看