C#设计模式系列:装饰模式(Decorator)
1. 装饰模式简介
装饰模式动态地给一个对象添加额外的职责。例如一幅画有没有画框都可以挂在墙上,画就是被装饰者。但是通常都是有画框的。在挂在墙上之前,画可以被蒙上玻璃,装到框子里,所以在画上加一层画框,并把它们组合成一个整体——有框的画。这样随着不断有新的装饰的加入,就给商品不断地打上包装,变成一个功能更让人满意的商品。这种不断打包装的过程就是装饰。
1.1 定义
装饰模式提供了一种给类增加功能的方法。它通过动态地组合对象,可以给原有的类添加新的代码,而无须修改现有代码。因此引入bug或产生意外副作用的机会将大幅度减少。
1.2 使用频率
中等
2. 装饰模式结构图
2.1 结构图
2.2 参与者
装饰模式参与者:
◊ Component:定义一个对象接口,可以给这些对象动态地添加职责
◊ ConcreteComponent:定义一个对象,可以给这个对象添加一些职责
◊ Decorator:维持一个指向Component的指针,并定义一个与Component接口一致的接口
◊ ConcreteDecorator:负责向ConcreteComponent添加功能
在装饰模式中,Decorator定义了一个装饰接口类。因为Decorator与ConcreteComponent继承同一个接口,所以继承Decorator的类ConcreteDecorator可以使用ConcreteComponent的方法,再在ConcreteDecorator里面加入一些新的方法,也就是装饰,就成为了一个包装好的装饰类。
3、装饰模式结构实现
Component.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.DecoratorPattern.Structural { public abstract class Component { public abstract void Operation(); } }
ConcreteComponent.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.DecoratorPattern.Structural { public class ConcreteComponent : Component { public override void Operation() { Console.WriteLine("ConcreteComponent.Operation()"); } } }
Decorator.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.DecoratorPattern.Structural { public abstract class Decorator : Component { protected Component component; public void SetComponent(Component component) { this.component = component; } public override void Operation() { if (component != null) { component.Operation(); } } } }
ConcreteDecoratorA.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.DecoratorPattern.Structural { public class ConcreteDecoratorA : Decorator { public override void Operation() { base.Operation(); Console.WriteLine("ConcreteDecoratorA.Operation()"); } } }
ConcreteDecoratorB.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.DecoratorPattern.Structural { public class ConcreteDecoratorB : Decorator { public override void Operation() { base.Operation(); AddedBehavior(); Console.WriteLine("ConcreteDecoratorB.Operation()"); } void AddedBehavior() { } } }
Program.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using DesignPatterns.DecoratorPattern.Structural; namespace DesignPatterns.DecoratorPattern { class Program { static void Main(string[] args) { // Create ConcreteComponent and two Decorators ConcreteComponent c = new ConcreteComponent(); ConcreteDecoratorA d1 = new ConcreteDecoratorA(); ConcreteDecoratorB d2 = new ConcreteDecoratorB(); // Link decorators d1.SetComponent(c); d2.SetComponent(d1); d2.Operation(); } } }
运行输出:
ConcreteComponent.Operation()
ConcreteDecoratorA.Operation()
ConcreteDecoratorB.Operation()
请按任意键继续. . .
4、装饰模式应用分析
装饰模式适用情形:
◊ 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责
◊ 处理那些可以撤销的职责
装饰模式的特点:
◊ 比静态类更灵活。使用装饰模式可以很容易地向对象添加职责的方式。可以用添加和分离的方法,对装饰在运行时添加和删除职责。相比之下,继承机制要求为每个添加的职责创建一个新的子类。这会产生很多新的类,并会增加系统的复杂度。
◊ 使用装饰模式可以很容易地重复添加一个特性,而两次继承特性类则极容易出错。
◊ 为了避免处理顶层的类有太多的特征。装饰模式下,你可以定义一个简单的类,并用装饰类给它逐渐地添加功能。这样可以从简单的部件组合出复杂的功能,具有低依赖性和地复杂性。
◊ 有许多小对象。采用装饰模式进行系统设计往往会产生许多看上去类似的小对象,尽管对于了解这些系统的人来说,很容易进行定制,但是很难学习这些系统,排错很恶化呢困难。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
2012-03-30 Ext.MessageBox消息框
2012-03-30 Ext JS下载及配置
2012-03-30 EF Code First执行SQL语句及存储过程
2012-03-30 EF Code First数据库连接配置
2010-03-30 VS中不显示解决方案的解决方法