观察者模式

来源:互联网 发布:网络侦探 丁香兽 编辑:程序博客网 时间:2024/06/05 17:11
  1. 观察者模式

    1. 观察者模式的介绍:

      说道观察者模式,让我想到了古代的一个例子,在战国时期,李斯是最强诸侯国的上尉,想一统诸国,因为知己知彼百战不殆,所以安间谍到各国的重要人物身边,获取信息并上报秦始皇。韩非子作为韩国的重量级人物,身边自然没少间谍了,韩非子早饭吃的什么,中午放了几个 P,晚上在做什么娱乐,李斯都了如指掌,那可是相隔千里!怎么做到的呢?间谍呀!

      对于观察者模式,我们就像秦始皇,通过李斯(观察者)来获取韩非子(被观察者)的信息

    2. 观察者模式的实现

    下边我们就从最原始的逐步优化实现观察者模式

     

      1. 首先创建李斯(观察者)

    观察者的职责就是根据被观察者的动作来作出相应的动作

     

    接口:

    publicinterface LiSiService {

        //一发现别人有动静,自己也要行动起来

        publicvoid update(String context);

    }

    实现类:

    publicclass LiSi implements LiSiService {

        //首先李斯是个观察者,一旦韩非子有活动,他就知道,他就要向老板汇报

        publicvoid update(String str){

            System.out.println("李斯:观察到韩非子活动,开始向老板汇报了...");

            this.reportToQiShiHuang(str);

            System.out.println("李斯:汇报完毕,秦老板赏给他两个萝卜吃吃...\n");

        }

         

        

        //汇报给秦始皇

        privatevoid reportToQiShiHuang(String reportContext){

            System.out.println("李斯:报告,秦老板!韩非子有活动了--->"+reportContext);

        }

    }

    1. 创建韩非子(被观察者)

    接口:

        publicinterface HanFeiZiService {

        //韩非子也是人,也要吃早饭的

        publicvoid haveBreakfast();

        //韩非之也是人,是人就要娱乐活动,至于活动时啥,嘿嘿,不说了

        publicvoid haveFun();

    }

    实现类:

        publicclass HanFeiZi implements HanFeiZiService{

        //把李斯声明出来

        private LiSiService liSi =new LiSi();

     

        //韩非子要吃饭了

        publicvoid haveBreakfast(){

            System.out.println("韩非子:开始吃饭了...");

            this.liSi.update("韩非子在吃饭");

        }

        //韩非子开始娱乐了,古代人没啥娱乐,你能想到的就那么多

        publicvoid haveFun(){

            System.out.println("韩非子:开始娱乐了...");

            this.liSi.update("韩非子在娱乐");

        }

    }

    1. 创建操控者(我们)

    publicclass Client {

        publicstaticvoid main(String[] args) throws InterruptedException {

            //定义出韩非子

            HanFeiZi hanFeiZi = new HanFeiZi();

            //然后这里我们看看韩非子在干什么

            hanFeiZi.haveBreakfast();

            //韩非子娱乐了

            hanFeiZi.haveFun();

        }

    }

    1. 运行结果:

    上边的方法,运行结果正确,效率也比较高,但是在被观察者中只有一个观察者,而且还是定死的,想想韩非子名望那么高,一定不会就一个人监视,那么每增加一个观察者我们就要修改增加大量的代码,所以我们可以让观察者实现一个通用的接口,被观察者实现一个通用的接口,并实现增加和删除观察者的方法,那么代码我们可以这么改。

     

    1. 创建观察者通用接口

    publicinterface Observer {

        //一发现别人有动静,自己也要行动起来

        publicvoid update(String context);

    }

    1. 创建具体的观察者实现观察者接口

    publicclass LiSi implements Observer {

        @Override

        publicvoid update(String str) {

            System.out.println("李斯:观察到李斯活动,开始向老板汇报了...");

            this.reportToQiShiHuang(str);

            System.out.println("李斯:汇报完毕,秦老板赏给他两个萝卜吃吃...\n");

        }

     

        // 汇报给秦始皇

        privatevoid reportToQiShiHuang(String reportContext) {

            System.out.println("李斯:报告,秦老板!韩非子有活动了--->" + reportContext);

        }

    }

     

    publicclass WangSi implements Observer {

     

        // 王斯,看到韩非子有活动,自己就受不了

        publicvoid update(String str) {

            System.out.println("王斯:观察到韩非子活动,自己也开始活动了...");

            this.cry(str);

            System.out.println("王斯:真真的哭死了...\n");

        }

     

        // 一看李斯有活动,就哭,痛哭

        privatevoid cry(String context) {

            System.out.println("王斯:因为" + context + "——所以我悲伤呀!");

        }

    }

    1. 创建被观察者通用接口

    publicinterface Observable {

        //增加一个观察者

        publicvoid addObserver(Observer observer);

        //删除一个观察者,——我不想让你看了

        publicvoid deleteObserver(Observer observer);

        //既然要观察,我发生改变了他也应该用所动作——通知观察者

        publicvoid notifyObservers(String context);

    }

    1. 创建具体的被观察者实现被观察者接口

    publicclass HanFeiZi implements Observable {

        // 定义个变长数组,存放所有的观察者

        private ArrayList<Observer> observerList = new ArrayList<Observer>();

     

        @Override

        publicvoid addObserver(Observer observer) {

            this.observerList.add(observer);

        }

     

        @Override

        publicvoid deleteObserver(Observer observer) {

            this.observerList.remove(observer);

        }

     

        @Override

        publicvoid notifyObservers(String context) {

            for (Observer observer : observerList) {

                observer.update(context);

            }

        }

     

        // 韩非子要吃饭了

        publicvoid haveBreakfast() {

            System.out.println("韩非子:开始吃饭了...");

            // 通知所有的观察者

            this.notifyObservers("韩非子在吃饭");

        }

     

        // 韩非子开始娱乐了,古代人没啥娱乐,你能想到的就那么多

        publicvoid haveFun() {

            System.out.println("韩非子:开始娱乐了...");

            this.notifyObservers("韩非子在娱乐");

        }

    }

     

    1. 创建操控者

      publicclass Clinet {

          publicstaticvoid main(String[] args) {

              //三个观察者产生出来

              Observer liSi = new LiSi();

              Observer wangSi = new WangSi();

              //定义出韩非子

              HanFeiZi hanFeiZi = new HanFeiZi();

              //我们后人根据历史,描述这个场景,有三个人在观察韩非子

              hanFeiZi.addObserver(liSi);

              hanFeiZi.addObserver(wangSi);

              

              //然后这里我们看看韩非子在干什么

              hanFeiZi.haveBreakfast();

          }

    }

    因为JDK的api已经给出现成的接口,所以我们的程序可以这样的简化

    1. 观察者

    import java.util.Observable;

    publicclass HanFeiZi extends Observable {

        

        //韩非子要吃饭了

        publicvoid haveBreakfast(){

        System.out.println("韩非子:开始吃饭了...");

        //通知所有的观察者

        super.setChanged();

        super.notifyObservers("韩非子在吃饭");

        }

        //韩非子开始娱乐了,古代人没啥娱乐,你能想到的就那么多

        publicvoid haveFun(){

        System.out.println("韩非子:开始娱乐了...");

        super.setChanged();

        this.notifyObservers("韩非子在娱乐");

        }

    }

    1. 被观察者

    import java.util.Observer;

    publicclass LiSi implements Observer {

        //首先李斯是个观察者,一旦韩非子有活动,他就知道,他就要向老板汇报

        publicvoid update(Observable observable,Object obj){

        System.out.println("李斯:观察到李斯活动,开始向老板汇报了...");

        this.reportToQiShiHuang(obj.toString());

        System.out.println("李斯:汇报完毕,秦老板赏给他两个萝卜吃吃...\n");

        }

        //汇报给秦始皇

        privatevoid reportToQiShiHuang(String reportContext){

        System.out.println("李斯:报告,秦老板!韩非子有活动了--->"+reportContext);

        }

    }

    import java.util.Observer;

    publicclass WangSi implements Observer {

        //王斯,看到韩非子有活动,自己就受不了

        publicvoid update(Observable observable,Object obj){

        System.out.println("王斯:观察到韩非子活动,自己也开始活动了...");

        this.cry(obj.toString());

        System.out.println("王斯:真真的哭死了...\n");

        }

        //一看李斯有活动,就哭,痛哭

        privatevoid cry(String context){

        System.out.println("王斯:因为"+context+"——所以我悲伤呀!");

        }

    }

    1. 操控者

        publicstaticvoid main(String[] args) {

            Observer liSi = new LiSi();

            Observer wangSi = new WangSi();

            //定义出韩非子

            HanFeiZi hanFeiZi = new HanFeiZi();

            //我们后人根据历史,描述这个场景,有三个人在观察韩非子

            hanFeiZi.addObserver(liSi);

            hanFeiZi.addObserver(wangSi);

            //然后这里我们看看韩非子在干什么

            hanFeiZi.haveBreakfast();

        }

    这样我们是不是又简化方法了