1. 基本概念

通常情况下,扩展类的功能可以通过继承实现,但是扩展越多,子类越多,装饰模式(Decorator Pattern, 结构型设计模式)可以在不定义子类的情况下动态的给对象添加一些额外的功能。具体的做法是将原始对象放入包含行为的特殊封装类(装饰类),从而为原始对象动态添加新的行为,而无需修改其代码。

举个简单的例子,假设你有一个基础的图形类,你想要为图形类添加颜色、边框、阴影等功能,如果每个功能都实现一个子类,就会导致产生大量的类,这时就可以考虑使用装饰模式来动态地添加,而不需要修改图形类本身的代码,这样可以使得代码更加灵活、更容易维护和扩展。

2. 基本结构

装饰模式包含以下四个主要角色:

image-20240512215825818

  • 组件Component:通常是抽象类或者接口,是具体组件和装饰者的父类,定义了具体组件需要实现的方法,比如说我们定义Coffee为组件。
  • 具体组件ConcreteComponent: 实现了Component接口的具体类,是被装饰的对象
  • 装饰类Decorator: 一个抽象类,给具体组件添加功能,但是具体的功能由其子类具体装饰者完成,持有一个指向Component对象的引用。
  • 具体装饰类ConcreteDecorator: 扩展Decorator类,负责向Component对象添加新的行为,加牛奶的咖啡是一个具体装饰类,加糖的咖啡也是一个具体装饰类。

3. 基本实现

装饰模式的实现包括以下步骤:

  1. 定义Component接口
1
2
3
4
// 组件接口
public interface Component {
void operation();
}
  1. 实现 ConcreteComponent
1
2
3
4
5
6
7
// 具体组件
public class ConcreteComponent implements Component {
@Override
public void operation() {
System.out.println("ConcreteComponent operation");
}
}
  1. 定义Decorator装饰类,继承自Component
1
2
3
4
5
6
7
8
9
10
11
12
13
// 定义一个抽象的装饰者类,继承自Component
public abstract class Decorator implements Component {
protected Component component;

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

@Override
public void operation() {
component.operation();
}
}
  1. 定义具体的装饰者实现,给具体组件对象添加功能。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 具体的装饰者实现
public class ConcreteDecorator extends Decorator {
public ConcreteDecorator(Component component) {
super(component);
}

// 根据需要添加额外的方法

@Override
public void operation() {
// 可以在调用前后添加额外的行为
System.out.println("Before operation in ConcreteDecorator");
super.operation();
System.out.println("After operation in ConcreteDecorator");
}
}
  1. 在客户端使用
1
2
3
4
5
6
7
8
9
10
11
12
public class Main {
public static void main(String[] args) {
// 创建具体组件
Component concreteComponent = new ConcreteComponent();

// 使用具体装饰者包装具体组件
Decorator decorator = new ConcreteDecorator(concreteComponent);

// 调用操作
decorator.operation();
}
}

4. 应用场景

装饰模式通常在以下几种情况使用:

  • 当需要给一个现有类添加附加功能,但由于某些原因不能使用继承来生成子类进行扩充时,可以使用装饰模式。
  • 动态的添加和覆盖功能:当对象的功能要求可以动态地添加,也可以再动态地撤销时可以使用装饰模式。

在Java的I/O库中,装饰者模式被广泛用于增强I/O流的功能。例如,BufferedInputStreamBufferedOutputStream这两个类提供了缓冲区的支持,通过在底层的输入流和输出流上添加缓冲区,提高了读写的效率,它们都是InputStreamOutputStream的装饰器。BufferedReaderBufferedWriter这两个类与BufferedInputStreamBufferedOutputStream类似,提供了字符流的缓冲功能,是Reader和Writer的装饰者。


本站由 卡卡龙 使用 Stellar 1.29.1主题创建

本站访问量 次. 本文阅读量 次.