C#设计模式之结构类模式:装饰模式
2021-04-25 06:25
标签:div sso mod itblog 场景 abstract memory images 复杂 动态的给一个对象添加一些额外的职责。就添加功能来说,它相比生成子类更为灵活。 在软件开发中,我们经常想要对一类对象添加不同的功能,例如要给手机添加贴膜,手机挂件,手机外壳等,如果此时利用继承来实现的话,就需要定义无数的类,如StickerPhone(贴膜是手机类)、AccessoriesPhone(挂件手机类)等,这样就会导致 ”子类爆炸“问题,为了解决这个问题,我们可以使用装饰者模式来动态地给一个对象添加额外的职责。下面让我们看看装饰者模式。 装饰者模式以对客户透明的方式动态地给一个对象附加上更多的责任,装饰者模式相比生成子类可以更灵活地增加功能。 这里以手机和手机配件的例子来演示装饰者模式的实现,具体代码如下: 此时客户端调用代码如下: 从上面的客户端代码可以看出,客户端可以动态地将手机配件增加到手机上,如果需要添加手机外壳时,此时只需要添加一个继承Decorator的手机外壳类,从而,装饰者模式扩展性也非常好。 实现完了装饰者模式之后,让我们看看装饰者模式实现中类之间的关系,具体见下图: 在装饰者模式中各个角色有: 看完装饰者模式的详细介绍之后,我们继续分析下它的优缺点。 缺点:装饰者模式会导致设计中出现许多小对象,如果过度使用,会让程序变的更复杂。并且更多的对象会是的差错变得困难,特别是这些对象看上去都很像。 下面让我们看看装饰者模式具体在哪些情况下使用,在以下情况下应当使用装饰者模式: 在.NET 类库中也有装饰者模式的实现,该类就是System.IO.Stream,下面看看Stream类结构: 上图中,BufferedStream、CryptoStream和GZipStream其实就是两个具体装饰类,这里的装饰者模式省略了抽象装饰角色(Decorator)。下面演示下客户端如何动态地为MemoryStream动态增加功能的 到这里,装饰者模式的介绍就结束了,装饰者模式采用对象组合而非继承的方式实现了再运行时动态地扩展对象功能的能力,而且可以根据需要扩展多个功能,避免了单独使用继承带来的 ”灵活性差“和”多子类衍生问题“。同时它很好地符合面向对象设计原则中 ”优先使用对象组合而非继承“和”开放-封闭“原则。 C#设计模式之结构类模式:装饰模式 标签:div sso mod itblog 场景 abstract memory images 复杂 原文地址:http://www.cnblogs.com/pangjianxin/p/7921598.html定义(Decorator Pattern):
一、引言
二、装饰者模式的详细介绍
2.1 定义
2.2 装饰者模式实现
///
class Customer
{
static void Main(string[] args)
{
// 我买了个苹果手机
Phone phone = new ApplePhone();
// 现在想贴膜了
Decorator applePhoneWithSticker = new Sticker(phone);
// 扩展贴膜行为
applePhoneWithSticker.Print();
Console.WriteLine("----------------------\n");
// 现在我想有挂件了
Decorator applePhoneWithAccessories = new Accessories(phone);
// 扩展手机挂件行为
applePhoneWithAccessories.Print();
Console.WriteLine("----------------------\n");
// 现在我同时有贴膜和手机挂件了
Sticker sticker = new Sticker(phone);
Accessories applePhoneWithAccessoriesAndSticker = new Accessories(sticker);
applePhoneWithAccessoriesAndSticker.Print();
Console.ReadLine();
}
2.3 装饰者模式的类图
三、装饰者模式的优缺点
优点:
四、使用场景
五、.NET中装饰者模式的实现
MemoryStream memoryStream = new MemoryStream(new byte[] {95,96,97,98,99});
// 扩展缓冲的功能
BufferedStream buffStream = new BufferedStream(memoryStream);
// 添加加密的功能
CryptoStream cryptoStream = new CryptoStream(memoryStream,new AesManaged().CreateEncryptor(),CryptoStreamMode.Write);
// 添加压缩功能
GZipStream gzipStream = new GZipStream(memoryStream, CompressionMode.Compress, true);
六、总结