菜单

风干咸鱼
风干咸鱼
发布于 2025-06-06 / 8 阅读
0
0

装饰器模式

1、基本介绍

装饰器设计模式是一种结构型设计模式,它允许动态地为对象添加新的行为。它通过创建一个包装器来实现,即将对象放入一个装饰器类中,再将装饰器类放入另一个装饰器类中,以此类推,形成一条包装链。这样就可以在不改变原有对象的情况下,动态地添加新的行为或修改原有行为

2、案例

1、定义一个抽象(抽象类或接口),作为被装饰对象的基类

public interface Component {
    void operation();
}

2、定义一个被装饰对象,实现基类

public class ConcreteComponent implements Component{
    @Override
    public void operation() {
        System.out.println("我是被装饰对象");
    }
}

3、定义一个抽象装饰器类,实现基类,并将被装饰对象作为属性

public class Decorator implements Component{
    // 持有被装饰对象,装饰器模式通过组合的方式进行装饰而非继承
    private Component component;

    public Decorator(Component component) {
        this.component = component;
    }

    @Override
    public void operation() {
        component.operation();
    }
}

4、定义第一个装饰器/包装器,基础抽象装饰器类

public class DecoratorOne extends Decorator{
    public DecoratorOne(Component component) {
        // 给父类Component赋值
        super(component);
    }

    @Override
    public void operation() {
        // 对被装饰器类做方法前后做增强
        System.out.println("装饰器一方法前增强");
        super.operation();
        System.out.println("装饰器一方法后增强");
    }
}

5、定义第二个装饰器/包装器,基础抽象装饰器类

public class DecoratorTwo extends Decorator{
    public DecoratorTwo(Component component) {
        // 给父类Component赋值
        super(component);
    }

    @Override
    public void operation() {
        // 对被装饰器类做方法前后做增强
        System.out.println("装饰器二方法前增强");
        super.operation();
        System.out.println("装饰器二方法后增强");
    }
}

6、装饰器模式的使用

public static void main(String[] args) {
    // 1、创建一个原始对象/被装饰对象
    Component component = new ConcreteComponent();
    // 2、进行第一次包装,此时的component实例DecoratorOne(用包装类替换了原始类),已进行第一次增强
    component = new DecoratorOne(component);
    // 3、进行第二次包装,此时的component实例DecoratorTwo,已进行第二次增强
    component = new DecoratorTwo(component);
    // 4、调用增强后的方法
    component.operation();
}

7、运行结果

装饰器二方法前增强
装饰器一方法前增强
我是被装饰对象
装饰器一方法后增强
装饰器二方法后增强

3、一个极易理解的使用场景 - IO流

InputStream inputStream = new FileInputStream("D://aa.txt");
// 通过包装类让inputStream支持带混存功能的读取数据
inputStream = new BufferedInputStream(inputStream);
// 继续通过包装类进行增强
inputStream = new DataInputStream(inputStream);

4、都是对原始类做增强,装饰器模式和代理模式有什么区别?

先回顾一下代理模式的核心功能:1、屏蔽被代理对象。2、对被代理类做增强

  1. 装饰器模式主要解决继承关系过于复杂的问题,通常通过组合来代替继承。而不需要像代理对象屏蔽原始对象(直接操作代理对象)。而装饰器设计模式,你想使用原始对象就使用原始对象,想使用包装对象就使用包装对象

  2. 装饰器类附加的是跟原始类相关功能增强(比如给查询缓存的对象添加LRU、LFU等过期策略),而代理类通常是附加跟原始类无关的功能(比如打印日志、权限控制等)

5、为什么要用组合来代替继承?

请了解组合优于继承设计原则


评论