1.3 源码接口设计启示
关于响应式编程的Rx标准,已经写入了JDK中,即java.util.concurrent.Flow:
可以看到,Flow类中包含了4个接口定义,Publisher通过subscribe方法与Subscriber产生订阅关系,而Subscriber依靠onSubscribe与上游源生产者产生联系,这里是通过Subscription做到的,所以Subscription往往会作为生产者的内部类进行定义,用来接收生产者所生产的元素,如果其支持背压,那么就和大坝蓄水一样。Subscription首先应该将元素放入一个队列中,然后根据元素请求数量来调用Subscriber的onNext等方法进行元素的下发。该实现方法在响应式编程中都是统一的模式,下面通过Reactor中reactor.core.publisher.Flux#fromArray所涉及的FluxArray的源码来进行理解:
大家可以结合前面的内容与源码内部的注释来理解源码细节。对于各种中间操作的包装,我们该如何做呢?依据之前的接口定义,我们应该更注重功能的设定。filter、flatMap、map等常用操作其实都是消费动作,理应定义在消费者层面,想到这里,我们又该如何做呢?
在这里,我们要结合设计模式——装饰器模式,对subscribe(Subscriber<?super T>subscriber)所传入的Subscriber进行功能增强,即从Subscriber这个角度讲,使用的是装饰增强模式。但从外面来看,其整体定义的依然是一个Flux或者Mono。FluxArray就是这样一个例子,从生产源角度来说,它通过继承Flux<T>来对外表示自己的生产源身份;而从功能增强处理的角度来说,其依靠的是内部类对所传入的Subscriber进行包装增强。最后通过subscribe(Subscriber<?super T>subscriber)将生产源与订阅者衔接起来,完成一整套标准流程的设定。
可以结合reactor.core.publisher.Flux#filter涉及的FluxFilter来观察和理解上述内容:
根据这些设计,完全可以以这套API接口设计作为参考,衍生出很多规范逻辑的开发实现,比如众多的Rx衍生操作API的设计实现,它们都是按照一套模板来实现的,可以称之为代码层面的微服务设计模板。