众所周知,代理模式和装饰器模式都是通过和目标类实现相同的接口来确定其行为,并且通过聚合目标对象来增强目标对象的行为,但是两者的主要区别是什么呢?首先,看下两者的UML图:
代理模式
装饰器模式
通过类图不难发现,装饰器模式通常都会有一个抽象装饰者类 Decorator, 而代理类模式则没有,这是为什么呢?
主要的原因在于装饰器模式的目的在于动态地向对象添加功能,关键在于动态两个字,由于装饰器模式的动态增强,也就意味着功能的增强可以添加也可以删除,如果删除了增强功能,那么客户端直接调用目标对象的方法即可,也就意味着目标对象对于客户端来说是可以访问的。而代理模式通常是通过代理对象隐藏客户端对目标对象的访问,因此,目标对象对于客户端来说通常是不可见的,而目标对象的生命周期则交给代理对象来处理。
其次,既然是动态,也就意味着具体装饰者比较多,需要抽象装饰者来隔离具体实现,客户端可以传入不同的具体装饰者来提供灵活的增强功能,还可以通过多个不同的装饰者来实现同时增加多个功能。而代理模式通常都是用来提供固定的增强功能,比如权限校验,日志的添加等,所以通常不需要增加抽象。
总结一下:
1 从目标对象是否透明的角度来看:
代理类通常充当客户端和实际目标对象之间的中介,客户端通过代理间接访问目标对象,对于客户端来说,代理和目标对象是一致的,客户端可以无需知道目标对象的存在。
装饰器模式关注于在对象的行为上进行透明的扩展,目标对象对于客户端来说是可见的,并且能够脱离装饰器独立工作,客户端可以无需知道装饰器的存在。
2 从动态扩展功能的角度来看:
代理模式通常都是用来提供固定的增强功能,无需提供代理类的抽象。而装饰者通常会提供多种增强,因此需要提供抽象装饰者(也要看具体情况,比如java IO流中的BufferedReader仅仅是提供缓冲功能,因此无需提供BufferedReaderDecorator)
最后:两者都是结构型设计模式,只要设计符合规范,方便扩展维护,实际上无需严格区分使用上的区别,毕竟很多设计模式的原理都是通用的
以上仅个人观点,如有不同,欢迎讨论
参考链接:
Design Patterns (refactoring.guru) 详细介绍设计模式,值得收藏
设计模式总结文章(一边学习一边更新中)
建造者模式和工厂模式的区别-CSDN博客