.NET设计模式研究之装饰模式
发布时间:2006-03-04 11:54:52 来源:博客园 网友评论 0 条 .NET 中的装饰模式
1..NET中Decorator模式一个典型的运用就是关于Stream,它存在着如下的类结构:

图8
可以看到, BufferedStream和CryptoStream其实就是两个包装类,这里的Decorator模式省略了抽象装饰角色(Decorator),示例代码如下:
| class Program { public static void Main(string[] args) { MemoryStream ms =new MemoryStream(new byte[] { 100,456,864,222,567}); //扩展了缓冲的功能 BufferedStream buff = new BufferedStream(ms); //扩展了缓冲,加密的功能 CryptoStream crypto = new CryptoStream(buff); } } |
通过反编译,可以看到BufferedStream类的代码(只列出部分),它是继承于Stream类:
| public sealed class BufferedStream : Stream { // Methods private BufferedStream(); public BufferedStream(Stream stream); public BufferedStream(Stream stream, int bufferSize); // Fields private int _bufferSize; private Stream _s; } |
2.在Enterprise Library中的DAAB中有一个DbCommandWrapper的包装类,它实现了对IDbCommand类的包装并提供了参数处理的功能。结构图如下:

图9
示意性代码如下:
| public abstract class DBCommandWrapper : MarshalByRefObject, IDisposable {} public class SqlCommandWrapper : DBCommandWrapper {} public class OracleCommandWrapper : DBCommandWrapper {} |
效果及实现要点
1.Component类在Decorator模式中充当抽象接口的角色,不应该去实现具体的行为。而且Decorator类对于Component类应该透明,换言之Component类无需知道Decorator类,Decorator类是从外部来扩展Component类的功能。
2.Decorator类在接口上表现为is-a Component的继承关系,即Decorator类继承了Component类所具有的接口。但在实现上又表现为has-a Component的组合关系,即Decorator类又使用了另外一个Component类。我们可以使用一个或者多个Decorator对象来“装饰”一个Component对象,且装饰后的对象仍然是一个Component对象。
3.Decortor模式并非解决“多子类衍生的多继承”问题,Decorator模式的应用要点在于解决“主体类在多个方向上的扩展功能”——是为“装饰”的含义。
4.对于Decorator模式在实际中的运用可以很灵活。 如果只有一个ConcreteComponent类而没有抽象的Component类,那么Decorator类可以是ConcreteComponent的一个子类。

图10
如果只有一个ConcreteDecorator类,那么就没有必要建立一个单独的Decorator类,而可以把Decorator和ConcreteDecorator的责任合并成一个类。

图11
5.Decorator模式的优点是提供了比继承更加灵活的扩展, 通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合。
6.由于使用装饰模式,可以比使用继承关系需要较少数目的类。使用较少的类,当然使设计比较易于进行。但是,在另一方面,使用装饰模式会产生比使用继承关系更多的对象。更多的对象会使得查错变得困难,特别是这些对象看上去都很相像。
适用性
在以下情况下应当使用装饰模式:
1.需要扩展一个类的功能,或给一个类增加附加责任。
2.需要动态地给一个对象增加功能,这些功能可以再动态地撤销。
3.需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变得不现实。
总结
Decorator模式采用对象组合而非继承的手法,实现了在运行时动态的扩展对象功能的能力,而且可以根据需要扩展多个功能,避免了单独使用继承带来的“灵活性差”和“多子类衍生问题”。同时它很好地符合面向对象设计原则中“优先使用对象组合而非继承”和“开放-封闭”原则。
- 推荐阅讯
- ASP.NET 2.0中执行数据库操作命令之二
- ASP.NET2.0数据库之SQL Server安全性
- 10天学会ASP.net之第九天
- ASP.NET 2.0站点登录、导航与权限管理
- ASP.NET Atlas简单控件介绍之界面控件
- .NET正则表达式使用高级技巧之反向引用
- ASP.NET中绑定枚举类型
- .NET中如何在调用COM时得到返回参数值
- 在ASP.NET应用中插入flash动画
- ASP.NET中实现大结果集分页研讨
- 阅读排行
- 1.用ASP.NET 2.0设计网络在线投票系统
- 2.在ASP.Net 2.0中实现多语言界面的方法
- 3.轻松加密ASP.NET 2.0 Web程序配置信息
- 4.在ASP.NET中使用AJAX的简单方法
- 5..NET 2.0中的企业库异常处理块简述
- 6.面向.NET开发人员的Ajax 技术平台策略
- 7.揭开ASP.NET中Cookie编程的奥秘
- 8.ASP.NET2.0服务器控件之创建自定义控件
- 9.ASP.NET2.0中Gridview中数据操作技巧
- 10.ASP.NET 2.0发送电子邮件全面剖析之二
- 专题教程
- Windows Server-Windows Server文档-Windows Server新闻-Windows Ser PostgreSQL-PostgreSQL文档-PostgreSQL新闻-PostgreSQL专家
- WebLogic-WebLogic文档-WebLogic新闻-WebLogic专家 FreeBSD-FreeBSD文档-FreeBSD新闻-FreeBSD专家
- Linux-内核 GUI KDE Gnome DNS FTP 安全 安装-Linux专区 Windows-AD IIS ServerCore 虚拟化 安全 HPC-Windows专区
- 大话G游 专题:手机病毒揭密
- ARP攻击防范与解决方案 路由故障处理手册
