<html><head><meta http-equiv="Content-type" content="text/html; charset=gb2312"></head><center><div width=700 style='width:700px;border:0px solid;' align=left>
<div align=center><font style='font-size:18pt'><b>.Net中的设计模式——Decorator模式</b></font></div><br><br>
导读:
<br>
<br>
<br>
讲解.Net Framework中的Decorator模式。
<br>
<br>
<br>
请访问:.Net中的设计模式——Decorator模式
<br>
<br>
<br>
<STRONG>一、模式概述</STRONG>
<br>
<br>
<br>
一个场景是我们要为一个对象动态添加新的职责,这个职责并不修改原有的行为,而是在原有行为基础上添加新的功能,就好比装饰工人为一座新居的墙上涂抹上色彩缤纷的颜料一般。
<br>
<br>
<br>
从我们拥有的面向对象的知识出发,为一个对象增加新的职责,完全可以利用继承机制,然而再通过实例化派生的子类,来获得新增的职责。由于需要在原有行为基础上添加新功能,此时父类的方法应该为虚方法,例如用户登录行为:
<br>
<br>
<br>
public class User
<br>
<br>
<br>
{
<br>
<br>
<br>
public virtual void SignIn()
<br>
<br>
<br>
{
<br>
<br>
<br>
Console.WriteLine("The User Sign In.");
<br>
<br>
<br>
}
<br>
<br>
<br>
}
<br>
<br>
<br>
如果需要为用户登录行为增加权限验证的职责,可以定义一个子类继承User类:
<br>
<br>
<br>
public class SecurityUser:User
<br>
<br>
<br>
{
<br>
<br>
<br>
public override void SignIn()
<br>
<br>
<br>
{
<br>
<br>
<br>
if (IsValid())
<br>
<br>
<br>
{
<br>
<br>
<br>
base.SignIn();
<br>
<br>
<br>
}
<br>
<br>
<br>
else
<br>
<br>
<br>
{
<br>
<br>
<br>
throw new NotAuthorizationException();
<br>
<br>
<br>
}
<br>
<br>
<br>
}
<br>
<br>
<br>
private bool IsValid()
<br>
<br>
<br>
{
<br>
<br>
<br>
//略;
<br>
<br>
<br>
return true;
<br>
<br>
<br>
}
<br>
<br>
<br>
}
<br>
<br>
<br>
实现的类图如下:
<br>
<br>
<br>
<div align=center><IMG src="http://www.cnblogs.com/images/cnblogs_com/wayfarer/patterns/dec01.gif"></div>
<br>
<br>
<br>
<br>
<br>
<br>
然而继承机制的一个局限是它只能静态地添加对象职责,一旦添加的职责有变,例如客户需求为登录行为添加日志记录功能,虽然我们可以再定义一个子类,重写SignIn()方法,然而我们却不能控制职责添加的时机与方式。此外,当User具有本身的继承体系时,则其并不能重用SecurityUser的职责。例如,User同时具有另外一个子类Employee,则Employee类的登录行为仍然沿用了其父类User的登录行为,而不具备权限验证的职责。如果需求要求Employee同样要验证登录权限,就必须再为它创建一个子类SecurityEmployee,如图:
<br>
<br>
<br>
<div align=center><IMG src="http://www.cnblogs.com/images/cnblogs_com/wayfarer/patterns/dec02.gif"></div>
<br>
<br>
<br>
<br>
<br>
<br>
这样的结果会导致类的数量会随着需求的变化而无限量的增加,同时有关权限验证的职责也没有能够得到充分的重用,这显然违背了面向对象设计的精神。
<br>
<br>
<br>
还有一个添加职责的办法,就是利用组合,将原有的对象嵌入到一个新的类中,由此来完成对新职责的添加,例如:
<br>
<br>
<br>
public class SecurityUser
<br>
<br>
<br>
{
<br>
<br>
<br>
private User m_user;
<br>
<br>
<br>
public User User
<br>
<br>
<br>
{
<br>
<br>
<br>
get {return m_user;}
<br>
<br>
<br>
set {m_user = value;}
<br>
<br>
<br>
}
<br>
<br>
<br>
public void SignIn()
<br>
<br>
<br>
{
<br>
<br>
<br>
if (IsValid())
<br>
<br>
<br>
{
<br>
<br>
<br>
m_user.SignIn();
<br>
<br>
<br>
}
<br>
<br>
<br>
else
<br>
<br>
<br>
{
<br>
<br>
<br>
throw new NotAuthorizationException();
<br>
<br>
<br>
}
<br>
<br>
<br>
}
<br>
<br>
<br>
private bool IsValid()
<br>
<br>
<br>
{
<br>
<br>
<br>
//略;
<br>
<br>
<br>
return true;
<br>
<br>
<br>
}
<br>
<br>
<br>
}
<br>
<br>
<br>
实现的类图如下:
<br>
<br>
<br>
<div align=center><IMG src="http://www.cnblogs.com/images/cnblogs_com/wayfarer/patterns/dec03.gif"></div>
<br>
<br>
<br>
<br>
<br>
<br>
比起继承机制而言,组合方式更加的灵活,尤其当面对User具有自身的继承体系时,如上的设计不需要任何修改,就能从容的应对:
<br>
<br>
<br>
<div align=center><IMG src="http://www.cnblogs.com/images/cnblogs_com/wayfarer/patterns/dec04.gif"></div>
<br>
<br>
<br>
<br>
<br>
<br>
此时我们只需要将Employee对象赋给SecurityUser中的User属性就可以实现对Employee权限验证的登录。因此,我们避免了此前采用继承机制所面临的两个问题:
<br>
<br>
<br>
1、 类的无限量增加(所谓的“类爆炸”);
<br>
<br>
<br>
2、 权限验证职责的不可重用。
<br>
<br>
<br>
然而组合却失去了继承的许多优势,其中,不具备对象的多态特质,就是最大的一个局限。例如,如下创建对象的方式就是错误的:
<br>
<br>
<br>
User user = new SecurityUser();
<br>
<br>
<br>
当一个方法体现为对User的操作时,此时SecurityUser就无法对User类型的对象进行替代,这就限制了软件的可扩展性。例如,在表示层逻辑中,会有一个登录页面将调用SignIn方法:
<br>
<br>
<br>
public class LoginPage
<br>
<br>
<br>
{
<br>
<br>
<br>
public static void SignIn(User user);
<br>
<br>
<br>
}
<br>
<br>
<br>
在这种情况下,SecurityUser对象就无法做为参数传入,那么,我们在前面所作的职责添加的努力岂不就是付诸东流了吗?
<br>
<br>
<br>
如果仔细观察继承与组合的优劣,我们发现如果将继承机制与组合方式两者结合起来,将会起到意想不到的效果,此时,各自的优点弥补了各自的缺点,完美地解决了“为对象动态添加新的职责”的需求。
<br>
<br>
<br>
新的解决方案如下图所示:
<br>
<br>
<br>
<div align=center><IMG src="http://www.cnblogs.com/images/cnblogs_com/wayfarer/patterns/dec05.gif"></div>
<br>
<br>
<br>
<br>
<br>
<br>
实际上,如上的类图结构就是设计模式中的Decorator模式,User是被装饰的对象,而SecurityUser则是Decorator,也就是我们所谓的“装饰工”。在这里,SecurityUser是一个具体类,如果有新的装饰需求,例如之前提到的增加日志记录功能,同样需要建立装饰类。此时,对于具体的装饰类而言,具有一些相同的逻辑,在此前提下,可以为其增加一个Decorator抽象类:
<br>
<br>
<br>
<div align=center><IMG src="http://www.cnblogs.com/images/cnblogs_com/wayfarer/patterns/dec06.gif"></div>
<br>
<br>
<br>
<br>
<br>
<br>
此时,我将原来的SecurityUser类更名为SecuritySignInDecorator,便于理解。SignInDecorator是一个抽象类,继承了User类,同时User类对象又作为一个属性存在于SignInDecorator抽象类中。注意,这里的组合方式其实有多种实现方式。如作为一个属性�
没有合适的资源?快使用搜索试试~ 我知道了~
PETSHOP4.0详细分析集合
共9个文件
html:6个
doc:3个
需积分: 0 9 下载量 183 浏览量
2008-10-02
16:56:39
上传
评论
收藏 571KB RAR 举报
温馨提示
PetShop是一个小型的项目,系统架构与代码都比较简单,却也凸现了许多颇有价值的设计与开发理念。本系资料对PetShop作一个全方位的解剖
资源详情
资源评论
资源推荐
收起资源包目录
PETSHOP4.0详细分析集合.rar (9个子文件)
PETSHOP4.0详细分析
《解剖PetShop》系列之六.doc 537KB
《解剖PetShop》系列之五.html 24KB
.Net中的设计模式——Decorator模式.html 24KB
《解剖PetShop》系列之一.html 9KB
深入剖析PETSHOP4.0.doc 1010KB
《解剖PetShop》系列之三.html 18KB
.Net中的设计模式——Strategy模式.html 12KB
《解剖PetShop》系列之二.html 14KB
《解剖PetShop》系列之四.doc 123KB
共 9 条
- 1
红烧清蒸
- 粉丝: 1
- 资源: 1
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0