写给自己看的设计模式之《观察者模式》

定义

当对象之间存在一对多的关系时,被依赖的对象发生变化,需要通知到依赖它的所有对象。

举个例子

由于疫情的影响,各地的学校纷纷延迟了开学时间,延迟开学的消息由学校传达给老师和家长(不考虑由老师转发给家长的情况),具体的开学时间也是一样。这个例子中学校与老师和家长之间具有一对多的关系,学校的通知需要都通知到他们,结合观察者模式来code看看。

  • 首先定义被观察者:学校

维护一个 Observer 的数组,老师和家长可以通过 registerObserver 方法注册;学校通过 publishNotice 方法发布通知

import java.util.ArrayList;
import java.util.List;
import observer.consumer.Observer;

public class School {
    
    

    private String name;

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

    private List<Observer> observers = new ArrayList<>();

    public void registerObserver(Observer observer) {
    
    
        observers.add(observer);
    }

    public void publishNotice(String message) {
    
    
        System.out.println("I'm school: " + name + ", send message: " + message);
        observers.forEach(e -> e.update(message));
    }
}
  • 定义接口 Observer
public interface Observer {
    
    
    void update(String message);
}
  • 定义观察者:老师
public class Teacher implements Observer {
    
    
    private String name;

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

    @Override
    public void update(String message) {
    
    
        System.out.println("I'm teacher: " + name + ", received message: " + message);
        // do something
    }
}
  • 定义观察者:家长
public class Parent implements Observer {
    
    
    private String name;

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

    @Override
    public void update(String message) {
    
    
        System.out.println("I'm parent: " + name + ", received message: " + message);
        // do something
    }
}
  • 最后通过 main 方法执行发布延迟开学的通知
public class Main {
    
    
    public static void main(String[] args) {
    
    
        Parent parent = new Parent("ZS");
        Teacher teacher = new Teacher("LS");

        School school = new School("CSU");
        school.registerObserver(parent);
        school.registerObserver(teacher);

        school.publishNotice("Delay the start of school");
    }
}

在这里插入图片描述

优缺点

  • 优点

    • 从上面的例子中看到,观察者与被观察者之间是抽象耦合的。School 类并不直接调用 Teacher & Parent 的 update 方法,而是面向接口编程,调用其接口 Observer 的方法。好处就是假如要添加一个新的观察者,直接继承 Observer 类并注册到 School 即可。
    • 建立了一套触发机制。假如 School 要发送各个学生的成绩,同样复用这套机制即可,不需要重新实现。
  • 缺点

    • 如果观察者过多,那么执行通知要花费很长时间(遍历大数组),不需要的观察者要及时取消注册。
    • 如果观察者与被观察者循环依赖,可能导致循环调用,导致系统崩溃。
    • 观察者不知道所观察的对象是怎么变化的,只知道变化。

猜你喜欢

转载自blog.csdn.net/Dkangel/article/details/107410214