# 观察者模式
# 概念
观察者模式(Observer Pattern)是一种软件设计模式,其核心是定义一对多的依赖关系,使多个观察者对象能同时监听某一主题对象。当主题对象状态发生变化时,所有注册的观察者对象会自动接收通知并更新自身状态。
# 作用
1.实现对象间的动态耦合,让一个对象的改变能自动通知并更新其他相关对象。
2.维护对象间的一致性和同步性,适用于需要多个对象同步更新的场景。
3.支持广播通信机制,主题对象可向所有注册的观察者发送通知。
# 场景
1.当一个对象的改变需要同时触发其他多个对象的更新时。
2.当抽象模型存在两个相互依赖的维度(如业务逻辑与展示逻辑分离)时。
3.当对象需要通知未知数量的其他对象,且具体观察者可能动态增减时。
# 举例
// 被观察者接口
interface Subject {
void registerObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObservers(String name);
}
// 观察者接口
interface Observer {
void update(String name);
}
// 具体的被观察者(人)
class Person implements Subject {
private String name;
private List<Observer> observers;
public Person(String name) {
this.name = name;
this.observers = new ArrayList<>();
}
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}
@Override
public void removeObserver(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers(String name) {
for (Observer observer : observers) {
observer.update(name);
}
}
public void setName(String newName) {
this.name = newName;
notifyObservers(newName);
}
}
// 具体的观察者(身份证)
class IDCard implements Observer {
@Override
public void update(String name) {
System.out.println("身份证更新:名字已改为 " + name);
}
}
// 具体的观察者(户口本)
class HouseholdRegister implements Observer {
@Override
public void update(String name) {
System.out.println("户口本更新:名字已改为 " + name);
}
}
// 具体的观察者(学生卡)
class StudentCard implements Observer {
@Override
public void update(String name) {
System.out.println("学生卡更新:名字已改为 " + name);
}
}
客户端测试:
// 测试类
public class Main {
public static void main(String[] args) {
Person person = new Person("张三");
IDCard idCard = new IDCard();
HouseholdRegister householdRegister = new HouseholdRegister();
StudentCard studentCard = new StudentCard();
person.registerObserver(idCard);
person.registerObserver(householdRegister);
person.registerObserver(studentCard);
person.setName("李四");
}
}
控制台输出:
身份证更新:名字已改为 李四
户口本更新:名字已改为 李四
学生卡更新:名字已改为 李四
# 反例
若不使用观察者模式,可通过手动维护观察者列表实现类似功能,但灵活性和通用性较低。例如:
// 被观察者(人)
class Person {
private String name;
private List<Runnable> updaters = new ArrayList<>();
public Person(String name) {
this.name = name;
}
public void addUpdater(Runnable updater) {
updaters.add(updater);
}
public void removeUpdater(Runnable updater) {
updaters.remove(updater);
}
public void setName(String newName) {
this.name = newName;
for (Runnable updater : updaters) {
updater.run();
}
}
}
// 身份证
class IDCard {
private Person person;
public IDCard(Person person) {
this.person = person;
person.addUpdater(() -> System.out.println("身份证更新:名字已改为 " + person.name));
}
}
// 户口本
class HouseholdRegister {
private Person person;
public HouseholdRegister(Person person) {
this.person = person;
person.addUpdater(() -> System.out.println("户口本更新:名字已改为 " + person.name));
}
}
// 学生卡
class StudentCard {
private Person person;
public StudentCard(Person person) {
this.person = person;
person.addUpdater(() -> System.out.println("学生卡更新:名字已改为 " + person.name));
}
}
客户端测试:
public class Main {
public static void main(String[] args) {
Person person = new Person("张三");
new IDCard(person);
new HouseholdRegister(person);
new StudentCard(person);
person.setName("李四");
}
}
# 原理
观察者模式的核心原理是:主题对象维护一个观察者列表,当自身状态发生变化时,遍历该列表并调用所有观察者的更新方法。观察者通过实现统一接口(如update
方法)接收通知,实现解耦。
# 缺点
观察者模式的缺点包括:
1.被观察者与观察者间的依赖关系可能变得复杂,增加维护难度。
2.观察者无法控制通知的顺序,可能导致更新逻辑依赖执行顺序的问题。
3.Java内置的Observable
和Observer
未考虑线程安全,需开发者自行处理并发问题。
总结
观察者模式通过一对多的依赖关系实现动态通知,适用于需要对象同步更新的场景。其优点是松耦合、支持广播通信和动态扩展,但依赖关系复杂度和通知顺序问题可能带来维护挑战。合理使用时,可有效提升系统的灵活性和可扩展性。

微信公众号

QQ交流群
原创网站开发,偏差难以避免。
如若发现错误,诚心感谢反馈。
愿你倾心相念,愿你学有所成。
愿你朝华相顾,愿你前程似锦。
如若发现错误,诚心感谢反馈。
愿你倾心相念,愿你学有所成。
愿你朝华相顾,愿你前程似锦。