今天是1024程序员节,小编还在苦逼的996,老板说2020-1024=996,更心碎的是观察已久的妹子已结婚了,谨以此篇留作纪念。
观察者模式
你去银行柜台办理业务,可是柜台窗口已经满员了,大堂经理会给你取个号,等窗口空闲时就会广播通知叫号。这时窗口就是一个主题或被观察者,等待办理业务的客户就是订阅者或观察者,客户订阅了这个主题,主题发生变化时就会发布消息给观察者。所以观察者模式也被称之为发布-订阅模式。
观察者模式是一种对象行为模式,被观察者和观察者之间建立了一套通知机制,即观察者注册到被观察者上,被观察者持有观察者引用,被观察者状态发生变化时,通过事件触发通知观察者。
下面我们使用Java模拟实现观察者模式,基于面向接口编程及模板设计模式,我们先定义抽象被观察者和抽象观察者。
public abstract class Subject {
List<Observer> observers = new ArrayList<>();
List<String> msgs = new ArrayList<>();
void add(Observer observer) {
observers.add(observer);
}
void remove(Observer observer) {
observers.remove(observer);
}
void change(String msg) {
msgs.add(msg);
}
abstract void notice();
}
以上我们就定义好了抽象主题,定义了观察者注册接口add和remove,我们使用msgs模拟被观察者的状态变化,最后定义notice用来通知观察者。public interface Observer {
void watch(String msg);
}
因为观察者模式本身是一种抽象耦合的模式,耦合部分越简单越好,这里只简单定义一个用来接收状态变化的接口。
public class BeautyGirl extends Subject{
@Override
void notice() {
msgs.forEach((msg)->{
observers.forEach((observer)->{
observer.watch(msg);});
});
}
}
我们定义一个具体的主题,在主题发生状态变化时,将变化消息依次发布给订阅者,主题可以是多个,订阅者也可以同时订阅多个主题。public class BeastBoy implements Observer {
String name;
public BeastBoy(String name) {
this.name = name;
}
@Override
public void watch(String msg) {
System.out.println(String.format("%s receive: %s", name, msg));
}
public static void main(String[] args) {
Subject girl = new BeautyGirl();
Observer boy1 = new BeastBoy("1号追求者");
Observer boy2 = new BeastBoy("2号追求者");
girl.add(boy1);
girl.add(boy2);
girl.change("I have married!!!");
girl.notice();
}
}
最后我们模拟一个观察者,用来接收状态变化,并通过main方法使用观察者模式,当被观察者发生变化时,通知观察者。执行结果如下:渣男1号 receive: I have married!!!
渣男2号 receive: I have married!!!