美文网首页
观察者模式 一

观察者模式 一

作者: zjxchase | 来源:发表于2020-03-21 22:37 被阅读0次

简单实例

首先看一个警察蹲点抓小偷的简单实例:警察蹲点观察到小偷偷东西就立即抓捕

Policemen.Java (警察)

public class Policemen implements Observer {

    /**
     * 警察姓名
     */
    private String name;

    public Policemen(String name) {
        this.name = name;
    }

    @Override
    public void update(Observable o, Object arg) {
        Pickpocket pickpocket = (Pickpocket) o;

        System.out.printf("警察 %s 发现(实际是被通知)扒手 %s 盗取了 %s,立即抓捕 \n", this.name, pickpocket.getName(), arg);
    }
}

Pickpocket.java (扒手)

public class Pickpocket extends Observable {

    /**
     * 小偷姓名
     */
    private String name;

    /**
     * 赃物
     */
    private List<String> booties = new ArrayList<>();

    public Pickpocket(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    /**
     * 偷窃
     * @param booty
     */
    public void steal(String booty) {
        booties.add(booty);

        setChanged();
        notifyObservers(booties);
    }
}

ObserverEx1Test.java (测试类)

public class ObserverEx1Test {

    public static void main(String[] args) {
        Policemen p1 = new Policemen("警察A");
        Policemen p2 = new Policemen("警察B");
        Pickpocket pp1 = new Pickpocket("郭某");

        pp1.addObserver(p1);
        pp1.addObserver(p2);

        pp1.steal("cellphone");
    }
}

运行ObserverEx1Test类输出结果:

警察 警察B 发现(实际是被通知)郭某 盗取了 [cellphone] ,立即抓捕
警察 警察A 发现(实际是被通知)郭某 盗取了 [cellphone] ,立即抓捕

上边这种例子观察者模式叫:发布-订阅模式

观察者模式介绍

定义

观察者模式(又被称为发布-订阅(Publish/Subscribe)模式,属于行为型模式的一种,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态变化时,会通知所有的观察者对象,使他们能够自动更新自己。

意图

定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

解决的问题

一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知的问题,而且要考虑到易用和低耦合,保证高度的协作。

优点

  • 降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系。
  • 目标与观察者之间建立了一套触发机制。

缺点

  • 目标与观察者之间的依赖关系并没有完全解除,而且有可能出现循环引用。
  • 当观察者对象很多时,通知的发布会花费很多时间,影响程序的效率。

使用场景

  • 一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。
  • 一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度。
  • 一个对象必须通知其他对象,而并不知道这些对象是谁。
  • 需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制。

简单实例 二

由于java.util.Observable 和 java.util.Observer 类在java9 之后过期了,该实例主要是不再继承java.util.Observable 和 java.util.Observer 实现观察者模式

IObserver.java 接口

public interface IObserver {

    /**
     * 观察者获得消息
     * @param msg
     */
    void update(String msg);
}

ISubject.java 接口

public interface ISubject {

    /**
     * 注册观察者
     * @param observer
     */
    void registerObserver(IObserver observer);

    /**
     * 取消观察者
     * @param observer
     */
    void removeObserver(IObserver observer);

    /**
     * 通知观察者
     */
    void notifyObserver();

    /**
     * 获取主体标示名称
     * @return
     */
    String getName();

}

Pickpocket.java

public class Pickpocket implements ISubject {

    /**
     * 小偷姓名
     */
    private String name;

    /**
     * 赃物
     */
    private String booty;

    /**
     * 观察者集合
     */
    private List<IObserver> observers = new ArrayList<>();

    public Pickpocket(String name) {
        this.name = name;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public void registerObserver(IObserver observer) {
        observers.add(observer);
    }

    @Override
    public void removeObserver(IObserver observer) {
        if (observers.contains(observer)) {
            observers.remove(observer);
        }
    }

    @Override
    public void notifyObserver() {
        for (IObserver observer : observers) {
            observer.update(booty);
        }
    }

    /**
     * 盗取赃物后给观察者(警察)发送消息
     * @param booty
     */
    public void steal(String booty) {
        this.booty = booty;
        // 通知观察者
        notifyObserver();
    }

}

Policemen.java

public class Policemen implements IObserver {

    /**
     * 警察姓名
     */
    private String name;

    /**
     * 增具体的观察者订阅的主体
     */
    private ISubject subject;

    public Policemen(String name, ISubject subject) {
        this.name = name;
        this.subject = subject;
        subject.registerObserver(this);
    }

    @Override
    public void update(String booty) {

        System.out.printf("警察 %s 发现(实际是被通知)%s 盗取了 %s ,立即抓捕\n", this.name, subject.getName(), booty);
    }
}

ObserverEx1Test.java

public class ObserverEx1Test {

    public static void main(String[] args) {
        Pickpocket pp = new Pickpocket("Pickpocket-A");

        Policemen p1 = new Policemen("Policemen-A", pp);
        Policemen p2 = new Policemen("Policemen-B", pp);

        pp.steal("手机");

        System.out.println("------------------------");
        pp.removeObserver(p2);
        pp.steal("PAD");
    }
}

执行结果:

警察 Policemen-A 发现(实际是被通知)Pickpocket-A 盗取了 手机 ,立即抓捕
警察 Policemen-B 发现(实际是被通知)Pickpocket-A 盗取了 手机 ,立即抓捕
------------------------
警察 Policemen-A 发现(实际是被通知)Pickpocket-A 盗取了 PAD ,立即抓捕

相关文章

  • 11.9设计模式-观察者模式-详解

    设计模式-观察者模式 观察者模式详解 观察者模式在android中的实际运用 1.观察者模式详解 2.观察者模式在...

  • RxJava 原理篇

    一、框架思想 观察者模式观察者自下而上注入被观察者被观察者自上而下发射事件观察者模式 装饰器模式自上而下,被观察者...

  • RxJava(二)

    一、观察者模式 1.1、传统的观察者模式 1.2、RxJava 的观察者模式 区别传统的观察者模式是一个 Obse...

  • RxJava基础—观察者模式

    设计模式-观察者模式 观察者模式:观察者模式(有时又被称为发布(publish )-订阅(Subscribe)模式...

  • 第5章 -行为型模式-观察者模式

    一、观察者模式的简介 二、观察者模式的优缺点 三、观察者模式的实例

  • 观察者模式(C++实现)

    一、什么是观察者模式 1.1观察者模式的概念 观察者模式(observer pattern)是一种对象行为模式。...

  • 前端面试考点之手写系列

    1、观察者模式 观察者模式(基于发布订阅模式) 有观察者,也有被观察者。 观察者需要放到被观察者列表中,被观察者的...

  • 学习 Vue 中观察者模式

    贴一个 Vue 中源码的观察者模式源码 手动实现观察者模式 观察者模式和订阅发布模式的区别 观察者模式是由具体的目...

  • 【设计模式】之观察者模式

    观察者模式 什么是观察者模式 观察者模式属于行为模式的一种,定义了对象的通用交流方式。 观察者模式定义了一对多的关...

  • 观察者设计模式

    每周学点Java设计模式__观察者设计模式 本次继续更新java23中设计模式之一——观察者模式。 观察者模式(有...

网友评论

      本文标题:观察者模式 一

      本文链接:https://www.haomeiwen.com/subject/lkfeyhtx.html