装饰器模式:Decorator Pattern,也叫作包装器模式(Wrapper Pattern),指在不改变原有对象的基础上,动态地给一个对象添加一些额外的职责

    应用场景:

    • 用于扩展一个类的功能,或者给一个类添加附加职责
    • 动态地给一个对象添加功能,这些功能支持再被动态地撤销
    • 需要为一批平行的兄弟类进行改装或加装功能

    装饰器与代理模式的区别:

    • 装饰器:强调自身的功能的扩展
    • 代理模式:强调对代理过程的控制

    典型应用:

    • java 的 IO 流设计
    • Spring 的 TransactionAwareCacheDecorator 类

    实现原理:

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

    UML 图:
    屏幕截图 2020-12-30 103737.png

    装饰器模式的 4 个角色:

    • 抽象组件:Component,可以是一个接口或抽象类,充当被装饰类的原始对象,规定了被装饰对象的行为
    • 具体组件:ConcreteComponent,实现了Component的一个具体对象,即被装饰对象
    • 抽象装饰器:Decorator,通用的装饰 ConcreteComponent 的装饰器,其内部必然有一个属性指向Component;其实现一般是一个抽象类,主要为了让其子类按照其构造形式传入一个Component,这是强制的通用行为。如果系统中装饰逻辑单一,则并不需要实现许多装饰器,可以直接省略该类,而直接实现一个具体装饰器即可
    • 具体装饰器:ConcreteDecorator,Decorator的具体实现类,理论上,每个ConcreteDecorator都扩展了Component对象的一种功能
    1. public class DecoratorDemo {
    2. public static void main(String[] args) {
    3. // 首先创建需要被装饰的原始对象,即被装饰的对象
    4. Component component = new ConcreteComponent();
    5. // 给被装饰的对象增加功能1并调用相关方法
    6. Decorator decorator = new ConcreteDecorator1(component);
    7. decorator.operation();
    8. // 给被装饰的对象增加功能2并调用相关方法
    9. Decorator decorator1 = new ConcreteDecorator2(component);
    10. decorator1.operation();
    11. // 在装饰器1上使用装饰器2
    12. Decorator decorator2 = new ConcreteDecorator2(decorator);
    13. decorator2.operation();
    14. }
    15. interface Component {
    16. void operation();
    17. }
    18. static class ConcreteComponent implements Component {
    19. @Override
    20. public void operation() {
    21. System.out.println("被装饰的目标方法!");
    22. }
    23. }
    24. abstract static class Decorator implements Component{
    25. // 持有对象组件
    26. protected Component component;
    27. // 构造方法,传入组建对象
    28. public Decorator(Component component) {
    29. this.component = component;
    30. }
    31. @Override
    32. public void operation() {
    33. component.operation();
    34. }
    35. }
    36. static class ConcreteDecorator1 extends Decorator {
    37. public ConcreteDecorator1(Component component) {
    38. super(component);
    39. }
    40. @Override
    41. public void operation() {
    42. System.out.println("装饰1增强!");
    43. super.operation();
    44. System.out.println("装饰器1增强!");
    45. }
    46. }
    47. static class ConcreteDecorator2 extends Decorator {
    48. public ConcreteDecorator2(Component component) {
    49. super(component);
    50. }
    51. @Override
    52. public void operation() {
    53. System.out.println("装饰2增强!");
    54. super.operation();
    55. System.out.println("装饰器2增强!");
    56. }
    57. }
    58. }