装饰者模式
对于一个初学设计模式的人来说,装饰者模式是很头疼的,因为我们一般很少会在项目中使用到这种模式(或者是个人的喜好吧)。装饰者模式是为了更为灵活的扩展对象的方法。
一般情况下,我们要扩展一个对象的方法,我们会用到继承,或者将对象内聚进去。但是,继承的扩展相对来说是静止的扩展,就是说一个方法扩展后,如果想继续新增功能的话,必须再次继承,再次扩展方法。这样的扩展就很容易引起子类的膨胀。
我想引入一个例子,就是tlw旁边的莆田卤面(听说又涨价啦),莆田卤面的做法比较灵活,可以加入多种佐料。比如 花蛤、虾、海蛎、蛏、蘑菇、猪肉。卤面中可以加入一种或者几种佐料,很显然,如果要为卤面加佐料的话,根据单一职责,需要派生出21种来子类来(6+5+4+3+2+1)。这样一来,就会出现子类膨胀,难以维护,而且对于边际扩展来说,所需要派生出来的子类就更多了(如果有10种配料的话,需要的子类是10+9+8+...+2+1)。
而装饰者模式就是为了解决这个问题的。装饰者模式的意图就是:动态地给一个对象添加一些额外的职责。
/// <summary>
/// 面条
/// </summary>
public class Noodles
{
}
/// <summary>
/// 佐料
/// </summary>
public abstract class Condiments
{
/// <summary>
/// 往苗条里面加佐料
/// </summary>
/// <param name="noodles"></param>
public abstract void CondimentsToNoodles(Noodles noodles);
}
//一般的调味品
public class GeneralCondiments : Condiments
{
public override void CondimentsToNoodles(Noodles noodles)
{
//加入一般的调味品
}
}
/// <summary>
/// 配料装饰者
/// </summary>
public class CondimentsDecorator : Condiments
{
private Condiments _Condiments;
public CondimentsDecorator(Condiments condiments)
{
this._Condiments = condiments;
}
/// <summary>
/// 将佐料加入面条
/// </summary>
/// <param name="noodles"></param>
public override void CondimentsToNoodles(Noodles noodles)
{
this._Condiments.CondimentsToNoodles(noodles);
}
}
接着扩展配料:
/// <summary>
/// 花蛤
/// </summary>
public class Clam : CondimentsDecorator
{
public Clam(Condiments condiments)
: base(condiments)
{
}
public override void CondimentsToNoodles(Noodles noodles)
{
base.CondimentsToNoodles(noodles); AddClamToNoodles(noodles);
}
private void AddClamToNoodles(Noodles noodles)
{
//往面条里面加入花蛤
}
}
/// <summary>
/// 虾
/// </summary>
public class Shrimp : CondimentsDecorator
{
public Shrimp(Condiments condiments)
: base(condiments)
{
}
public override void CondimentsToNoodles(Noodles noodles)
{
base.CondimentsToNoodles(noodles); AddClamToNoodles(noodles);
}
private void AddShrimp2Noodles(Noodles noodles)
{
//往面条里面加虾
}
}
/// <summary>
/// 蘑菇
/// </summary>
public class Mushrooms : CondimentsDecorator
{
public Mushrooms(Condiments condiments)
: base(condiments)
{
}
public override void CondimentsToNoodles(Noodles noodles)
{
base.CondimentsToNoodles(noodles); AddMushrooms2Noodles(noodles);
}
private void AddMushrooms2Noodles(Noodles noodles)
{
//往面条里面加蘑菇
}
}
/// <summary>
/// 猪肉
/// </summary>
public class Pork : CondimentsDecorator
{
public Pork(Condiments condiments)
: base(condiments)
{
}
public override void CondimentsToNoodles(Noodles noodles)
{
base.CondimentsToNoodles(noodles); AddPork2Noodles(noodles);
}
private void AddPork2Noodles(Noodles noodles)
{
//往面条里面加猪肉
}
}
最后调用:
//莆田卤面
Noodles putianNoodles = new Noodles();
GeneralCondiments general = new GeneralCondiments();
Clam clam = new Clam(general);
Shrimp shrimp = new Shrimp(clam);
Mushrooms mushrooms = new Mushrooms(shrimp);
Pork pork = new Pork(mushrooms);
pork.CondimentsToNoodles(putianNoodles);
上面的调用加入了所有的佐料,我们可以根据需要,灵活的添加不同组合的佐料。
装饰者模式的奥妙就是将装饰者和被装饰者使用的是一种类型;并且将被装饰者集聚到装饰者的类中,这种设计方式,使得扩展变得容易,并且灵活。
可以这么简单的理解,遇到一些子类需要选择组合的时候,使用装饰者模式将是子类的扩展变得很灵活,不会出现子类泛滥的情况。
我在学习设计模式的过程中,觉得最难理解的就是装饰者了,因为这种模式在我所遇到的项目里不常用到。

浙公网安备 33010602011771号