装饰模式:动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。
例子:穿衣服
一.通常我们会写成这样:
如果要添加穿裙子这个新方法,就要修改‘人’类,就违背了开放-封闭原则。
二.单纯的抽象一个服饰类,下面继承一些具体服饰的子类:
但是相当于穿上大T恤就展示一下,再穿垮裤展示一下。如果想按顺序穿完衣服之后再展示,这时候就可以使用装饰模式。
装饰模式结构:
代码:
‘人’类:
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 TShirts: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 LeatherShoes : Finery
{
public override void Show()
{
Console.Write("皮鞋 ");
base.Show();
}
}
class Tie : Finery
{
public override void Show()
{
Console.Write("领带 ");
base.Show();
}
}
class Suit : Finery
{
public override void Show()
{
Console.Write("西装 ");
base.Show();
}
}
客户端代码:
static void Main(string[] args)
{
Person xc = new Person("小菜");
Console.WriteLine("\n第一种装扮:");
Sneakers pqx = new Sneakers();
BigTrouser kk = new BigTrouser();
TShirts dtx = new TShirts();
pqx.Decorate(xc);
kk.Decorate(pqx);
dtx.Decorate(kk);
dtx.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();
}
结果:
分析:客户端中
pqx.Decorate(xc);
kk.Decorate(pqx);
dtx.Decorate(kk);
dtx.Show();
把每个要装饰的功能放在单独的类中,并让这个类包装它所要装饰的对象。小菜就是cx即要装饰的对象,这样可以按顺序使用装饰功能包装小菜。展示的时候,由下往上展示。