**
代理模式和装饰模式
**
话说代理模式和装饰模式的uml图很类似,之前会用,但是对于语意却不甚理解。今天在翻到一篇博文时,忽然间感觉开朗了。
简单理解:
代理模式 :主要用来控制对对象的访问。
装饰模式: 主要用来对对象动态的添加额外的一些“能力”,是继承的另一种替代。【但比继承好,优先使用组合而不是继承,使用装饰者模式,很大情况下因为继承容易产生子类爆炸】
之前的误区在于,很大程度上根据实现来进行区分,网上也有很多的类似博客:
对于代理模式,代理类中可以静态的绑定到某一个具体的被代理类,客户端直接使用代理,而不需要知道被代理的对象是谁。
装饰者往往是客户传入某一个具体的被装饰对象。
感觉还是有点道理。于是代码成为这样:
public interface Subject{
public void doSomething();
}
public class RealSubject implements Subject{
public void doSomething(){
//做一些工作
}
}
public class ProxySubject implements Subject{
private Subject subject;
public ProxySubject(){
subject = new RealSubject();
}
public void doSomething(){
subject.doSomething();
}
}
//客户端
main(){
Subject sub = new ProxySubject();
sub.doSomething();
}
嗯,客户端是不需要知道代理类了。
可是再看看装饰者模式:
public interface Subject{
public void doSomething();
}
public class RealSubject implements Subject{
public void doSomething(){
//做一些工作
}
}
public class DecorateSubject implements Subject{
private Subject subject;
public ProxySubject(Subject subject){
this.subject = subject;
}
public void doSomething(){
subject.doSomething();
}
}
main(){
Subject sub = new DecorateSubject(new RealSubject());
sub.doSomething();
}
难道就是因为这一点区别吗?客户端需要知道对谁进行装饰,并且可以多次装饰。
当然这里面我没有在装饰者的doSomething中添加额外的修饰【为了更好的和上面做对比】
难道代理模式就不能直接传入吗?传人了就不是代理模式了吗?
不是的!
设计模式博大精深,绝不可能仅仅因为这一点实现或者仅仅如此一点语意【客户端是否需要知道被装饰/代理 者】就出现两种完全一样的模式。那么区别究竟在哪里?
我回头认真思考了下,常用的几种代理【动态代理更多的是一种实现手法,不是语意】,比如远程代理,虚拟代理,缓冲代理等等。以及常用的 访问控制代理。发现一个共同点: 代理干了什么?
代理有权利控制客户是否可以访问到真实被代理对象【这一点装饰者做不到,它只是添加额外功能,但是最终还是要“老老实实”的使用被装饰对象的功能“】
代理做的事情,更多的是为”被代理对象“服务。比如WCF技术,我们知道会在客户端产生代理,但是代理增加了我们的执行逻辑了吗?没有,代理只是做了一些琐碎的事情【帮助简化客户端和”被代理对象“之间的”沟通“】。权限控制代理呢?它做了什么?没有增加被代理的对象【比如资源】的什么能力,而是在外部,阻止一些不合权限的人进入!。装饰者就不同了,它是真正的增加了被代理对象的能里,那么此时问个问题,假设你现在创建普通的三层应用,你有一个DBHelper类,但是没有事务管理【如果操作有异常出现,希望自动回滚】,你希望为这个DBHelper增加事务管理,该使用什么方式呢?代理还是装饰者?
答案是装饰者,因为我们是为被代理的对象【DBHelper类】添加了和它自身有关的”能力“!。
而对于一些所谓:
void func(){
doBefore()//
RealSubject.doSomething();
doAfter();//
}
我个人认为视情况而定,有时它是装饰者,有时它是代理。
以上为个人理解,如有错误欢迎大家指出,谢谢。