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

一、什么是观察者模式

 

  •     定义:属于行为模式的一种,定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态变化时,会通知所有的观察者对象,使他们能够自动更新自己。

 

  •     观察者模式结构图

 

 

 

  •     模式中的角色

    

            抽象主题:把所有的观察者对象的引用保存到一个聚集里,每个主题都可以有任意数量的观察者。抽象主题提供一个接口,可以增加和删除观察者。

            具体主题:将有关状态存入具体的观察者对象中。在具体主题内部状态改变时,给所有登记过的观察者发出通知。

            抽象观察者:为所有的具体观察者提供一个接口,在得到主题通知时更新自己。

            具体观察者:实现抽象观察者角色所需要的更新接口,以便使本身的状态和主题状态相协调。

 

         

 

 

二、为什么用观察者模式

 

        使用场景:

  • 关联行为场景,需要注意的是,关联行为是可拆分的,而不是“组合“的关系

  • 事件多级触发场景

  • 跨系统的消息交换场景,如消息队列,事件总线的处理机制

 

        优点:

  •     解耦合,让耦合的双方都依赖与抽象,从而使得各自的变换都不会影响到另一边的变换                  

 

        缺点:

  •     在应用观察者模式时需要考虑一下开发效率和运行效率的问题,程序中包括一个被观察者、多个观察者,开发、调试等内容会比较复杂,而且Java中消息的通知一般是顺序执行的,那么一个观察者卡顿,会影响整体的执行效率。一般会采用异步实现。

 

 

三、怎样使用观察者模式(实际应用场景)

 

    模拟场景:

 

  • 主题(被观察者):ChickenStore炸鸡店

  • 观察者:Buyer买家

 

 

    楼下新开了一家炸鸡店,由于这家店炸鸡很好吃,所以经常出现卖断货的情况。买家屡屡去买的时候都是无货可买,只有等到下一锅炸鸡出炉的时候才能买,但是一锅炸鸡出炉又需要等待很长的时间。

 

    这样很浪费顾客的时间,为了解决让客户等待的问题,我们让每位要来买炸鸡的顾客留下联系方式,等到下一锅炸鸡要出炉的时候,通过短信/电话的方式通知买家,买家一旦接到通知,就作出响应的动作来买炸鸡。

 

 

    代码实现:

 

    1、抽象主题:Subject

package com.itszt.subject;



import com.itszt.observer.Observer;



import java.util.HashSet;

import java.util.Set;



/**

* Created by PanYangyi on 2018/5/31.

*

* 主题对象(被观察者)

*

* 抽象类

*

*/

public abstract class Subject {



    //1、主题对象注册观察者对象,放到一个集合中

    Set<Observer> observers = new HashSet();

    public void registObserver(Observer observer){

        observers.add(observer);

    }



    //2、数据发生变化时,通知观察者对象

    public void notifyObserver(Object data){

        for (Observer observer : observers) {

            observer.receiveNotify(data);

        }

    }



    //3、主题对象自己的业务方法

    public abstract void work();



}

 

    2、具体主题(炸鸡店)


 

package com.itszt.subject;



import com.itszt.subject.Subject;



/**

* Created by PanYangyi on 2018/5/31.

*/

public class ChickenStore extends Subject {



    @Override

    public void work() {

        new Thread(){

            int num = 0;

            @Override

            public void run(){

                while(true) {

                    num++;

                    try {

                        Thread.sleep(3000);

                    } catch (InterruptedException e) {

                        e.printStackTrace();

                    }

                    System.out.println("炸鸡第" + num + "锅出炉了!!!");

                    String data = "炸鸡第" + num + "锅炸好了,赶紧马不停蹄的过来买吧!!!";

                    System.out.println("--------------------------------------");



                    //通知观察者

                    notifyObserver(data);

                }

            }

        }.start();

    }

}

 

    3、抽象观察者:Observer

package com.itszt.observer;



import com.itszt.subject.Subject;



/**

* Created by PanYangyi on 2018/5/31.

*

* 观察者

*

* 抽象类

*/

public abstract class Observer {



    //1、观察者需要传入主题对象,这样才能知道观察者观察的是谁。

    //用构造器传参的方式

    private Subject subject;

    public Observer(Subject subject){

        this.subject = subject;

    }



    //2、观察者需要接受主题对象的通知

    public abstract void receiveNotify(Object data);





}

 

 

    4、具体观察者(买家)


 

package com.itszt.observer;



import com.itszt.subject.Subject;



/**

* Created by PanYangyi on 2018/5/31.

*/

public class Buyer extends Observer {

    public Buyer(Subject subject) {

        super(subject);

        //观察者一旦注册好,就需要将观察者注册到主题对象中

        subject.registObserver(this);

    }



    @Override

    public void receiveNotify(Object data) {

        System.out.println("buyer收到了一条短消息--->"+data);

        System.out.println("赶紧下楼打车去炸鸡店买炸鸡,顺道去一人民广场占座!!!");

        System.out.println("--------------------------------------------");

    }

}



    5、测试类

package com.itszt;



import com.itszt.observer.Buyer;

import com.itszt.observer.Observer;

import com.itszt.subject.ChickenStore;

import com.itszt.subject.Subject;



/**

* Created by PanYangyi on 2018/5/31.

*/

public class Test {

   public static void main(String[] args){

       //实例化一个主题对象

       Subject chickenStore = new ChickenStore();

       //实例化有个观察者对象

       Observer buyer = new Buyer(chickenStore);

       //主题对象开始工作

       chickenStore.work();

   }

}

  

 

    运行结果:

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值