面向对象设计原则“合成/聚合复用原则”指出:尽量不要使用继承,要尽量使用合成/聚合。
如果对系统功能扩展有很多种方法,可以直接改源码,如果改完之后出现的Bug,排错起来应该相当困难,因为很不容易清楚到底是直接新加入的代码出的错,还是新加入的代码导致原有代码发生异常;也可以用继承,直接继承原有的类,再子类中增加新的功能,再或者直接写个全新的类替换原有(有点疯狂)。设计模式中的结构型模式可以将类和对象结合在一起形成更强大的结构,结构模式中的装饰模式可以在客户端以透明的方式扩展对象的功能,是用以继承关系实现复用方式的一种替代方案。
装饰模式的角色有:
1、 抽象构件(Component)角色:一个抽象接口抽象类,用来规范准备接收附加功能的对象。
2、 具体构件(Concrete Component)角色:实际或继承抽象构件一个类,它可以接收附加的功能。
3、 装饰(Decorator)角色:实现或继承抽象构件,并持有一个构件对象实例,关定义与抽象构件接口一致的接口。
4、 具体装饰(Concrete Decorator)角色:负责为构件对象附加功能。
如果现在有一个附件上传类:
class UploadAttachment
{
public UploadAttachment()
{
}
//上传附件方法
public bool UploadFile(HttpPostedFile postedFile,FillInfo fillInfo,FillInfoSettings Fs)
{
//……
}
//删除附件方法
public bool DelFile(FillInfo fillInfo)
{
//……
}
}
客户端调用代码:
如果现在要扩展一个功能,判断上传的是否为图片,如果是同时生成相应的缩略图,删除一个附件时如果是图片同时删除缩略图,这时我们就可以用装饰模式对原来的功能进行扩展。
客户端调用代码:
这里是一个退化了的装饰模式,UploadAttachment类同时具有抽象构件和具体构件的角色,ThumbnailHandler同时扮演装饰角色和抽象角色。上例中在客户端可以像原来对象调用一样来调用装饰实例的方法。