Decorator介绍:
装饰模式(Decorator)动态地给一个对象添加一个额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。
Component是定义一个对象的接口,可以给这些对象动态添加职责。ConcreteCompoent是定义了一个具体的对象,也可以给这个对象添加一些职责。Decorator装饰抽象类,继承了Component,从外类来扩展Component类的功能,但对于Component来说,是无需知道Decorator的存在的。至于ConcreteDecorator就是具体的装饰对象,起到给Component添加职责的功能
装饰模式结构图
在装饰模式中的各个角色有:
抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象。
具体构件(Concrete Component)角色:定义一个将要接收附加责任的类。
装饰(Decorator)角色:持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口。
具体装饰(Concrete Decorator)角色:负责给构件对象"贴上"附加的责任。
举例:
代码结构
客户端代码
Person xc = new Person("小菜");
Console.WriteLine("\n第一种装扮:");
Sneakers pqx = new Sneakers();
BigTrouser kk = new BigTrouser();
TShirt dkx = new TShirt();
pqx.Decorate(xc);
kk.Decorate(pqx);
dkx.Decorate(kk);
dkx.Show();
Console.WriteLine("\n第二种装扮:");
LeatherShoes px = new LeatherShoes();
Tie ld = new Tie();
Suit xz = new Suit();
px.Decorate(xc);
ld.Decorate(px);
xz.Decorate(ld);
xz.Show();
Console.Read();
Person类
class Person
{
public Person()
{ }
private string name;
public Person(string name)
{
this.name = name;
}
public virtual void Show()
{
Console.WriteLine("装扮的{0}", name);
}
}
服装类
class Finery : Person
{
protected Person component;
public void Decorate(Person component)
{
this.component = component;
}
public override void Show()
{
if (component!=null)
{
component.Show();
}
}
}
具体服饰类
class LeatherShoes : Finery
{
public override void Show()
{
Console.Write("皮鞋");
base.Show();
}
}
//大T恤
class TShirt : Finery
{
public override void Show()
{
Console.Write("大T恤");
base.Show();
}
}
//垮裤
class BigTrouser : Finery
{
public override void Show()
{
Console.Write("垮裤");
base.Show();
}
}
//破球鞋
class Sneakers : Finery
{
public override void Show()
{
Console.Write("破球鞋");
base.Show();
}
}
//西装
class Suit : Finery
{
public override void Show()
{
Console.Write("西装");
base.Show();
}
}
//领带
class Tie : Finery
{
public override void Show()
{
Console.Write("领带");
base.Show();
}
}
//皮鞋
效果图
装饰模式利用SetComponent来对对象进行包装的,这样每个装饰的实现就和如何使用这个对象分离开了,每个装饰对象只关心自己的功能,不需要关心如何被添加到对象链当中
优点:
装饰模式与继承关系的目的都是要扩展对象的功能,但是装饰模式可以提供比继承更多的灵活性。
通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。
这种比继承更加灵活机动的特性,也同时意味着装饰模式比继承更加易于出错。
缺点:
由于使用装饰模式,可以比使用继承关系需要较少数目的类。使用较少的类,当然使设计比较易于进行。但是,在另一方面,使用装饰模式会产生比使用继承关系更多的对象。更多的对象会使得查错变得困难,特别是这些对象看上去都很相像。
应用
在以下情况下应当使用装饰模式:
需要扩展一个类的功能,或给一个类增加附加责任。
需要动态地给一个对象增加功能,这些功能可以再动态地撤销。
需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变得不现实。