什么是观察者模式?
观察者模式是一种常用的设计模式,它定义了一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。
简单来说,观察者模式就是一种发布-订阅模式,被观察者是发布者,观察者是订阅者,当发布者发生变化时,订阅者会自动收到通知。
为什么要使用观察者模式?
使用观察者模式可以实现对象间的松耦合,降低系统的耦合度,同时也可以提高代码的复用性和可扩展性。
比如在 MVC 模式中,控制器是观察者,模型是被观察者,当模型发生变化时,控制器会自动更新视图,从而实现了 MVC 模式的基本功能。
如何使用观察者模式?
观察者模式的核心是观察者和被观察者之间的关系,我们可以通过定义一个抽象的被观察者类和一个抽象的观察者类来实现这种关系。
// 抽象的被观察者类 class Subject { constructor() { this.observers = [] } // 添加观察者 addObserver(observer) { this.observers.push(observer) } // 删除观察者 removeObserver(observer) { const index = this.observers.indexOf(observer) if (index > -1) { this.observers.splice(index, 1) } } // 通知观察者 notify() { for (const observer of this.observers) { observer.update(this) } } } // 抽象的观察者类 class Observer { update() {} }
通过定义这两个抽象类,我们就可以很方便地实现具体的观察者和被观察者。
观察者模式的优缺点
观察者模式有以下优点:
- 降低了对象间的耦合度,使得对象之间的关系更加灵活。
- 支持广播通信,当一个对象发生改变时,所有依赖它的对象都会自动更新。
- 符合开闭原则,可以方便地扩展和修改系统。
观察者模式也有一些缺点:
- 如果观察者很多,被观察者通知观察者的时间会变长,影响系统性能。
- 如果被观察者和观察者之间有循环依赖,会导致系统崩溃。
实战案例:使用观察者模式构建一个天气预报应用
我们可以使用观察者模式构建一个天气预报应用,当天气发生变化时,所有订阅了该城市天气的用户都会收到通知。
class WeatherStation extends Subject { constructor(city, temperature) { super() this.city = city this.temperature = temperature } // 更新天气 updateWeather(city, temperature) { this.city = city this.temperature = temperature this.notify() } } class User extends Observer { constructor(name) { super() this.name = name } // 收到天气通知 update(weatherStation) { console.log(`${this.name} 收到 ${weatherStation.city} 的天气通知:${weatherStation.temperature} 度`) } } // 创建一个天气预报应用 const weatherApp = new WeatherStation('北京', 20) // 订阅用户 const user1 = new User('张三') const user2 = new User('李四') const user3 = new User('王五') weatherApp.addObserver(user1) weatherApp.addObserver(user2) weatherApp.addObserver(user3) // 更新天气 weatherApp.updateWeather('上海', 25)
运行以上代码,我们可以看到三个用户都收到了天气通知:
张三 收到 上海 的天气通知:25 度 李四 收到 上海 的天气通知:25 度 王五 收到 上海 的天气通知:25 度
总结
观察者模式是一种常用的设计模式,它可以帮助我们实现对象间的松耦合,提高代码的复用性和可扩展性。在实际开发中,我们可以根据具体的业务场景来选择是否使用观察者模式。