装饰模式
装饰模式,是面向对象编程领域中,一种动态地往一个类中添加新的行为的设计模式。就功能而言,修饰模式相比生成子类更为灵活,这样可以给某个对象而不是整个类添加一些功能。
通过使用装饰模式,可以在运行时扩充一个类的功能。原理是:增加一个修饰类包裹原来的类,包裹的方式一般是通过在将原来的对象作为修饰类的构造函数的参数。装饰类实现新的功能,但是,在不需要用到新功能的地方,它可以直接调用原来的类中的方法。修饰类必须和原来的类有相同的接口。
修饰模式是类继承的另外一种选择。类继承在编译时候增加行为,而装饰模式是在运行时增加行为。
当有几个相互独立的功能需要扩充时,这个区别就变得很重要。在有些面向对象的编程语言中,类不能在运行时被创建,通常在设计的时候也不能预测到有哪几种功能组合。这就意味着要为每一种组合创建一个新类。相反,修饰模式是面向运行时候的对象实例的,这样就可以在运行时根据需要进行组合。
维基百科-修饰模式
装饰模式实现穿衣服功能
public class Person
{
private string name;
public Person() { }
public Person(string name)
{
this.name = name;
}
public virtual void Show()
{
Console.WriteLine("装扮的是{0}", name);
}
}
/// <summary>
/// 服饰类
/// </summary>
public class Finery : Person
{
protected Person componet;
public void Decorate(Person componet)
{
this.componet = componet;
}
public override void Show()
{
if (componet!=null)
{
componet.Show();
}
}
}
#region 具体服饰类
public class TShirts : Finery
{
public override void Show()
{
Console.WriteLine("大T恤");
base.Show();
}
}
public class BigTrouser : Finery
{
public override void Show()
{
Console.WriteLine("大垮裤");
base.Show();
}
}
public class Shoes : Finery
{
public override void Show()
{
Console.WriteLine("鞋子");
base.Show();
}
}
#endregion
static void Main(string[] args)
{
Person person = new Person("小菜");
TShirts shirts = new TShirts();
BigTrouser bigTrouser = new BigTrouser();
Shoes shoes = new Shoes();
//装饰过程
shirts.Decorate(person);
bigTrouser.Decorate(shirts);
shoes.Decorate(bigTrouser);
shoes.Show();
Console.ReadLine();
}
输出:
鞋子
大垮裤
大T恤
装扮的是小菜
总结
装饰模式是为已有的功能动态的添加更多功能的一种方式。
使用场景:当系统需要新功能的时候,需要向旧的类中添加新的代码。这些新加的代码通常装饰了原有类的核心职责或主要行为,在主类中加入新的字段,新的方法和新的逻辑,从而增加了主类的复杂度。而这些新加入的东西仅仅是为了满足一些只有在特定情况下才会执行的特殊行为需要。在这种情况下,装饰模式提供了一个非常好的解决方案,它为每个要装饰的功能放在单独的类中,并让这个了类包裹它所要装饰的对象。因此,当需要执行特殊行为时,客户代码就可以在运行时根据需要有选择地,按顺序使用装饰功能包装对象了。