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

后端 · 2020-11-14 ·

在现实生活中,大多数对象都不是单独存在的,其中一个对象的行为发生改变可能会导致一个或者多个其他对象的行为也发生改变。例如“蝴蝶效应”。

在软件开发系统中也是这样,例如事件模型中的事件源与事件处理者,MVC模式中的模型和视图的关系。

定义

定义对象间存在一对多的依赖关系,使得每当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。这种模式又被称为“发布-订阅模式”。

角色


观察者模式的主要角色如下:

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

代码

package xin.mla.observer;

import java.util.ArrayList;
import java.util.List;

public class ObserverTest {

    public static void main(String[] args) {
        Observer observera = new ConcreteObserverA();
        Observer observerb = new ConcreteObserverB();
        ConcreteTarget target = new ConcreteTarget();
        target.add(observera);
        target.add(observerb);
        target.notifyObserver();

    }

}

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

// 具体观察者
class ConcreteObserverA implements Observer {

    @Override
    public void response() {
        System.out.println("观察者A,作出了改变");

    }

}

// 具体观察者
class ConcreteObserverB implements Observer {

    @Override
    public void response() {
        System.out.println("观察者B,作出了改变");

    }

}

// 抽象目标
abstract class Target {
    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 ConcreteTarget extends Target {

    @Override
    public void notifyObserver() {
        System.out.println("具体目标发生改变...");
        System.out.println("--------------");
        for (Object obs : observers) {
            ((Observer) obs).response();
        }

    }

}

优点

  1. 降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系,符合依赖倒置原则。

缺点

  1. 目标和观察者之间的依赖关系并没有完全解除。
  2. 当观察者对象很多时,通知的发布会花费很多时间,影响程序的效率。
%