一,概念
摘自TerryLee的博客(http://terrylee.cnblogs.com/archive/2006/03/01/340592.html)
概述
在软件系统中,有时候我们会使用继承来扩展对象的功能,但是由于继承为类型引入的静态特质,使得这种扩展方式缺乏灵活性;并且随着子类的增多(扩展功能的增多),各种子类的组合(扩展功能的组合)会导致更多子类的膨胀。如何使“对象功能的扩展”能够根据需要来动态地实现?同时避免“扩展功能的增多”带来的子类膨胀问题?从而使得任何“功能扩展变化”所导致的影响将为最低?这就是本文要讲的Decorator模式。
意图
动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator模式相比生成子类更为灵活。[GOF 《设计模式》]
二,实现
using System;
using System.Collections.Generic;
using System.Text;
using DebugOut = System.Diagnostics.Debug;
namespace CsharpBase.DesignPattern
{
/// <summary>
/// 装饰模式
/// </summary>
class DecoratorDemo
{
public static void Run()
{
Dark dark = new GreenDark();
//能飞的鸭子
FlyDarkWapper flyWapper = new FlyDarkWapper(dark);
//能飞,也能唱歌的鸭子
SingDarkWapper singWrapper = new SingDarkWapper(flyWapper);
//能飞,能唱歌,还能跳舞的鸭子
DanceDarkWapper danceWrapper = new DanceDarkWapper(singWrapper);
danceWrapper.Action();
//结果
//i'm a Green dark
//now,i can fly.
//now i can sing
//now,i can dance
}
}
public abstract class Dark
{
public abstract void Action();
}
public class RedDark : Dark
{
public override void Action()
{
DebugOut.WriteLine("i'm a red dark");
}
}
public class GreenDark : Dark
{
public override void Action()
{
DebugOut.WriteLine("i'm a Green dark");
}
}
public abstract class DarkWapper : Dark
{
Dark dark;
public DarkWapper(Dark dark)
{
this.dark = dark;
}
public override void Action()
{
dark.Action();
}
}
/// <summary>
/// 功能扩展(飞)
/// </summary>
public class FlyDarkWapper : DarkWapper
{
public FlyDarkWapper(Dark dark)
: base(dark)
{
}
public override void Action()
{
base.Action();
Fly();
}
private void Fly()
{
DebugOut.WriteLine("now,i can fly.");
}
}
/// <summary>
/// 功能扩展(唱歌)
/// </summary>
public class SingDarkWapper : DarkWapper
{
public SingDarkWapper(Dark dark)
: base(dark)
{
}
public override void Action()
{
base.Action();
Sing();
}
private void Sing()
{
DebugOut.WriteLine("now i can sing");
}
}
/// <summary>
/// 功能扩展(跳舞)
/// </summary>
public class DanceDarkWapper : DarkWapper
{
public DanceDarkWapper(Dark dark)
: base(dark)
{
}
public override void Action()
{
base.Action();
Dance();
}
private void Dance()
{
DebugOut.WriteLine("now,i can dance");
}
}
}