# 装饰器模式

# 概念

装饰器模式(Decorator Pattern)是一种结构型设计模式,核心思想是通过创建装饰器类来包装原始对象,在运行时动态地为其添加额外功能或职责,而无需修改原始类的代码。其本质是对继承关系的一种替代方案,通过组合而非继承实现功能的扩展。

# 作用

1.动态扩展功能:支持在运行时为对象动态添加或移除功能,满足灵活多变的需求。

2.避免类爆炸:通过装饰器类的组合实现功能扩展,替代继承导致的子类数量指数级增长问题。

3.符合开闭原则:对扩展开放(新增装饰器类即可扩展功能),对修改封闭(无需修改原始类代码)。

4.解耦功能与对象:将功能实现与对象本身分离,提高代码的可维护性和复用性。

# 场景

1.需要动态添加/移除功能:如图形绘制系统中,用户可自由选择是否添加边框、阴影等效果。

2.避免继承层次过深:当功能扩展通过继承会导致类结构复杂时(如多个独立功能需要叠加)。

3.功能组合灵活:需要组合多种独立功能时(如同时添加边框和阴影)。

4.运行时功能切换:允许在运行时动态决定是否启用某些功能。

# 举例

以下是一个图形绘制系统中使用装饰器模式的Java代码示例,实现为形状动态添加边框和阴影功能:

// 图形接口
public interface Shape {
    void draw();
}
// 圆形实现
public class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("绘制圆形");
    }
}
// 矩形实现
public class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println("绘制矩形");
    }
}
// 装饰器基类
public abstract class ShapeDecorator implements Shape {
    protected Shape decoratedShape;

    public ShapeDecorator(Shape decoratedShape) {
        this.decoratedShape = decoratedShape;
    }

    @Override
    public void draw() {
        decoratedShape.draw();
    }
}
// 边框装饰器
public class BorderDecorator extends ShapeDecorator {
    public BorderDecorator(Shape decoratedShape) {
        super(decoratedShape);
    }

    @Override
    public void draw() {
        super.draw();
        addBorder();
    }

    private void addBorder() {
        System.out.println("添加边框");
    }
}
// 阴影装饰器
public class ShadowDecorator extends ShapeDecorator {
    public ShadowDecorator(Shape decoratedShape) {
        super(decoratedShape);
    }

    @Override
    public void draw() {
        super.draw();
        addShadow();
    }

    private void addShadow() {
        System.out.println("添加阴影");
    }
}

控制台输出:

public class Main {
    public static void main(String[] args) {
        // 圆形添加边框
        Shape circle = new Circle();
        Shape circleWithBorder = new BorderDecorator(circle);
        circleWithBorder.draw(); // 输出:绘制圆形 添加边框

        // 矩形添加阴影
        Shape rectangle = new Rectangle();
        Shape rectangleWithShadow = new ShadowDecorator(rectangle);
        rectangleWithShadow.draw(); // 输出:绘制矩形 添加阴影

        // 圆形同时添加边框和阴影
        Shape circleWithBoth = new ShadowDecorator(new BorderDecorator(circle));
        circleWithBoth.draw(); // 输出:绘制圆形 添加边框 添加阴影
    }
}

# 反例

若不使用装饰器模式,通常需要通过继承或组合实现功能扩展,但会导致类数量爆炸或代码冗余:

# 继承方式

// 圆形添加边框
public class CircleWithBorder extends Circle {
    @Override
    public void draw() {
        super.draw();
        System.out.println("添加边框");
    }
}
// 圆形添加阴影
public class CircleWithShadow extends Circle {
    @Override
    public void draw() {
        super.draw();
        System.out.println("添加阴影");
    }
}
// 圆形同时添加边框和阴影(需单独定义)
public class CircleWithBorderAndShadow extends Circle {
    @Override
    public void draw() {
        super.draw();
        System.out.println("添加边框");
        System.out.println("添加阴影");
    }
}

# 组合方式

// 圆形添加边框(组合)
public class CircleWithBorder {
    private Circle circle;

    public CircleWithBorder(Circle circle) {
        this.circle = circle;
    }

    public void draw() {
        circle.draw();
        System.out.println("添加边框");
    }
}
// 圆形添加阴影(组合)
public class CircleWithShadow {
    private Circle circle;

    public CircleWithShadow(Circle circle) {
        this.circle = circle;
    }

    public void draw() {
        circle.draw();
        System.out.println("添加阴影");
    }
}

问题

1.继承方式中,每增加一种功能组合(如边框+阴影)需定义新类,导致类数量呈指数级增长(N功能×M对象 → N×M类)。

2.组合方式虽避免继承缺陷,但需为每种功能单独定义包装类,代码冗余且灵活性差。

# 原理

# 工作机制

装饰器模式通过递归包装实现功能扩展:

1.定义统一接口(如Shape),所有对象和装饰器均实现该接口。

2.装饰器基类(如ShapeDecorator)持有被包装对象,并委托其执行基础功能。

3.具体装饰器(如BorderDecorator)覆盖接口方法,在调用基础功能后追加新功能(如添加边框)。

4.多层装饰器可嵌套使用(如ShadowDecorator(BorderDecorator(Circle))),实现功能叠加。

# 缺点

1.设计复杂度增加:过度使用可能导致装饰器链过长,难以追踪执行流程。

2.装饰器依赖关系:若装饰器间存在执行顺序依赖(如边框必须在阴影前添加),需额外逻辑处理。

3.类型暴露风险:客户端可能依赖具体装饰器类型,违背面向接口编程原则。

总结

装饰器模式通过动态包装对象实现功能的灵活扩展,避免了继承导致的类爆炸问题,符合开闭原则。其核心在于将功能作为独立模块,通过组合方式叠加到对象上。适用于需要动态调整功能或避免复杂继承结构的场景,但需注意装饰器链的管理和依赖关系处理。



微信公众号

QQ交流群
原创网站开发,偏差难以避免。

如若发现错误,诚心感谢反馈。

愿你倾心相念,愿你学有所成。

愿你朝华相顾,愿你前程似锦。