装饰者模式
顾名思义就是动态的给一个对象添加一些额外的职责,就增加功能来说,装饰者模式比生成子类更加灵活。
当系统需要新功能时,是向旧的类中添加新的代码,这些新加的代码通常装饰了原有类的核心职责或主要行为,在主类中加入了新的字段,新的方法和新的逻辑,从而增加了主类的复杂度,而这些新加入的东西仅仅是为了满足一些只在某种特定情况下才会执行的特殊行为的需要。
装饰模式却提供了一个非常好的解决方案,它把每个要装饰的功能放在单独的类中,并让这个类包装它所要装饰的对象,因此,当需要执行特殊行为时,客户代码就可以在运行时根据需要有选择的,按顺序的使用装饰功能包装对象了。
有效的把类的核心职责和装饰功能区分开了。而且可以去除相关类中重复的装饰逻辑
结构图:
在这里就举一个手抓饼套餐的例子
实现代码
定义一个接口/包含套餐内容及其价钱两个方法
public interface ICake
{
//套餐描述
string descripestion();
//价格描述
double money();
}
定义一个抽象装饰者类
//装饰者类
public abstract class Deractor : ICake
{
public ICake cake;
public Deractor(ICake cake)
{
this.cake = cake;
}
public virtual string descripestion()
{
return cake.descripestion();
}
public virtual double money()
{
return cake.money();
}
}
定义一个被装饰者类,也就是普通的手抓饼类
//被装饰者类
public class Shreddedcake : ICake
{
public string descripestion()
{
return "原味手抓饼";
}
public double money()
{
return 3.5;
}
}
定义第一个具体装饰者类,鸡蛋类
//具体装饰者类&添加鸡蛋
public class EggCake : Deractor
{
public EggCake(ICake cake):base(cake)
{
}
public override string descripestion()
{
return "鸡蛋" + cake.descripestion();
}
public override double money()
{
return 3.5 + 1.5;
}
}
定义第二个具体装饰者类,牛肉类
//装饰者类&加牛肉
class BeffCake : Deractor
{
public BeffCake(ICake cake):base(cake)
{
}
public override string descripestion()
{
return "牛肉" + cake.descripestion();
}
public override double money()
{
return cake.money() + 3.0;
}
}
在主方法内调用
//原味手抓饼
Shreddedcake sh = new Shreddedcake();
Console.WriteLine(sh.descripestion());
Console.WriteLine("价格:" + sh.money());
//加蛋手抓饼
EggCake egg = new EggCake(sh);
Console.WriteLine(egg.descripestion());
Console.WriteLine("价格:" + egg.money());
//加蛋加牛肉手抓饼
BeffCake beff = new BeffCake(egg);
Console.WriteLine(beff.descripestion());
Console.WriteLine("价格:"+beff.money());
输出结果为
原味手抓饼
价格:3.5
鸡蛋原味手抓饼
价格:5
牛肉鸡蛋原味手抓饼
价格:8