概念:动态给一个对象添加额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。
结构图:
解析:
Component类:
定义一个对象接口,可以给这些对象动态添加职责(方法)。
ConcreteComponent类:
定义了一个具体的对象,也可以给这个对象添加职责。
Decorator类:
装饰抽象类,继承Component,从外类来扩展Component类的功能,但对于Component来说,是无需知道Decorator的存在的。
ConcreteDecorator类:
具体的装饰对象,起到给Component添加职责的功能。
注意:
如果只有一个ConcreteComponent类而没有抽象的Component类,那么Decorator类可是ConcreteComponent的一个子类,同样道理,如果只有一个ConcreteDecorator类,那么就没有必要建立一个单独的Decorator类,而可以把Decorator和ConcreteDecorator的责任合并成一个类。
先看结构一个结构图:
此时,没有Component类,将“人“这个类看成是Component类和ConcreteComponent类的综合体,那么”服饰类“(Decorator类)可以看成是其一个子类,后面的球鞋类、西装类、领带类、皮鞋类都是具体的装饰对象。
实例:
结构图:
代码实现:
Photot life = new LifePhoto();
Photot art= new ArtPhoto ();
//life.Display ();
//art.Display ();
PhotoFrame glass=new GlassPhotoFrame (life );
glass .Display ();
PhotoFrame ruby = new RubyPhotoFrame(art );
ruby.Display ();
}
}
//对象接口
abstract class Photot
{
public abstract void Display();
}
//具体对象
class LifePhoto : Photot //具体对象一
{
public override void Display()
{
Console.WriteLine("生活照");
}
}
class ArtPhoto : Photot //具体对象二
{
public override void Display()
{
Console .WriteLine ("艺术照");
}
}
//装饰抽象类
abstract class PhotoFrame : Photot
{
private Photot photo;
public PhotoFrame (Photot photo)
{
this.photo=photo ;
}
public override void Display()
{
photo.Display();
}
}
//具体装饰对象
class GlassPhotoFrame : PhotoFrame //装饰对象一
{
public GlassPhotoFrame(Photot photo)
: base(photo)
{ }
public override void Display()
{
Console.WriteLine("加了玻璃相框");
base.Display();
}
}
class RubyPhotoFrame : PhotoFrame //装饰对象二
{
public RubyPhotoFrame(Photot photo)
: base(photo)
{ }
public override void Display()
{
Console.WriteLine("红宝石色相框");
base.Display();
}
}
运行结果:
优点:
第一:使书写的代码具有柔韧性,能够以一系列的功能来增加代替对象的行为,它不会污染原有的代码,反而会让代码容易编写,容易对外扩展。
第二:它将每个功能放在一个单独的类中,让这个类去包装要装饰的对象,这样就将装饰功能类与原有的类分开,简化了原有类,类的核心职责和装饰功能也区分开了,而且相关类中重复的装饰逻辑也没有了。
缺点:
第一:如果原有的对象的接口发生变化了,那么他所有的装饰类也得修改,进而匹配接口。
第二:如果装饰链过大,系统就会花费较长的时间去用于初始化对象,影响信息的传递。
适用范围:
第一:想在不影响其他类的情况下,动态的给对象添加新的职责方法;
第二:给对象增加职责可能会在未来发生改变;
第三:用子类来扩展功能不方便的情况下。