连锁酒店网站方案/网络营销八大职能
定义
当对象之间存在一对多的关系时,被依赖的对象发生变化,需要通知到依赖它的所有对象。
举个例子
由于疫情的影响,各地的学校纷纷延迟了开学时间,延迟开学的消息由学校传达给老师和家长(不考虑由老师转发给家长的情况),具体的开学时间也是一样。这个例子中学校与老师和家长之间具有一对多的关系,学校的通知需要都通知到他们,结合观察者模式来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;}@Overridepublic 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;}@Overridepublic 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 要发送各个学生的成绩,同样复用这套机制即可,不需要重新实现。
-
缺点
- 如果观察者过多,那么执行通知要花费很长时间(遍历大数组),不需要的观察者要及时取消注册。
- 如果观察者与被观察者循环依赖,可能导致循环调用,导致系统崩溃。
- 观察者不知道所观察的对象是怎么变化的,只知道变化。