后端开发C#C#中的装饰者模式
L X Y
装饰者模式:动态扩展对象功能
主要代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| public abstract class Beverage { public string description = "Unknown Beverage"; public virtual string GetDescription() { return description; } public abstract float Cost(); }
public abstract class CondimentDecorator : Beverage { }
public class DerkBeverage : Beverage { public DerkBeverage() { description = "Derk Beverage"; } public override float Cost() { return 1.0f; } }
public class Milk : CondimentDecorator { Beverage _beverage; public Milk(Beverage beverage) { _beverage = beverage; } public override string GetDescription() { return _beverage.GetDescription() + ", Milk"; } public override float Cost() { return _beverage.Cost() + 0.1f; } }
public class Sugar : CondimentDecorator { Beverage _beverage; public Sugar(Beverage beverage) { _beverage = beverage; } public override string GetDescription() { return _beverage.GetDescription() + ", Sugar"; } public override float Cost() { return _beverage.Cost() + 0.1f; } }
|
模式结构
| 角色 |
代码示例 |
职责 |
| 组件接口 |
Beverage |
定义基础对象接口 |
| 具体组件 |
DerkBeverage |
实现基础功能 |
| 装饰器基类 |
CondimentDecorator |
继承组件接口 |
| 具体装饰器 |
Milk/Sugar |
添加额外功能 |
关键点
递归组合
1 2 3 4 5 6 7
| public class Milk : CondimentDecorator { Beverage _beverage;
public override float Cost() { return _beverage.Cost() + 0.1f; } }
|
透明装饰
动态扩展
1 2
| beverage = new Milk(beverage); beverage = new Sugar(beverage);
|
使用
1 2 3 4 5 6 7 8
| Beverage beverage = new DerkBeverage(); Console.WriteLine(beverage.GetDescription() + " $" + beverage.Cost());
beverage = new Milk(beverage); Console.WriteLine(beverage.GetDescription() + " $" + beverage.Cost());
beverage = new Sugar(beverage); Console.WriteLine(beverage.GetDescription() + " $" + beverage.Cost());
|
优势分析
| 特性 |
实现方式 |
优势 |
| 动态扩展 |
运行时添加装饰器 |
避免静态继承的类爆炸 |
| 开闭原则 |
新增装饰器不影响现有代码 |
系统扩展性强 |
| 功能分解 |
每个装饰器只添加单一功能 |
符合单一职责原则 |
| 透明性 |
装饰器与组件接口一致 |
客户端无需改变调用方式 |
应用场景
- 需要动态添加/撤销功能
- 不适合使用子类扩展的场景
- 常见案例:
- GUI组件装饰(滚动条/边框)
- 流处理(加密/压缩装饰器)
- 权限系统(叠加权限检查)
要点记忆:
所有装饰器继承CondimentDecorator基类
装饰器构造函数接收被装饰对象
GetDescription()递归拼接描述
Cost()递归计算总价
可多层嵌套装饰(牛奶+糖)