应用概述: StarBuzz咖啡店有很多饮料,每种饮料都可以根据客户需要加一些调料,比如深培咖啡可以加摩卡(或双倍摩卡),而且某些饮料可以分为大中小杯,根据容量不同,售价不同,而且调料的价格根据饮料的容量不同而不同(比如大杯咖啡加糖要1元,中杯咖啡加糖要0.9元等)
又一设计原则: 对扩展开放,对修改关闭(本例中各种饮料都有共同的大中小杯特性--这是关闭的部分,另外各种具体子类饮料和调料的描述和价格都不相同--这是开放的部分)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace StarBazz
{
/// <summary>
/// 抽象"饮料"类
/// </summary>
public abstract class Beverage
{
protected string description = "Unknown Beverage";
protected int _Size = (int)SizeEnum.Big;//初始化各种饮料均为"大杯"
public abstract string GetDescription();//抽象方法,由"饮料"的具体子类返回各自的描述
public abstract double GetCost();//抽象方法,由"饮料"
/// <summary>
/// 返回各种饮料的"大中小杯"
/// </summary>
/// <returns></returns>
public int GetSize()
{
return _Size;
}
/// <summary>
/// 设置各种饮料的"大中小杯"
/// </summary>
/// <param name="size"></param>
public void SetSize(SizeEnum size)
{
_Size = (int)size;
}
/// <summary>
/// 大中小杯枚举类型
/// </summary>
public enum SizeEnum:int
{
Small =1,Middle=2,Big=3
}
}
}
被装饰组件之一:“浓咖啡”类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace StarBazz
{
/// <summary>
/// “浓咖啡”类
/// </summary>
public class Espresso:Beverage
{
public Espresso()
{
description = "Espresso";//初始化描述
}
/// <summary>
/// 实现父类的抽象方法GetDescription()
/// </summary>
/// <returns></returns>
public override string GetDescription()
{
return description;
}
/// <summary>
/// 实现父类的抽象方法GetCost() -注:“浓咖啡”不论大中小杯,价格均为1.99元
/// </summary>
/// <returns></returns>
public override double GetCost()
{
return 1.99;
}
}
}
被装饰组件之二:“深培咖啡类”类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace StarBazz
{
/// <summary>
/// “HouseBlend”深培咖啡类
/// </summary>
public class HouseBlend:Beverage
{
public HouseBlend()
{
description = "House Blend Coffee" ;
}
/// <summary>
/// 实现父类的抽象方法
/// </summary>
/// <returns></returns>
public override string GetDescription()
{
return description + "(" + (Beverage.SizeEnum)this.GetSize() + ")";
}
/// <summary>
/// 实现父类的抽象方法(大杯0.89元,中杯0.79元,小杯0.68元)
/// </summary>
/// <returns></returns>
public override double GetCost()
{
double _cost = 0;
switch (base.GetSize())
{
case (int)Beverage.SizeEnum.Big:
_cost = 0.89;
break;
case (int)Beverage.SizeEnum.Middle:
_cost = 0.79;
break;
case (int)Beverage.SizeEnum.Small:
_cost = 0.68;
break;
default:
break;
}
return _cost;
}
}
}
装饰者类: “摩卡”调料
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace StarBazz
{
/// <summary>
/// “摩卡”调料(用来给其它各种饮料做调味品)--装饰者
/// </summary>
public class Mocha:Beverage
{
Beverage _beverage;//声明一个内部公用的Beverage对象
/// <summary>
/// 构造函数
/// </summary>
/// <param name="beverage"></param>
public Mocha(Beverage beverage)
{
_beverage = beverage;
description = _beverage.GetDescription();//保存被装饰对象的描述
_Size = _beverage.GetSize();//保存被装饰对象的"大中小杯"值
}
/// <summary>
/// 实现父类的抽象方法
/// </summary>
/// <returns></returns>
public override string GetDescription()
{
return description + ",Mocha";
}
/// <summary>
/// 实现父类的抽象方法,计算价格(大杯饮料加一份Mocha需要0.2元,中杯饮料加一份Mocha需要0.15元,小杯饮料加一份Mocha需要0.1元)
/// </summary>
/// <returns></returns>
public override double GetCost()
{
double _cost = this._beverage.GetCost();
switch (_beverage.GetSize())
{
case (int)Beverage.SizeEnum.Big:
_cost += 0.2;
break;
case (int)Beverage.SizeEnum.Middle:
_cost += 0.15;
break;
case (int)Beverage.SizeEnum.Small:
_cost += 0.1;
break;
default:
break;
}
return _cost;
}
}
}
最终测试
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace StarBazz
{
class Program
{
static void Main(string[] args)
{
//先来一份Expresso(浓咖啡),不要任何调料
Beverage _beverage = new Espresso();
Console.WriteLine(_beverage.GetDescription() + " Cost:" + _beverage.GetCost().ToString());//Espresso Cost:1.99
//再来一份HouseBlend(深培咖啡)
Beverage _beverage2 = new HouseBlend();
Console.WriteLine(_beverage2.GetDescription() + " Cost:" + _beverage2.GetCost().ToString());//House Blend Coffee(Big) Cost:0.89
//客户补充说:只要一份小杯的哦!
_beverage2.SetSize(Beverage.SizeEnum.Small);
Console.WriteLine(_beverage2.GetDescription() + " Cost:" + _beverage2.GetCost().ToString());//House Blend Coffee(Small) Cost:0.68
//客户要求:我要加二份摩卡
Beverage _beverage3 = new Mocha(_beverage2);
Console.WriteLine(_beverage3.GetDescription() + " Cost:" + _beverage3.GetCost().ToString());//House Blend Coffee(Small),Mocha Cost:0.78
_beverage3 = new Mocha(_beverage3);
Console.WriteLine(_beverage3.GetDescription() + " Cost:" + _beverage3.GetCost().ToString());//House Blend Coffee(Small),Mocha,Mocha Cost:0.88
Console.ReadLine();
}
}
}
Espresso Cost:1.99 House Blend Coffee(Big) Cost:0.89 House Blend Coffee(Small) Cost:0.68 House Blend Coffee(Small),Mocha Cost:0.78 House Blend Coffee(Small),Mocha,Mocha Cost:0.88