装饰器(Decorator)模式:指在不改变现有对象结构的情况下,动态地给该对象增加一些职责的模式

    优点:

    1. 装饰器是继承的补充,相对灵活,在不改变原有功能的前提下,扩展一个对象的功能
    2. 通过使用不同的装饰类,可以实现不同的功能
    3. 遵循开闭原则

    缺点:会增加很多类

    通常情况下,扩展一个类常常使用继承来实现,但是不能忽视继承会带来的一些问题

    • 继承是静态的。 你无法在运行时更改已有对象的行为, 只能使用由不同子类创建的对象来替代当前的整个对象。
    • 子类只能有一个父类。 大部分编程语言不允许一个类同时继承多个类的行为。

    其中一种方法是用聚合或组合 , 而不是继承。 两者的工作方式几乎一模一样: 一个对象包含指向另一个对象的引用, 并将部分工作委派给引用对象; 继承中的对象则继承了父类的行为, 它们自己能够完成这些工作。
    你可以使用这个新方法来轻松替换各种连接的 “小帮手” 对象, 从而能在运行时改变容器的行为。 一个对象可以使用多个类的行为, 包含多个指向其他对象的引用, 并将各种工作委派给引用对象。 聚合 (或组合) 组合是许多设计模式背后的关键原则 (包括装饰在内)

    “装饰器” 是一个能与其他 “目标” 对象连接的对象。 装饰器包含与目标对象相同的一系列方法, 它会将所有接收到的请求委派给目标对象。 但是, 装饰器可以在将请求委派给目标前后对其进行处理, 所以可能会改变最终结果。

    具体结构

    1. 抽象构件:定义一个抽象接口以规范准备接收附加责任的对象
    2. 具体构件:实现抽象构件,通过装饰器为其添加一些职责
    3. 抽象装饰:继承抽象构件,并包含有具体构件的实例,可以通过其子类扩展具体构件的功能
    4. 具体装饰:实现抽象装饰相关的方法,并给具体构件对象添加附加职责

    举例:假设我们目前有个绘制图形的功能,现在要给某些图形附加颜色的职责

    1. public class DecoratorDemo {
    2. // 形状
    3. interface Shape {
    4. void draw();
    5. }
    6. // 圆形
    7. static class Circle implements Shape{
    8. @Override
    9. public void draw() {
    10. System.out.println("绘制圆形");
    11. }
    12. }
    13. // 装饰器
    14. abstract static class ColorDecorator implements Shape {
    15. private Shape shape;
    16. public ColorDecorator(Shape shape){
    17. this.shape = shape;
    18. }
    19. @Override
    20. public void draw() {
    21. this.shape.draw();
    22. }
    23. public abstract void addColor();
    24. }
    25. // 装饰颜色
    26. static class BlueCircle extends ColorDecorator{
    27. public BlueCircle(Shape shape) {
    28. super(shape);
    29. }
    30. @Override
    31. public void addColor() {
    32. System.out.println("添加蓝色");
    33. this.draw();
    34. }
    35. }
    36. public static void main(String[] args) {
    37. ColorDecorator colorDecorator = new BlueCircle(new Circle());
    38. colorDecorator.addColor();
    39. }
    40. }