设计模式-观察者模式

消息队列(MQ),一种能实现生产者到消费者单向通信的通信模型,这也是现在常用的主流中间件。

常见有 RabbitMQ、ActiveMQ、Kafka等 他们的特点也有很多 比如 解偶、异步、广播、削峰 等等多种优势特点。

在设计模式中也有一种模式能有效的达到解偶、异步的特点,那就是观察者模式又称为发布订阅模式。

什么是观察者模式

观察者(Observer)模式的定义:指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。这种模式有时又称作发布-订阅模式、模型-视图模式,它是对象行为型模式。

观察者模式优点

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

观察者模式缺点

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

模式的结构

设计模式-观察者模式_第1张图片

  • 抽象主题(Subject)角:也叫抽象目标类,它提供了一个用于保存观察者对象的聚集类和增加、删除观察者对象的方法,以及通知所有观察者的抽象方法
  • 具体主题(Concrete Subject)角色:也叫具体目标类,它实现抽象目标中的通知方法,当具体主题的内部状态发生改变时,通知所有注册过的观察者对象
  • 抽象观察者(Observer):它是一个抽象类或接口,它包含了一个更新自己的抽象方法,当接到具体主题的更改通知时被调用
  • 具体观察者(Concrete Observer):实现抽象观察者中定义的抽象方法,以便在得到目标的更改通知时更新自身的状态

    怎么看都感觉还是有点抽象,我们用具体实例代码来走一遍,下面以朋友圈为例,当前个人作为订阅者,好友作为主题。一个人发一条动态朋友圈出去,他的好友都能看到这个朋友圈,并且可以在自主选择点赞或者评论。

    定义添加删除关系以及通知订阅者

    public interface Subject {
    	  // 添加订阅关系
        void attach(Observer observer);
        // 移除订阅关系
        void detach(Observer observer);
        // 通知订阅者
        void notifyObservers(String message);
    }
    

    其次再创建的具体主题,并且构建一个容器来维护订阅关系

    
    //具体目标
    class ConcreteSubject extends Subject {
        public void notifyObserver() {
    	        System.out.println("发生了改变");
    	        System.out.println("===============");
            for (Object obs : observers) {
                ((Observer) obs).response();
            }
        }
    }
    

    创建一个观察者接口,方便我们管理

    //抽象观察者
    interface Observer {
        void response(); //反应
    }
    

    最后就是创建具体的观察者类,实现观察者接口的response方法,处理本身的业务逻辑

    //具体观察者1
    class ConcreteObserver1 implements Observer {
        public void response() {
    	        System.out.println("观察者1接收到你的该改变了!");
        }
    }
    //具体观察者1
    class ConcreteObserver2 implements Observer {
        public void response() {
    	        System.out.println("观察者2接收到你的该改变了!");
        }
    }
    

    最后是测试结果

    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    	       Subject subject = new ConcreteSubject();
    	        Observer obs1 = new ConcreteObserver1();
    	        Observer obs2 = new ConcreteObserver2();
    	        subject.add(obs1);
    	        subject.add(obs2);
    	        subject.notifyObserver();
    	}
    
    
    
    发生了改变
    ===============
    观察者1接收到你的该改变了!
    观察者2接收到你的该改变了!
    

    应用场景

    • Spring 框架中有一个 ApplicationListener ,也是采用观察者模式来处理的,ApplicationEventMulticaster作为主题,里面有添加,删除,通知等
    • 熟悉 JDK 的人应该知道 在java.util 包下 除了常用的 集合 和map之外还有一个Observable类,他的实现方式其实就是观察者模式。里面也有添加、删除、通知等方法,这里需要注意是的它是用 Vector 作为订阅关系的容器,同时在他的定义方法中都添加 synchronized 关键字修饰类,以达到线程安全的目的
    • Google Guava的事件处理机制 Guava EventBus 他的实现也是采用设计模式中的观察者设计模式

    你可能感兴趣的:(java,观察者模式,中间件,java)