模式说明

使用组合关系来创建一个可以被层层包装的对象(即装饰对器象)来包裹被装饰的主体对象,并在保持主体对象的类结构不变的前提下,通过装饰器对象自己的方法,为被装饰的主体对象提供额外的功能(装饰)。

本示例以技术为抽象主体类(TechComponent),一项核心技术为具体主体类(JavaComponent)。以其他扩展技术为抽象装饰类(TechDecorator),其具体装饰类为web技术(WebTechDecorator)和Spring技术(SpringTechDecorator)。演示如何在核心技术上扩展web和Spring技术。

结构

主体接口
定义一种行为方法。
具体主体类
实现抽象主体接口,实现抽象方法。
抽象装饰器类
装饰部件抽象类,实现抽象主体接口,实现抽象方法。
具体装饰器类
继承抽象装饰类,拥有自己的行为方法的同时实现抽象方法,并在其中调用自己的行为方法以及完成其所装饰的主体的行为方法。即所谓在保持主体对象不变的前提下,为其提供额外功能。

代码演示

  1. package com.yukiyama.pattern.structure;
  2. /**
  3. * 装饰器模式
  4. */
  5. public class DecoratorDemo {
  6. public static void main(String[] args) {
  7. // 声明一个主体com
  8. Functionable com = new JavaComponent();
  9. // 声明修饰对象deco1和deco2
  10. TechDecorator deco1 = new WebTechDecorator();
  11. TechDecorator deco2 = new SpringTechDecorator();
  12. // 此时主体为com,要在其上装饰deco1,为deco1传入com
  13. deco1.decorate(com);
  14. // 此时的主体为deco1,要在其上装饰deco2,为deco2传入deco1
  15. deco2.decorate(deco1);
  16. // 调用最后一层装饰对象的func(),会依次调用之前的所有装饰对象的
  17. // func()方法,最终调用到原始主体com的func()方法
  18. deco2.func();
  19. // 修饰顺序不同,调用的装饰器的功能顺序也不同
  20. }
  21. }
  22. /**
  23. * 主体接口
  24. * 声明主体的行为方法show()
  25. */
  26. interface Functionable{
  27. void func();
  28. }
  29. /**
  30. * 具体主体类
  31. * 实现抽象主体接口。
  32. */
  33. class JavaComponent implements Functionable{
  34. private final String tech = "JavaSE";
  35. @Override
  36. public void func() {
  37. System.out.printf("展示主体技术%s的技术内容。\n", tech);
  38. }
  39. }
  40. /**
  41. * 抽象装饰器类
  42. * 实现抽象主体接口,持有一个被本装饰器类装饰前的主体类,实现一个非抽象装饰
  43. * 方法addTech传入被修饰对象,一个抽象的主体行为方法。
  44. */
  45. abstract class TechDecorator implements Functionable{
  46. protected Functionable component;
  47. public void decorate(Functionable component) {
  48. this.component = component;
  49. }
  50. // 抽象类实现接口,可以不必实现接口内的抽象方法
  51. @Override
  52. public abstract void func();
  53. }
  54. /**
  55. * 具体装饰器类
  56. * 继承抽象装饰器类,拥有自己的行为方法,实现抽象方法的时候调用自己的行为
  57. * 方法并完成其所装饰的主体的行为方法。
  58. * 下例是Web技术。
  59. */
  60. class WebTechDecorator extends TechDecorator{
  61. private final String tech = "WebTech";
  62. // 重写func()并在其中执行自身功能,即装饰效果
  63. @Override
  64. public void func() {
  65. myFunc();
  66. component.func();
  67. }
  68. // 具体装饰类自身的功能
  69. public void myFunc() {
  70. System.out.printf("展示扩展技术%s的技术内容。\n", tech);
  71. }
  72. }
  73. /**
  74. * 具体装饰器类
  75. * 下例是Spring技术。
  76. */
  77. class SpringTechDecorator extends TechDecorator{
  78. private final String tech = "SpringTech";
  79. // 重写func()并在其中执行自身功能,即装饰效果
  80. @Override
  81. public void func() {
  82. myFunc();
  83. component.func();
  84. }
  85. // 具体装饰类自身的功能
  86. public void myFunc() {
  87. System.out.printf("展示扩展技术%s的技术内容。\n", tech);
  88. }
  89. }