C# Design Patterns (3) - Decorator
2009-06-29 07:07:51 来源:WEB开发网图片看不清楚?请点击这里查看原图(大图)。
图 2 示例 02_Steak.aspx.cs 的 Class Diagram
02_Steak.aspx.cs
using System;
using com.cnblogs.WizardWu.sample02; //客戶端程序调用服务器端的组件和类
//客戶端程序
public partial class _02_Steak : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
//点一客猪排,不需要副菜。并列出它的描述与价格
Meal meal1 = new PorkChop();
//Meal meal1 = new BeefSteak();
Response.Write(meal1.Description + " = $ " + meal1.cost() + "<br>");
//点一客猪排,副菜只要面条。并列出它的描述与价格
Meal meal2 = new PorkChop();
meal2 = new Noodle(meal2); //用 Noodle 装饰它 (运行时动态地增加职责)
Response.Write(meal2.Description + " = $ " + meal2.cost() + "<br>");
//点一客猪排,因为这个人食量大,副菜要两份面条、一杯饮料(热饮)、一盘甜点。并列出它的描述与价格
Meal meal3 = new PorkChop();
meal3 = new Noodle(meal3); //用 Noodle 装饰它
meal3 = new Noodle(meal3); //用第二个 Noodle 装饰它
meal3 = new Drink(meal3, true); //用 Drink 装饰它
meal3 = new Dessert(meal3); //用 Dessert 装饰它
Response.Write(meal3.Description + " = $ " + meal3.cost() + "<br>");
//第四个人不吃猪肉,因此主菜改点一客牛排,副菜要一盘沙拉、一杯饮料(冷饮)。并列出它的描述与价格
Meal meal4 = new BeefSteak();
meal4 = new Salad(meal4); //用 Salad 装饰它 (运行时动态地增加职责)
meal4 = new Drink(meal4, false); //用 Drink 装饰它
Response.Write(meal4.Description + " = $ " + meal4.cost() + "<br>");
}
}
//服務器端程序
namespace com.cnblogs.WizardWu.sample02
{
//装饰者(副菜)、被装饰者(主菜)的共同基类。类似前一例的 Component 抽象类
abstract class Meal
{
protected string description = "西餐";
public virtual string Description
{
get { return description; }
set { description = value; }
}
abstract public int cost(); //必须在子类实作的抽象方法,除非该个子类也是抽象类
}
//主菜(被装饰者)。类似前一例的 ConcreteComponent 类
class PorkChop : Meal //主菜 - 猪排。以后执行时,才会动态被副菜装饰
{
public PorkChop() //构造函数
{
Description = "猪排";
}
public override int cost() //具体对象的操作
{
return 130; //猪排的价格。现在不需要管「副菜」的价格,直接返回猪排的价格即可
}
}
//主菜(被装饰者)。类似前一例的 ConcreteComponent 类
class BeefSteak : Meal //主菜 - 牛排。以后执行时,才会动态被副菜装饰
{
public BeefSteak() //构造函数
{
Description = "牛排";
}
public override int cost() //具体对象的操作
{
return 150; //牛排的价格。现在不需要管「副菜」的价格,直接返回牛排的价格即可
}
}
//装饰者。类似前一例的 Decorator 抽象类。此为所有「副菜(装饰者)」的父类。
//功能一、未来所有可能添加的副菜,其共同的属性、行为,都可放在这个类里。
//功能二、用来「分类」哪些是主菜,哪些是副菜。
abstract class CondimentDecorator : Meal //副菜,用来「动态」装饰主菜和 Meal 基类,亦即在运行时动态地替他们增加职责
{
//以父类声明的字段。
//实现 UML Class Diagram 的 Aggregation,指向 Meal 对象的指针。
protected Meal meal;
public override string Description
{
get { return meal.Description + " + " + description; }
set { description = value; }
}
}
//副菜(装饰者)。具体装饰类 - 面条,用来动态装饰主菜 - 牛排或猪排
class Noodle : CondimentDecorator //类似前一例的 ConcreteDecoratorA
{
public Noodle(Meal meal) //构造函数
{
Description = "面条";
this.meal = meal;
}
public override int cost() //具体装饰对象 A 的操作
{
return 50 + meal.cost();
}
}
//副菜(装饰者)。具体装饰类 - 沙拉,用来动态装饰主菜 - 牛排或猪排
class Salad : CondimentDecorator //类似前一例的 ConcreteDecoratorB
{
public Salad(Meal meal) //构造函数
{
Description = "生菜沙拉";
this.meal = meal;
}
public override int cost() //具体装饰对象 B 的操作
{
return 60 + meal.cost();
}
}
//副菜(装饰者)。具体装饰类 - 饮料,用来动态装饰主菜 - 牛排或猪排
class Drink : CondimentDecorator //类似前一例的 ConcreteDecoratorC
{
private bool isHot;
public bool IsHot
{
get { return isHot; }
}
public Drink(Meal meal, bool isHot) //构造函数
{
Description = (isHot) ? "热饮" : "冷饮";
this.meal = meal;
this.isHot = isHot;
}
public override int cost() //具体装饰对象 C 的操作。冷饮比热饮多收 20 块钱
{
return (isHot) ? (30 + meal.cost()) : (50 + meal.cost());
}
}
//副菜(装饰者)。具体装饰类 - 甜点,用来动态装饰主菜 - 牛排或猪排
class Dessert : CondimentDecorator //类似前一例的 ConcreteDecoratorD
{
public Dessert(Meal meal) //构造函数
{
Description = "甜点";
this.meal = meal;
}
public override int cost() //具体装饰对象 D 的操作
{
return 40 + meal.cost();
}
}
} // end of namespace
更多精彩
赞助商链接