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