之前在说单例设计模式的时候提到过,设计模式是针对问题最有效的解决方法。这里再回顾一下自己熟悉的装饰、代理、工厂、策略、观察者设计模式。先说装饰、代理设计模式。
装饰设计模式
当想要对已有的对象进行功能增强时,可以定义类,将已有对象传入,基于已有对象的功能,提供加强功能。那么自定义的该类称为装饰类。
装饰类。通常会通过构造方法接收被装饰的对象,并基于被装饰对象的功能,提供更强的功能。
装饰模式比继承要灵活,避免了继承体系的臃肿。而且降低了类与类之间的关系。
装饰类因为只是增强已有对象,具备的功能和已有对象是相同的,只不过提供了更强的功能,所以装饰类和被装饰类通常属于一个体系。
代码
|
|
增强Reader,增强一个MyReaderLine(读一行)的方法,而其他的方法还是调用原来对象的方法。
工作中常用到可能是下图这种情况,有人写了一个工具类方法,但是功能不够强或比较繁琐。那我们不能直接去改这个工具类方法,因为这个工具类方法可能有很多地方进行了调用。要么写个子类进行覆盖,要么进行增强。这也是装饰的一种手法。
当一个Java对象方法不够用的时候,有如下方法解决此问题。
- 写一个子类,覆盖某个方法。如果父类已经封装了信息,不再建议使用此方法。
- 写一个此类的包装类,增强某个方法。当包装方式比较复杂时,使用代理模式。
- 使用代理模式,返回一个代理对象出去,拦截某个方法的调用,并对其进行增强。
代理模式
代理模式有点类似明星与经纪人一样。这里主要讲动态代理。某个房地产公司想请某明星代言,直接找该明星的经纪人谈具体的细节,谈好之后,实际的代言是由明星去做。这是一个思路,那我们来看怎么实现。
运行如下:
Proxy类的newProxyInstance()是JDK自带的动态代理,产生代理对象,基于接口进行代理,拦截对真实对象的访问。代理对象需要具备与真实对象相同的行为,代理对象最终还是找真实对象实现具体的行为。
newProxyInstance()方法接收三个参数,第一个是类加载器,第二个是哪个接口,第三个是干什么行为。
如果一个类没有接口,要使用动态代理,需要使用CGLib。
spring在AOP中两种进行了采用。
JDK返回出的代理对象是基于接口生成的。
CGLib返回出的代理对象是基于子类生成的,所以类不能被final修饰。