代理模式和装饰模式

**

代理模式和装饰模式

**

话说代理模式和装饰模式的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();//
}

我个人认为视情况而定,有时它是装饰者,有时它是代理。
以上为个人理解,如有错误欢迎大家指出,谢谢。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值