Skip to content

装饰模式

装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许在不修改现有对象结构的情况下,动态地给对象添加新的功能。这种模式通过将对象包装在装饰器类中来实现功能的扩展,从而提供了一种比继承更灵活的替代方案。

核心思想

  • 组合而非继承:使用组合的方式而不是通过继承来扩展对象的功能。
  • 透明性:客户端代码可以透明地使用被装饰的对象,就像使用原始对象一样。
  • 递归包装:可以多次应用装饰器,形成一个装饰器链,每个装饰器都可以增加额外的行为。

优点

  • 灵活性高:可以在运行时动态地添加或移除功能。
  • 遵循开闭原则:对扩展开放,对修改关闭,即可以在不修改原有代码的基础上增加新功能。
  • 避免类爆炸:相比于通过继承来实现多种功能组合,装饰器模式减少了子类的数量,避免了类层次结构的过度膨胀。

缺点

  • 复杂度增加:随着装饰器数量的增加,系统的复杂性也会增加,可能会导致难以理解和维护。
  • 多层装饰:如果装饰器层级过多,可能会影响性能,并且调试变得困难。

使用场景

  • 当需要向一个对象添加职责,但又不想使用子类时。
  • 当希望能够在运行时动态地为对象添加或移除功能。
  • 当有多个可选的行为需要组合应用到对象上时,例如文本编辑器中的格式化选项、窗口系统的边框和滚动条等。

实现方式

装饰器模式通常包含以下几个角色:

  1. Component(组件):定义了一个对象接口,可以给这些对象动态地添加职责。
  2. ConcreteComponent(具体组件):定义了一个具体的对象,也可以给这个对象添加一些职责。
  3. Decorator(装饰器):持有一个Component对象的引用,并定义了一个与Component接口一致的接口。
  4. ConcreteDecorator(具体装饰器):向组件添加职责。

示例:

组件

java
public interface Costume {

    void wear();
}

具体组件

java
@Slf4j
public  class Person implements Costume {

    private String name;

    public Person(String name) {
        this.name = name;
    }

    @Override
    public void wear() {
       log.info("装扮的{}" ,name);
    }
}

装饰器

java
public abstract class CostumeDecorator implements Costume {

    protected Costume costume;

    protected CostumeDecorator(Costume costume) {
        this.costume = costume;
    }

    @Override
    public void wear() {
        Optional
                .ofNullable(costume)
                .ifPresent(Costume::wear);
    }
}

装饰器具体实现:

java
@Slf4j
public class JeansDecorator extends  CostumeDecorator{

    private String color;

    public JeansDecorator(Costume costume,String color) {
        super(costume);
        this.color = color;
    }
    @Override
    public void wear() {
        log.info("{}牛仔裤",color);
        super.wear();
    }
}

@Slf4j
public class TShirtDecorator extends CostumeDecorator {

    protected TShirtDecorator(Costume costume) {
        super(costume);
    }

    @Override
    public void wear() {
        log.info("T恤");
        super.wear();
    }
}

调用

java
public class Main {
    public static void main(String[] args) {
        Costume person = new Person("张三");
        person = new TShirtDecorator(person);
        person = new JeansDecorator(person,"蓝色");
        person.wear();

    }
}

打印

java
11:11:03.010 [main] INFO com.lj.decorator.Jeans -- 蓝色牛仔裤
11:11:03.015 [main] INFO com.lj.decorator.TShirt -- T恤
11:11:03.015 [main] INFO com.lj.decorator.Person -- 装扮的张三
最近更新