您的位置:首页 > 其它

我读设计模式之装饰模式(Decorator Pattern)

2008-07-23 11:41 701 查看
随感

可能是对继承的理解不是很透彻,也或者习惯了静态的定义和使用继承,今天刚看到装饰模式的时候,却是晕了好一会。

TerryLee的Blog中对装饰模式的引入和讨论真是思路清晰,精准到位,跟着他的思路,总算有点头绪。习惯了过程化编程的我,对于这种需求的变化,首先想到的肯定是改写实现方法体即可。但是通过这段时间学习设计模式和设计原则,我明白这样做的代价只能是维护和扩展的痛苦和艰难。所以,尝试着用OO的思想来冲洗我过程化的习惯,一时还真的觉得挺难接受。

引入

很显然,装饰模式的关键点在于对继承机制的动态应用。通常的继承使用方式(静态实现),在一些情况下显得有些臃肿,这个时候使用装饰模式可以动态搞定。

我设想了一个这样的场景:用户登陆控制。对于系统的登陆验证,我们可以根据具体的情况采用不同的登陆策略:测试阶段可以只根据用户名验证登陆;正式发布后要根据用户名和密码验证;如果有部门限制的话,还要结合部门信息进行权限验证。

在装饰模式中的各个角色有:

抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象。
具体构件(Concrete Component)角色:定义一个将要接收附加责任的类。
装饰(Decorator)角色:持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口。
具体装饰(Concrete Decorator)角色:负责给构件对象"贴上"附加的责任。

例证

1.结构图

class checkLogin //构件角色

class loginDecorator : checkLogin //装饰角色
class pwdCheckLogin : loginDecorator //具体装饰角色
class UserPwdCheckLogin : loginDecorator //具体装饰角色
class DeptCheckLogin : loginDecorator //具体装饰角色
static void Main(string[] args)
checkLogin CheckLogin;

public void setInstance(checkLogin checklogin)

public abstract class IGoodRecWrapper:IMovementBase
{
IMovementBase _mv;

public IGoodRecWrapper(IMovementBase mv)
{
this._mv = mv;
}

public override string ExecuteCallSAP(BasicInfo info)
{
return _mv.ExecuteCallSAP(info);
}
}

class MaterialTransfer309:IGoodRecWrapper
{
public MaterialTransfer309(IMovementBase mv)
:base(mv)
{

}

public override string ExecuteCallSAP(BasicInfo info)
{
string mat_doc= base.ExecuteCallSAP(info);

string doc_309= ExecuteMaterialTransfer();

return mat_doc + "," + doc_309;
}

public string ExecuteMaterialTransfer() //功能扩展
{
return "I have executed 309 operation";
}
}

SourceCode:/Files/Ivan-Yan/DecoratorPattern.rar

总结

最后引用TerryLee的精辟总结:
Decorator模式采用对象组合而非继承的手法,实现了在运行时动态的扩展对象功能的能力,而且可以根据需要扩展多个功能,避免了单独使用继承带来的“灵活性差”和“多子类衍生问题”。同时它很好地符合面向对象设计原则中“优先使用对象组合而非继承”和“开放-封闭”原则。

学习参考:
/article/4583356.html

http://www.cnblogs.com/zhenyulu/articles/46735.aspx

大话设计模式:装饰模式
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: