介绍
装饰器模式
装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许你动态地将行为添加到现有的对象中,而无需修改其代码。装饰器模式提供了比继承更灵活的功能扩展方式。
主要角色
- Component:定义一个对象接口,可以给这些对象动态地添加职责。
- ConcreteComponent:具体实现Component接口的类,即被装饰器装饰的原始对象。
- Decorator:装饰器基类,持有一个Component对象的引用,并且与Component接口保持一致。
- ConcreteDecorator:具体的装饰器类,实现具体要向Component添加的功能。
Java代码实现示例
我们将通过一个简单的例子来演示装饰器模式。假设我们有一个基本的消息发送系统,能够发送简单的文本消息。现在我们希望能够在发送消息之前对消息进行加密,并在发送之后记录日志。
定义组件接口和具体组件
// Component
interface Message {
String send();
}
// ConcreteComponent 被装饰者
class TextMessage implements Message {
private String content;
public TextMessage(String content) {
this.content = content;
}
@Override
public String send() {
return "Sending message: " + content;
}
}
定义装饰器基类和具体装饰器
// Decorator 装饰者 (增强)
abstract class MessageDecorator implements Message {
protected Message wrapped;
public MessageDecorator(Message wrapped) {
this.wrapped = wrapped;
}
@Override
public String send() {
return wrapped.send();
}
}
// ConcreteDecoratorA
class EncryptedMessageDecorator extends MessageDecorator {
public EncryptedMessageDecorator(Message wrapped) {
super(wrapped);
}
@Override
public String send() {
String originalMessage = wrapped.send();
String encryptedMessage = encrypt(originalMessage);
return "Encrypted(" + encryptedMessage + ")";
}
private String encrypt(String message) {
// 简单的模拟加密逻辑
StringBuilder encrypted = new StringBuilder(message);
return encrypted.reverse().toString();
}
}
// ConcreteDecoratorB
class LoggedMessageDecorator extends MessageDecorator {
public LoggedMessageDecorator(Message wrapped) {
super(wrapped);
}
@Override
public String send() {
String result = wrapped.send();
log(result);
return result;
}
private void log(String message) {
System.out.println("Logging: " + message);
}
}
使用装饰器模式
public class Main {
public static void main(String[] args) {
Message message = new TextMessage("Hello, World!");
// 使用加密装饰器
Message encryptedMessage = new EncryptedMessageDecorator(message);
System.out.println(encryptedMessage.send()); // 输出加密后的消息
// 使用日志装饰器
Message loggedMessage = new LoggedMessageDecorator(message);
System.out.println(loggedMessage.send()); // 日志消息并输出
// 组合装饰器
Message encryptedLoggedMessage = new LoggedMessageDecorator(new EncryptedMessageDecorator(message));
System.out.println(encryptedLoggedMessage.send()); // 输出加密并记录日志的消息
}
}
运行结果
解释
- Message接口:定义了发送消息的方法
send
。 - TextMessage类:实现了Message接口,表示一个简单的文本消息。
- MessageDecorator抽象类:也是Message接口的实现,但它持有一个Message对象,并在其方法调用时委托给该对象。
- EncryptedMessageDecorator类:扩展MessageDecorator,通过重写
send
方法添加加密功能。 - LoggedMessageDecorator类:扩展MessageDecorator,通过重写
send
方法添加日志记录功能。
通过这种方式,我们可以在不修改原始类的情况下,为对象动态添加新功能。这提供了一种比继承更灵活、可扩展性更强的方式来增强对象的行为。
类图
装饰器模式(Decorator Pattern)是一种结构型设计模式,允许你通过将对象放入包装对象中来动态地添加行为,相比继承更加灵活。以下是装饰器模式的类图示例:
+----------------------------------+
| Component |
+----------------------------------+
| operation(): void |
+----------------------------------+
^
|
|
+-----------------------------+
| ConcreteComponent |
+-----------------------------+
| operation(): void |
+-----------------------------+
△
|
+-----------------------------+
| Decorator |
+-----------------------------+
| component: Component |
| operation(): void |
+-----------------------------+
|
|
+-----------------------------+
| ConcreteDecoratorA |
+-----------------------------+
| operation(): void |
| addedBehavior(): void |
+-----------------------------+
△
|
+-----------------------------+
| ConcreteDecoratorB |
+-----------------------------+
| operation(): void |
| addedBehavior(): void |
+-----------------------------+
说明:
-
Component(抽象构件):
- 定义一个对象接口,可以给这些对象动态地添加职责。
operation()
是抽象操作,可以是接口或者抽象类。
-
ConcreteComponent(具体构件):
- 定义一个具体的对象,也可以给这个对象添加一些职责。
-
Decorator(装饰器抽象类):
- 持有一个 Component 对象的引用,并定义一个与 Component 接口一致的接口。
- 可以用来装饰 Component 对象,增加其行为。
-
ConcreteDecoratorA、ConcreteDecoratorB(具体装饰器):
- 负责给具体构件对象添加额外的职责。
类图说明:
- Component 是抽象构件角色,定义了对象接口。
- ConcreteComponent 是具体构件角色,实现了 Component 接口的具体对象。
- Decorator 是装饰器抽象类,持有一个 Component 对象的引用,并定义了与 Component 接口一致的接口。
- ConcreteDecoratorA、ConcreteDecoratorB 是具体装饰器类,实现了 Decorator 定义的接口,负责给 Component 对象添加额外的职责。
装饰器模式的核心是通过组合而非继承来扩展对象的功能,使得动态添加功能更加灵活。