前言:什么叫设计模式?
设计是解决软件开发某些特定问题而提出的一些解决方案也可以理解成解决问题的一些思路。通过设计模式可以帮助我们增强代码的可重用性、可扩充性、 可维护性、灵活性好。我们使用设计模式最终的目的是实现代码的高内聚和低耦合。
观察者模式
一、定义
多个观察者同时监听某一个主题对象,当主题对象发生变化时,它的所有观察者都会收到通知并更新。
二、优点
(1)被观察者和观察者对象之间不需要知道对方的具体实现,只需要知道对方的接口,避免了紧耦合的关系。
(2)由于被观察者对象并不关心具体的观察者是谁,所以在程序运行的过程中,可以动态地增加或者删除观察者对象,增加了灵活性。
(3)符合开闭原则,当需要添加新的观察者时,只需要添加一个实现观察者接口的类,而不需要修改被观察者对象的代码。
三、缺点
(1)当观察者没有被正确移除时,可能会导致内存泄漏的问题。
(2)实现观察者模式,需要定义多个接口和类,增加了程序的复杂度。
(3)在某些情况下,被观察者和观察者对象之间可能出现循环依赖的问题。
四、代码
使用场景:双11快到了,你观看了小米14的发布会心血来潮,打算购买小米14Pro手机,体验一把真正的性价比。然而,开抢时间设置在11月10号晚上12点。于是你在京东上面默默设置了开抢“预约”。与此同时,你的好基友小明、小红也默契的跟你做了相同的操作。
抽象被观察者:Subject (可理解为平台上所有支持抢购的物品统称)
具体被观察者:ConcreteSubject (XiaoMi14Pro)
抽象观察者:Observer(能接收信息的个人)
具体观察者:ObserverImpl(我、小红、小明)
1、抽象观察者接口(可理解为能接收信息的个人)
public interface IObserver {
//接收通知
void receive();
}
2、实现具体的观察者小明、小红
public class ObserverXiaoMing implements IObserver{
private static final String TAG = "ObserverXiaoMing";
@Override
public void receive() {
Log.i(TAG, "小明收到开抢信息!");
}
}
public class ObserverXiaoHong implements IObserver{
private static final String TAG = "ObserverXiaoMing";
@Override
public void receive() {
Log.i(TAG, "小红收到开抢信息!");
}
}
3、抽象被观察者类(可理解为平台上所有支持抢购的物品统称)
public abstract class Subject {
protected List<IObserver> observers = new ArrayList<IObserver>();
// 增加观察者方法
public void add(IObserver observer){
observers.add(observer);
}
// 删除观察者方法
public void remove(IObserver observer){
observers.remove(observer);
}
// 通知观察者方法
public abstract void notifyObserver();
}
4、具体被观察者对象
public class ConcreteSubject extends Subject{
private static final String TAG = "ConcreteSubject";
@Override
public void notifyObserver() {
Log.i(TAG, "双11开始了!");
for(IObserver iObserver: observers){
iObserver.receive();
}
}
}
5、测试类
public class MyTest {
public static void main(String[] args) {
ConcreteSubject xiaoMi14Pro = new ConcreteSubject();
ObserverXiaoMing xiaoMing = new ObserverXiaoMing();
ObserverXiaoHong xiaoHong = new ObserverXiaoHong();
//小明预约了抢购
xiaoMi14Pro.add(xiaoMing);
//小红预约了抢购
xiaoMi14Pro.add(xiaoHong);
//小米14Pro的双11抢购开始了
xiaoMi14Pro.notifyObserver();
//小红取消了预约
xiaoMi14Pro.remove(xiaoHong);
xiaoMi14Pro.notifyObserver();
}
}
6、执行结果
2023-12-06 18:37:10.334 5016-5016/com.cxj.mytester I/ConcreteSubject: 双11开始了!
2023-12-06 18:37:10.334 5016-5016/com.cxj.mytester I/ObserverXiaoMing: 小明收到开抢信息!
2023-12-06 18:37:10.334 5016-5016/com.cxj.mytester I/ObserverXiaoMing: 小红收到开抢信息!
2023-12-06 18:37:10.334 5016-5016/com.cxj.mytester I/ConcreteSubject: 双11开始了!
2023-12-06 18:37:10.334 5016-5016/com.cxj.mytester I/ObserverXiaoMing: 小明收到开抢信息!