代理模式的套娃版本

    装饰器模式(Decorator Pattern)也叫作包装器模式(Wrapper Pattern),指在不改变原有对象的基础上,动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活,属于结构型设计模式。
    image.png
    如果系统中装饰逻辑单一,则并不需要实现许多装饰器,可以直接省略该类,而直接实现一个具体装饰器即可。

    装饰器模式的实现原理是,让装饰器实现与被装饰类(例如ConcreteComponent)相同的接口(例如Component),使得装饰器与被扩展类类型一致,并在构造函数中传入该接口对象,然后在实现这个接口的被包装类对象的现有功能上添加新功能。由于装饰器与被包装类属于同一类型(均为Component),且构造函数的参数为其实现接口类(Component),因此装饰器模式具备嵌套扩展功能,这样就能使用装饰器模式一层一层地对底层被包装类进行功能扩展了。

    场景

    • 解决类爆炸问题
    • 扩展一个类的功能
    • 扩展一个对象的功能,并且可以动态撤销
    • 需要为一批平行的兄弟类进行改装或加装功能。

    优点:

    • 装饰类和被装饰类之间解耦,对被装饰类的扩展不需要修改被装饰类
    • is-a关系代替继承
    • 动态扩展类的功能,可以通过排列组合获取不同的效果
    • 装饰器模式角色分配符合设计模式的里氏替换原则、依赖倒置原则,从而使得其具备很强的扩展性,最终满足开闭原则。

    抽象类

    1. public abstract class Component {
    2. public abstract void op();
    3. }
    4. public class ConcreteComponent extends Component{
    5. @Override
    6. public void op() {
    7. }
    8. }
    9. public abstract class Decorator extends Component{
    10. private Component component = null;
    11. public Decorator(Component component) {
    12. this.component = component;
    13. }
    14. @Override
    15. public void op() {
    16. this.component.op();
    17. }
    18. }
    19. public class DecoratorA extends Decorator {
    20. public DecoratorA(Component component) {
    21. super(component);
    22. }
    23. private void doSomethingElse(){
    24. }
    25. @Override
    26. public void op() {
    27. super.op();
    28. this.doSomethingElse();
    29. }
    30. }
    31. public class DecoratorB extends Decorator {
    32. public DecoratorB(Component component) {
    33. super(component);
    34. }
    35. private void doSomethingElse(){
    36. }
    37. @Override
    38. public void op() {
    39. super.op();
    40. this.doSomethingElse();
    41. }
    42. }
    43. public class Client {
    44. public static void main(String[] args){
    45. Component component = new ConcreteComponent();
    46. //套娃
    47. DecoratorB decoratorB = new DecoratorB(new DecoratorA(component));
    48. decoratorB.op();
    49. }
    50. }

    框架:

    • IO流模型

    image.png

    • Spring的TransactionAwareCacheDecorator和HttpHeadResponseDecorator
    • Mybatis的FifoCache、LruCache、TranscationCacde

    代理模式和装饰着模式的关注点不同

    • 装饰器模式强调自身功能的扩展。Decorator所做的就是增强Concrete Component的功能(也有可能减弱功能),主体对象为Concrete Component,着重类功能的变化。
    • 代理模式强调对代理过程的控制。Proxy完全掌握对RealSubject的访问控制,因此,Proxy可以决定对RealSubject进行功能扩展、功能缩减甚至功能散失(不调用RealSubject方法),主体对象为
    • 装饰器模式不会对准入条件进行判断、对准入参数进行过滤,只是对被修饰类功能进行增强。代理模式包含了流程判断,是否调用被代理对象,但是不对被代理类的功能进行处理