前言:本篇系看完《研磨设计模式》一书的个人理解和总结,可能存在不正确的地方,看时需要持怀疑态度。另外,所有的图都是示意图,示意,示。
代理模式(Proxy):
几点解释:
- 代理类实现了和原始类相同的接口,并且持有原始类的一个实例。客户端使用的是代理类的实例,代理类再向原始类实例发起相应的调用。这样就可以在调用原始类实例的方法前后做一些控制。
- 本质:控制对象的访问。也可以增添一些功能。
- 代理模式其实对应Java中的静态代理,需要一个实际的代理类来实现对应的接口。由此产生的问题在于:接口发生了变化,则代理类和实际类的类都需要做出改动。
- Java中内置了 动态代理,实现方式为 动态字节码生成以及反射技术。动态代理目前只支持接口,如果没有接口的话,可以使用 CGLIB等工具来通过继承的方式生成代理对象。动态代理的好处在于,对于接口方法的调用会全部指向 InvocationHandler 的 invoke方法,无论接口怎么变化都没有关系。
- 我们其实可以思考下Java内置的动态代理所需要做的工作:创建一个类来实现对应的接口,接口中所有的方法都要实现为 向 InvocationHandler 的 invoke方法发起调用,传入一些反射需要的参数 Method对象,方法的参数列表等等。这其实是一些通用且固定的步骤,当然可以给出一个通用的实现。
- Spring中的AOP就是策略的运用了 Java动态代理和CGLIB技术,来给目标类加入额外的功能。
- 代理在开发中很常用,可以在代理类中做一些 权限判断,参数校验等通用的横向的功能。我们不想改动既有的对象代码,又想把一些通用的例如 权限判断的功能剥离出来,就可以运用代理。演化到后面,就有了AOP的思想,面向切面编程,做一些横向的通用的工作。
- 咋一看,和装饰模式的结构很类似,都是实现相同的接口,并持有一个原始类的示例,增加一些额外的功能。但是二者的目的其实不同:代理模式目的更多在于控制对象的访问,装饰模式则是灵活的给对象加上各种的功能。但是二者的实现方式很相似,所以不用过于纠结,可以灵活变形。
观察者模式(Observer):
几点解释:
- 观察者模式分为两个部分:观察者和观察目标。观察目标和观察者是一对多的关系,并且是单向依赖,即 观察者依赖观察目标,而观察目标并不依赖观察者。
- 观察目标需要维护自己的观察者列表,并提供 注册和解除注册的功能,并在状态变化的时候,通知所有的观察者,只是简单的通知下,并不关心后续的部分。
- 这其实和我们日常使用的消息队列很像,解耦了 观察者和被观察者,被观察者服务只需在状态发生变化时,向消息队列写入一条消息,对这个状态感兴趣的服务自行订阅相应的消息即可。使得系统具有很好的扩展性。
- 当我们接触到UI相关的,比如说SWING或者是安卓。我们一定会接触到 addXXXListener()方法,其实就是观察者模式的运用,添加相应的观察者,当界面上某个按钮被点击或者某个控件的状态发生变化时,通知相关的观察者,实现相关的功能。