设计模式学习 - 观察者模式

观察者模式简介

定义

观察者模式是一种一对多的依赖关系,每当一个对象改变状态时,则所有依赖于它的对象都会得到通知并自动更新。
可以这样理解,一条绳上的蚂蚱,一荣俱荣,一损俱损,类似这样的感觉。

例子

近日,世界杯正在火热的进行中,幸好赛程不是在白天,大部分安排在夜间23点到2点间,避免了上班偷偷摸摸看世界杯,生怕被领导发现……可以熬夜也是一种痛苦啊……但NBA季后赛和总决赛就没有这么好了,好多赛程都在平时上班时间内进行,今年是火箭近些年最有希望夺冠的一年,当火箭在西部决赛拿到赛点的时候,感觉离冠军越来越近了,可是最终还是被勇士翻盘了;在这期间为了看比赛,上班总是在不断切换屏幕,怕领导突然进入办公室被发现,可就惨了。
由于跟前台的妹子平时聊的还比较好,事先跟前台妹子通通气了,如果领导来了,马上发震动消息通知下,我就好愉快的切换电脑屏幕,进入工作状态,哈哈……

上面的例子就是典型的观察者模式的样本,如果其他人也有同样的需求,那怎么办了?

  • 某某 先找到前台妹子
  • 再跟前台妹子通好气来,类似于注册登记
  • 等领导来了,就立马发消息通知大家
  • 大家收到消息后,马上切换屏幕,进入工作状态。

接下来使用观察者模式实现:

1、哪些同事需要无找前台妹子。

/**
 * 
 * @author 13480
 * 哪些同事需要去前台妹子那登记,这些人都有共同的特征,就是切换更新屏幕。
 * 
 */
public interface Colleague {
    /**
     * 更新切换屏幕
     * @param msg 收到前台妹子发来的消息内容
     */
    void updateScreen(String msg);
}

-------------------具体同事的名字-------------------

public class ITColleague implements Colleague{

    private String name;

    public ITColleague(String name) {
        super();
        this.name=name;
    }

    //收到消息后的动作
    @Override
    public void updateScreen(String msg) {
        System.out.println(name+"收到前台妹子发来的消息了,马上切换屏幕");
    }

}

2、先去前台找到妹子(Girl)


/**
 * 
 * @author 13480
 * 前台有很多妹子,但都有共同的特点,权利很大,有权选择通知谁,千万别随意得罪妹子哦
 * 有添加、删除、通知等权利。
 */
public interface Girl {

    /**
     * 在前台在登记的方法
     * @param observer 登记人的名字
     */
    void attach(Colleague observer);

    /**
     * 删除某人,不通知他
     * @param observer 被删除人的名字
     */
    void delete(Colleague observer);

    /**
     * 妹子给每位同事发消息
     * @param msg 消息的具体内容
     */
    void sendMessage(String msg);

}


-----------------------具体妹子的名字----------------
/**
 * 
 * @author 13480
 * 具体到哪一个妹子,选瑶瑶妹子吧,人比较漂亮。
 * 瑶瑶那有一张表,记录了所有登记过的同事名单,在代码上用集合保存
 */
public class YaoYaoGirl implements Girl{

    private List<Colleague> mList=new ArrayList<Colleague>();

    @Override
    public void attach(Colleague observer) {
        mList.add(observer);
    }

    @Override
    public void delete(Colleague observer) {
        mList.remove(observer);
    }

    @Override
    public void sendMessage(String msg) {
        for (int i = 0; i < mList.size(); i++) {
            Colleague colleague = mList.get(i);
            colleague.updateScreen(msg);
        }
    }

}

3、领导来,瑶瑶妹子发消息通知大家,收到的同事做动作

public class ObserverTest {

    public static void main(String[] args) {
        //找到前台瑶瑶妹子
        YaoYaoGirl yaoYaoGirl = new YaoYaoGirl();

        //具体需要通知的同事
        Colleague colleague1 = new ITColleague("牛哥");
        Colleague colleague2 = new ITColleague("凯帆");
        Colleague colleague3 = new ITColleague("华哥");

        //具体同事到瑶瑶妹子那登记
        yaoYaoGirl.attach(colleague1);
        yaoYaoGirl.attach(colleague2);
        yaoYaoGirl.attach(colleague3);

        //领导来了,瑶瑶妹子发震动消息
        yaoYaoGirl.sendMessage("领导来了");

    }

}

输出结果:

牛哥收到前台妹子发来的消息了,马上切换屏幕
凯帆收到前台妹子发来的消息了,马上切换屏幕
华哥收到前台妹子发来的消息了,马上切换屏幕

这就是整个观察者模式的实现,下面用UML类图体现上面的实现:

UML结构图

这里写图片描述

角色介绍:

  • Colleague:抽象观察者(Observer),定义了接口,定义了更新自己状态的方法。
  • ITColleague:具体观察者(ConcrereObserver),实现抽象观察者所有方法,收到被观察者发送的消息时更新自己的状态。
  • Girl:抽象被观察者(Subject),定义了接口,定义了增加、删除、发送消息方法。
  • YaoYaoGirl:具体被观察者(ConcrereSubject),实现抽象被观察者所有方法,同时用集合保存所有注册的具体观察者对象,最后发送消息通知具体观察者更新状态。

使用场景

优点及使用场景:

  • 降低了观察者与被观察者将耦合度,有利于业务扩展(类似ListView中notifyDataSetChanged),方便实现一套事件触发机制事件(类似于事件总线EventBus框架)。

缺点:

  • 由于观察者对象是用数组保存的,一般是按顺序执行,如果其中某个观察者对象出现卡顿,后面的将会受到影响。

猜你喜欢

转载自blog.csdn.net/hzw2017/article/details/80809348