初步理解设计模式——观察者模式

790 阅读2分钟

概念与介绍

定义

    多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,
所有依赖于它的对象都能得到通知并自动更新。
    观察者模式有时又称作发布-订阅模式,属于行为型模式。

应用场景

    一个对象的改变将导致其他一个或多个对象也发生改变,但是并不
知道这些对象是谁,也不知道有多少对象将发生改变。

应用举例

1.体育老师吹哨叫大家集合。
2.一声惊雷,外面突然乌云密布,眼看就要下雨,大伙连忙出去收衣服。
(这里,乌云就是一个观察目标,所有晾了衣服的人都是观察者。)

主要优点

1.降低了目标与观察者之间的耦合关系,让耦合的双方都依赖于抽象,
  而不是依赖于具体。从而使得各自的变化都不会影响另一边的变化。
2.目标与观察者之间建立了一套触发机制。

主要缺点

1.目标与观察者之间的依赖关系并没有完全解除(抽象目标与抽象观察者
  仍然存在耦合)。如果两者之间存在循环依赖的话,有可能出现因为循
  环引用而导致的系统崩溃。
2.当观察者对象很多时,将所有的观察者对象都通知到需要花费大量的
  时间。

结构与实现

一、模式的结构

classDiagram
抽象目标Subject <|-- 具体目标ConcreteSubject : Inheritance
抽象目标Subject o-- 抽象观察者Observer : Aggregation
具体观察者ConcreteObserver1 ..|> 抽象观察者Observer : Realization
具体观察者ConcreteObserver2 ..|> 抽象观察者Observer : Realization


class 抽象目标Subject{
#List~Observer~ observers
+add(Observer observer) void
+remove(Observer observer) void
+notifyObserver() void
}




class 抽象观察者Observer{
<<interface>>
+response void
}

class 具体观察者ConcreteObserver1{
+response void
}

class 具体观察者ConcreteObserver2{
+response void
}

class 具体目标ConcreteSubject{
+notifyObserver() void
%% 使用notifyObserver方法()
%% 通知每一个依赖在该具体目标上的具体观察者执行response()
}

(PS:mermaid是代码自动生成的布局,很多地方受限,不能调整。所以后面还是打算放UML图片了)

二、模式的实现

package observer;
//观察者模式
public class ObserverPattern {
    public static void main(String[] args) {
        Subject subject = new ConcreteSubject();
        Observer obs1 = new ConcreteObserver1();
        Observer obs2 = new ConcreteObserver2();
        subject.add(obs1);
        subject.add(obs2);
        subject.notifyObserver();
    }
}
//抽象目标
abstract class Subject {
    protected List<Observer> observers = new ArrayList<Observer>();

    //增加观察者
    public void add(Observer observer) {
        observers.add(observer);
    }
    //删除观察者
    public void remove(Observer observer) {
        observers.remove(observer);
    }
    //通知观察者
    public abstract void notifyObserver();
}
//具体目标
class ConcreteSubject extends Subject {
    public void notifyObserver() {
        System.out.println("天上乌云密布...");
        System.out.println("--------------");
        for (Object obs : observers) {
            ((Observer) obs).response();
        }
    }
}
//抽象观察者
interface Observer {
    void response(); //反应
}
//具体观察者1
class ConcreteObserver1 implements Observer {
    public void response() {
        System.out.println("我连忙出去收衣服");
    }
}
//具体观察者2
class ConcreteObserver2 implements Observer {
    public void response() {
        System.out.println("邻居连忙出去收衣服");
    }
}

程序运行结果

天上乌云密布...
--------------
我连忙出去收衣服
邻居连忙出去收衣服