观察者模式,又叫做发布-订阅模式(Publish/Subscribe)。它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。当这个主题对象状态发生变化时,会通知所有已注册的观察者对象,使它们能够依据实际情况,进行后续处理。
假设,我们有个自播带货的应用场景就可以用到观察者模式。
直播带货指的是通过视频直播平台,进行现场直播卖货的模式。目前带货平台以淘宝、快手、抖音为主,京东、拼多多、有赞等电商平台也开始试水直播带货的玩法。现在的直播间,刚好处在吸粉阶段,关注直播间得礼物,送代金券是目前的主流玩法。
想要得到礼物,观众就得关注直播间,这时的观众就是观察者啦。
1 直播带货应用示例
下面用 Java 语言实现该模式。
(1)观察者抽象类
观察者模式实际是围绕着观察者进行设计,所以我们首先实现观察者抽象类:
/**
* 观察者
* <p/>
*
* @author Deniro Lee
*/
public abstract class Observer {
/**
* 姓名
*/
private String name;
public Observer(String name) {
this.name = name;
}
/**
* 获取礼物
*
* @param gift
*/
public abstract void getGift(String gift);
public String getName() {
return name;
}
}
这里之所以使用抽象类而不是接口,是因为抽象类可以实现一些公共方法,简化代码。
(2)观众
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
/**
* 观众
* <p/>
*
* @author Deniro Lee
*/
public class Audience extends Observer {
private static final Logger logger = LogManager.getFormatterLogger();
public Audience(String name) {
super(name);
}
/**
* 得到礼物
*
* @param gift 礼物
*/
@Override
public void getGift(String gift) {
logger.info("%s 得到礼物“%s”啦๑乛◡乛๑", getName(), gift);
}
}
(3)Subject 主题接口
定义 Subject 主题接口,包含新增与减少观察者方法以及通知方法:
/**
* 主题
* <p/>
*
* @author Deniro Lee (lisq037@163.com)
*/
public interface Subject {
/**
* 新增需要通知的观察者
*
* @param observer
*/
void attach(Observer observer);
/**
* 减少需要通知的观察者
*
* @param observer
*/
void detach(Observer observer);
/**
* 通知
*/
void inform();
}
(4)直播间
import java.util.ArrayList;
import java.util.List;
/**
* 直播间
* <p/>
*
* @author Deniro Lee
*/
public class BroadcastingRoom implements Subject {
/**
* 观众列表
*/
private List<Observer> audiences = new ArrayList<>();
@Override
public void attach(Observer observer) {
audiences.add(observer);
}
@Override
public void detach(Observer observer) {
audiences.remove(observer);
}
@Override
public void inform() {
//发放代金券
for (Observer audience : audiences) {
audience.getGift("代金券");
}
}
}
(5)执行
/**
* 执行“观察者模式”
* <p/>
*
* @author Deniro Lee
*/
public class Main {
public static void main(String[] args) {
BroadcastingRoom room = new BroadcastingRoom();
//millie 关注直播间
Audience millie = new Audience("millie");
room.attach(millie);
//alfie 关注直播间
Audience alfie = new Audience("alfie");
room.attach(alfie);
//直播间发放代金券
room.inform();
}
}
运行结果:
2 观察者模式特点
- 观察者模式的关键对象是主题 Subject 和观察者 Observer;
- 一个 Subject 对应多个 Observer;
- 当 Subject 的状态发生改变时,所有的 Observer 都会得到通知;
- Subject 发出通知时并不知道谁是它的实际观察者,也就是说,Subject 与实际的观察者是解耦的;
- 任何一个具体观察者道也不知道其他观察者的存在。
3 应用场景
当一个对象的改变需要同时改变其他对象,并且这个对象不知道实际有多少对象需要改变时,就可以考虑使用观察者模式。
观察者模式可以有效地解除耦合。让双方都依赖于抽象,使得它们各自的变化都不会影响另一方的变化 。