您的位置:首页 > 编程语言 > C#

设计模式学习(三): 装饰者模式 (附C#实现)

2017-10-04 18:27 489 查看

需求

做一个咖啡店的订单系统。

买咖啡时,可以要求加入各种调料,如奶,豆浆,摩卡等。咖啡店会根据调料的不同收取不同的费用。订单系统要考虑这些。

初版设计



然后下面就是所有的咖啡....:



cost方法将计算出咖啡加上各种调料后的价格。

这种方法太笨了。。。必须换一种。

再版设计

使用实例变量和继承!



但是有新的问题:

1.调料价格变化就需要更改现有的代码。

2.一旦出现新的调料,就需要加上新的方法,并改变超类中的cost方法。

3.如果有新的饮料,有些调料可能会不适用。

4.想买双倍的摩卡咖啡怎么办?

设计原则

类应该对扩展开发,对修改关闭。

使用装饰者模式









装饰者模式定义

装饰者模式动态的将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。



重新设计



C#代码实现

Beverage:

namespace C03DecoratorPattern.Bases
{
public abstract class Beverage
{
protected string Description;

protected Beverage()
{
Description = "Unknown Beverage";
}

public abstract double Cost();

public virtual string GetDescription()
{
return Description;
}
}
}


CondimentDecorator:

namespace C03DecoratorPattern.Bases
{
public abstract class CondimentDecorator : Beverage
{
public abstract override double Cost();
public abstract override string GetDescription();
}
}


咖啡们:

namespace C03DecoratorPattern.Beverages
{
public class Espresso : Beverage
{
public Espresso()
{
Description = "Espresso";
}

public override double Cost()
{
return 1.99;
}
}
}

namespace C03DecoratorPattern.Beverages
{
public class HouseBlend : Beverage
{
public HouseBlend()
{
Description = "House Blend Coffee";
}

public override double Cost()
{
return .89;
}
}
}


调料们:

namespace C03DecoratorPattern.Condiments
{
public class Milk : CondimentDecorator
{
private readonly Beverage _beverage;

public Milk(Beverage beverage)
{
_beverage = beverage;
}

public override double Cost()
{
return .34 + _beverage.Cost();
}

public override string GetDescription()
{
return $"{_beverage.GetDescription()}, Milk";
}
}
}

namespace C03DecoratorPattern.Condiments
{
public class Mocha : CondimentDecorator
{
private readonly Beverage _beverage;

public Mocha(Beverage beverage)
{
_beverage = beverage;
}
public override double Cost()
{
return .2 + _beverage.Cost();
}

public override string GetDescription()
{
return $"{_beverage.GetDescription()}, Mocha";
}
}
}

namespace C03DecoratorPattern.Condiments
{
public class Soy: CondimentDecorator
{
private readonly Beverage _beverage;

public Soy(Beverage beverage)
{
_beverage = beverage;
}

public override double Cost()
{
return .17 + _beverage.Cost();
}

public override string GetDescription()
{
return $"{_beverage.GetDescription()}, Soy";
}
}
}


测试程序:

namespace C03DecoratorPattern
{
class Program
{
static void Main(string[] args)
{
Beverage beverage = new Espresso();
Console.WriteLine($"{beverage.GetDescription()} $ {beverage.Cost()}");

Beverage beverage2 = new HouseBlend();
beverage2 = new Mocha(beverage2);
beverage2 = new Milk(beverage2);
beverage2 = new Soy(beverage2);
Console.WriteLine($"{beverage2.GetDescription()} $ {beverage2.Cost()}");

Console.ReadLine();
}
}
}


运行结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: