最近在看阿里开源RPC框架Dubbo的源码,顺带梳理了一下其中用到的设计模式。下面将逐个列举其中的设计模式,并根据本身的理解分析这样设计的缘由和优劣。html
责任链模式在Dubbo中发挥的做用举足轻重,就像是Dubbo框架的骨架。Dubbo的调用链组织是用责任链模式串连起来的。责任链中的每一个节点实现Filter
接口,而后由ProtocolFilterWrapper
,将全部Filter
串连起来。Dubbo的许多功能都是经过Filter
扩展实现的,好比监控、日志、缓存、安全、telnet以及RPC自己都是。若是把Dubbo比做一列火车,责任链就像是火车的各车箱,每一个车箱的功能不一样。若是须要加入新的功能,增长车箱就能够了,很是容易扩展。java
Dubbo中使用观察者模式最典型的例子是RegistryService
。消费者在初始化的时候回调用subscribe方法,注册一个观察者,若是观察者引用的服务地址列表发生改变,就会经过NotifyListener
通知消费者。此外,Dubbo的InvokerListener
、ExporterListener
也实现了观察者模式,只要实现该接口,并注册,就能够接收到consumer端调用refer和provider端调用export的通知。Dubbo的注册/订阅模型和观察者模式就是天生一对。设计模式
Dubbo中还大量用到了修饰器模式。好比ProtocolFilterWrapper
类是对Protocol类的修饰。在export和refer方法中,配合责任链模式,把Filter组装成责任链,实现对Protocol功能的修饰。其余还有ProtocolListenerWrapper
、 ListenerInvokerWrapper
、InvokerWrapper
等。我的感受,修饰器模式是一把双刃剑,一方面用它能够方便地扩展类的功能,并且对用户无感,但另外一方面,过多地使用修饰器模式不利于理解,由于一个类可能通过层层修饰,最终的行为已经和原始行为偏离较大。缓存
CacheFactory
的实现采用的是工厂方法模式。CacheFactory
接口定义getCache方法,而后定义一个AbstractCacheFactory
抽象类实现CacheFactory
,并将实际建立cache的createCache方法分离出来,并设置为抽象方法。这样具体cache的建立工做就留给具体的子类去完成。安全
ProxyFactory
及其子类是Dubbo中使用抽象工厂模式的典型例子。ProxyFactory
提供两个方法,分别用来生产Proxy
和Invoker
(这两个方法签名看起来有些矛盾,由于getProxy方法须要传入一个Invoker对象,而getInvoker方法须要传入一个Proxy
对象,看起来会造成循环依赖,但其实两个方式使用的场景不同)。AbstractProxyFactory
实现了ProxyFactory
接口,做为具体实现类的抽象父类。而后定义了JdkProxyFactory
和JavassistProxyFactory
两个具体类,分别用来生产基于jdk代理机制和基于javassist代理机制的Proxy
和Invoker
。网络
为了让用户根据本身的需求选择日志组件,Dubbo自定义了本身的Logger接口,并为常见的日志组件(包括jcl, jdk, log4j, slf4j)提供相应的适配器。而且利用简单工厂模式提供一个LoggerFactory
,客户能够建立抽象的Dubbo自定义Logger
,而无需关心实际使用的日志组件类型。在LoggerFactory初始化时,客户经过设置系统变量的方式选择本身所用的日志组件,这样提供了很大的灵活性。app
Dubbo consumer使用Proxy
类建立远程服务的本地代理,本地代理实现和远程服务同样的接口,而且屏蔽了网络通讯的细节,使得用户在使用本地代理的时候,感受和使用本地服务同样。框架