原理、实现、场景
观察者模式(Observer Design Patteren) 也称之为发布订阅模式(Publish Subscribe Patteren)。定义:在对象之间定义一个对多的依赖,当一个对象状态改变的时候,所依赖的对象都会自动收到通知
对于这个模式我更喜欢称之为发布订阅模式,一看就知道这个模式一般使用在一对多的场景,且包含发布者和订阅者两部分。为了基于接口编程,所以发布者包含发布者接口和发布者实现类,同样订阅者也包含订阅者接口和订阅者实现类。
类图如下:
由类图可以看出:
发布者包含一个维护订阅者的集合、一个添加订阅者的方法、一个移除订阅者的方法,以及一个通知订阅者的方法。
订阅者包含一个接收通知的方法。
如果是以观察者模式来解读的话,只需要把发布者替换为被观察者,订阅者替换为观察者即可。
代码实现如下:
/**
* 发布者接口
*/
public interface Publish {
void addSubscribe(Subscribe subscribe); //添加订阅者
void removeSubscribe(Subscribe subscribe); //删除订阅者
void notifySubscribes(String message); //通知订阅者
}
/**
* 订阅者接口
*/
public interface Subscribe {
void accept(String message); //接收通知
}
/**
* 发布者类
*
* 往订阅者发布消息
*/
public class ConcretePublish implements Publish{
List<Subscribe> subscribeList=new ArrayList<>();
@Override
public void addSubscribe(Subscribe subscribe) {
subscribeList.add(subscribe);
}
@Override
public void removeSubscribe(Subscribe subscribe) {
subscribeList.remove(subscribe);
}
@Override
public void notifySubscribes(String message) {
for(Subscribe subscribe:subscribeList){
subscribe.accept(message);
}
}
}
/**
* A订阅者
*
* 接收通知
*/
public class ConcreteSubcribeA implements Subscribe{
@Override
public void accept(String message) {
System.out.println("A订阅者接收到通知:"+message);
}
}
/**
* B订阅者
*
* 接收消息
*/
public class ConcreteSubcribeB implements Subscribe{
@Override
public void accept(String message) {
System.out.println("B订阅者接收到通知:"+message);
}
}
测试:
@Test
public void test(){
Publish publish=new ConcretePublish();
publish.addSubscribe(new ConcreteSubcribeA());
publish.addSubscribe(new ConcreteSubcribeB());
publish.notifySubscribes("38节,美女们可以提前下班了!");
}
测试结果:
上述代码比较简单,就不在详解了。弄明白了发布订阅模式(观察者模式)。那它会用在哪些场景。会通过一个实际的开发场景进行说明。
一个观察者模式的实际使用场景
在某些投资理财系统中,用户注册成功之后,会发放注册体验金。如果在注册接口中完成这这两件事:注册、发放体验金;实际上这个接口违反了单一职责原则,也不符合开闭原则。如果没有扩展和修改的需求的话,放在一个方法中实现也是可以接受的,如果非得使用观察者模式的话,就需要引入更多的类,更多复杂的代码结构,反而成了一种过度设计
如果需求频繁变动,你boss又提需求了,注册成功之后需要通过短信通知系统通知用户注册成功,且不再发放体验金了,而是改为发放优惠劵了。而且可能还会添加一些后续的操作。这个时候观察者模式就可以登场了。重构注册接口。我们可以把含有注册方法的类看成“发布者”。而短信通知、发放体验金、发放优惠券可以看成"订阅者"。“订阅者”可以灵活替换,更加符合开闭原则,和单一职责原则。。
参考:设计模式之美--王争