跳转到内容

装饰 (Decorator)

装饰 (Decorator) 是一种结构型设计模式,动态地给对象增加一些职责(即增加其额外功能)。相比继承,装饰更为灵活,可任意组合多种装饰。

  • 希望在不修改原有类的前提下,为对象增加额外行为(如日志、缓存、权限)。
  • 若用继承,每多一种组合就多一个子类,类爆炸且不够灵活。
  • 定义与被装饰对象相同的组件接口 (Component)具体组件 (ConcreteComponent) 实现之。
  • 装饰器 (Decorator) 实现 Component 并持有一个 Component,在自身方法中先调用被装饰对象的方法,再执行额外逻辑(或反之)。
  • 具体装饰器 (ConcreteDecorator) 继承 Decorator,增加具体职责。可多层包装,形成链式增强。
classDiagram
    class Component {
        <<interface>>
        +operation()* void
    }
    class ConcreteComponent {
        +operation() void
    }
    class Decorator {
        <<abstract>>
        #component Component
        +operation() void
    }
    class ConcreteDecoratorA {
        +operation() void
    }
    class ConcreteDecoratorB {
        +operation() void
    }
    Component <|.. ConcreteComponent
    Component <|-- Decorator
    Decorator o-- Component
    Decorator <|-- ConcreteDecoratorA
    Decorator <|-- ConcreteDecoratorB
public interface Component {
void operation();
}
public class ConcreteComponent implements Component {
@Override
public void operation() {
System.out.print("核心逻辑 ");
}
}
public abstract class Decorator implements Component {
protected Component component;
public Decorator(Component component) {
this.component = component;
}
@Override
public void operation() {
component.operation();
}
}
public class ConcreteDecoratorA extends Decorator {
public ConcreteDecoratorA(Component component) {
super(component);
}
@Override
public void operation() {
System.out.print("[装饰A-前] ");
super.operation();
System.out.print("[装饰A-后] ");
}
}
public class ConcreteDecoratorB extends Decorator {
public ConcreteDecoratorB(Component component) {
super(component);
}
@Override
public void operation() {
System.out.print("[装饰B-前] ");
super.operation();
System.out.print("[装饰B-后] ");
}
}
// 客户端:可任意叠装饰
public class Client {
public static void main(String[] args) {
Component c = new ConcreteDecoratorB(new ConcreteDecoratorA(new ConcreteComponent()));
c.operation();
// 输出: [装饰B-前] [装饰A-前] 核心逻辑 [装饰A-后] [装饰B-后]
}
}

装饰通过“包装同一接口”的方式,在运行时动态叠加职责,避免子类膨胀,符合开闭原则。