概述
装饰模式(Decorator Pattern)是一种结构型设计模式,它允许向一个现有的对象添加新的功能,同时又不改变其结构。装饰模式通过创建一个装饰类来包装原始类,从而在保持类方法签名完整的前提下,提供了额外的功能。装饰模式比生成子类更灵活,能够动态地扩展对象的功能。
结构
装饰模式包含以下几个角色:
- 组件(Component):定义一个对象接口,可以给这些对象动态地添加职责。
- 具体组件(ConcreteComponent):实现组件接口的具体对象。
- 装饰(Decorator):实现组件接口,并持有一个组件对象的引用。
- 具体装饰(ConcreteDecorator):扩展装饰类,添加额外的功能。
示例代码
假设我们有一个应用程序需要为不同类型的消息添加不同的装饰(如加密和压缩)。
代码地址
组件接口
public interface IMessage
{
string GetContent();
}
具体组件
public class TextMessage : IMessage
{
private string _content;
public TextMessage(string content)
{
_content = content;
}
public string GetContent()
{
return _content;
}
}
装饰
public abstract class MessageDecorator : IMessage
{
protected IMessage _message;
protected MessageDecorator(IMessage message)
{
_message = message;
}
public abstract string GetContent();
}
具体装饰
public class EncryptedMessage : MessageDecorator
{
public EncryptedMessage(IMessage message) : base(message) { }
public override string GetContent()
{
return Encrypt(_message.GetContent());
}
private string Encrypt(string content)
{
// 简单的加密逻辑(仅示例)
return Convert.ToBase64String(Encoding.UTF8.GetBytes(content));
}
}
public class CompressedMessage : MessageDecorator
{
public CompressedMessage(IMessage message) : base(message) { }
public override string GetContent()
{
return Compress(_message.GetContent());
}
private string Compress(string content)
{
// 简单的压缩逻辑(仅示例)
return $"Compressed({content})";
}
}
客户端代码
class Program
{
static void Main(string[] args)
{
IMessage message = new TextMessage("Hello, World!");
// 添加加密装饰
IMessage encryptedMessage = new EncryptedMessage(message);
Console.WriteLine(encryptedMessage.GetContent());
// 添加压缩装饰
IMessage compressedMessage = new CompressedMessage(message);
Console.WriteLine(compressedMessage.GetContent());
// 添加加密和压缩装饰
IMessage encryptedAndCompressedMessage = new CompressedMessage(encryptedMessage);
Console.WriteLine(encryptedAndCompressedMessage.GetContent());
}
}
应用场景
装饰模式适用于以下场景:
- 当你希望在不改变类文件或使用继承的情况下,动态地给对象添加功能时。
- 当你希望可以动态地撤销或添加功能时。
- 当通过生成子类来扩展功能的方式难以实现或不合适时。
优缺点
优点
- 灵活性高:装饰模式允许你在运行时动态地组合对象,增加或撤销功能。
- 遵循单一职责原则:通过将功能划分到不同的类中,装饰模式使得每个类只关注一个特定的功能。
缺点 - 增加代码复杂性:使用装饰模式会增加系统中类和对象的数量,导致代码复杂性增加。
- 调试困难:由于功能是通过多个装饰类动态组合的,调试时可能会比较困难。