如有错误或有补充,以及任何的改进意见,请在评论区留下您的高见,同时文中给出大部分示例
如果觉得本文写的不错,不妨点个赞,收藏一下,助力博主产生质量更高的作品
概念
观察者模式是一种对象行为型模式,它定义了对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
在观察者模式中,存在两种类型的对象:目标对象和观察者对象。目标对象负责发出通知,而观察者对象则订阅目标对象,以便在目标对象的状态发生变化时接收到通知。一旦接收到通知,观察者对象就会执行相应的行为。
优缺点
观察者模式的优点主要包括:
解耦:观察者模式有助于降低目标对象和观察者对象的耦合度。观察者不再依赖于目标的具体实现,只需要知道目标提供了更新操作。
自动通知:当目标状态发生变化时,所有的观察者都会自动收到通知。这减少了手动更新每个观察者的需求,并确保所有观察者都能得到一致的状态更新。
支持任意数量的观察者:观察者模式允许你在运行时动态地添加或删除观察者,使得系统更加灵活和可扩展。
然而,观察者模式也存在一些缺点:
通知可能过于频繁:如果目标频繁地发生变化,可能会导致大量的通知被发送给观察者,这可能会对性能产生影响。
通知顺序问题:如果多个观察者依赖于同一个目标,并且该目标的状态频繁发生变化,那么这些观察者可能无法以一致的顺序接收到通知。
循环依赖:如果观察者和目标之间存在循环依赖,可能会导致内存泄漏,系统崩溃。
状态同步问题:在某些情况下,观察者可能需要在收到通知后立即执行某些操作,而这些操作可能依赖于目标对象的状态。由于目标对象在通知发送后可能会被其他线程修改,因此观察者可能无法获取到最新的状态。
增加了代码复杂度:使用观察者模式需要定义观察者和目标之间的关系,并在目标状态发生变化时通知所有观察者。这增加了代码的复杂度,并可能使代码更难以理解和维护。
使用场景
观察者模式的例子很多,例如气象局发布天气预报,当气象数据发生变化时,所有订阅了气象服务的客户端都会接收到更新的天气预报信息。再比如微信公众号,当公众号发布文章时,所有关注了这个公众号的用户都会接收到通知并看到文章。
代码实现示例
Subject.java
public class Subject { // 观察者列表 private ArrayList<Observer> observers = new ArrayList<>(); // 初始化观察者 public Subject() { this.observers.add(new Observer1()); this.observers.add(new Observer2()); } // 主体变化 public void change(){ for (Observer observer : observers) { observer.update(); } } // 展现Subject的观察者的变化 public void show(){ for (Observer observer : observers) { observer.show(); } } }
Observer.java
public interface Observer { public void update(); public void show(); }
Observer1.java
public class Observer1 implements Observer { private int count = 0; // 更新 @Override public void update() { count++; } @Override public void show() { System.out.println("Observer1-count: " + count); } }
Observer2.java
public class Observer2 implements Observer { private int count = 10; // 更新 @Override public void update() { count--; } @Override public void show() { System.out.println("Observer2-count: " + count); } }
Main.java
public class Main { public static void main(String[] args) { // 实例化Subject对象 Subject subject = new Subject(); // 未变动前,观察者的状态 subject.show(); System.out.println(); // 变动 subject.change(); // 变动后,观察者的状态 subject.show(); } }
输出
Observer1-count: 0
Observer2-count: 10
Observer1-count: 1
Observer2-count: 9