装饰(Decorator)模式是对象结构模式,GOF对它的作用描述为:动态地给一个对象添加一些额外的职责,就增加功能来说,Decorator模式比生成子类更为灵活。现在直接给出GOF著作中的Decorator模式结构图:
实现案例是学习设计模式的好办法,GOF一书中给了一个例子,就是“图形用户界面”设计的问题,一个图形用户界面工具箱允许你对任意一个用户界面组件添加一些特性,例如边框,或是一些行为,例如窗口滚动。 可以使用继承实现,但方法太过死板,因为通过继承实现的边框,它的选择是静态的,用户不能控制对组件加边框的方式和时机。记住:继承是强关联关系。较为灵活的办法是将组件放到一个对象中,由这个对象为组件添加边框。而这个嵌入的对象就是装饰。类图如下图:
由给定的类图结构,设计以下相应的代码,如下:

1 abstract class VisualComponent{ 2 public VisualComponent(){}; 3 abstract void Draw(); 4 abstract void Resize(); 5 } 6 abstract class Decorator extends VisualComponent{ 7 private VisualComponent v; 8 public Decorator(VisualComponent v){this.v=v;}; 9 void Draw(){v.Draw();}; 10 void Resize(){v.Resize();}; 11 } 12 class TextView extends VisualComponent{ 13 public TextView(){}; 14 public void Draw(){ 15 System.out.println("Draw a TextView"); 16 } 17 public void Resize(){ 18 System.out.println("Reset the text's size"); 19 } 20 } 21 class BorderDecorator extends Decorator{ 22 private int width; 23 public BorderDecorator(VisualComponent v,int width){ 24 super(v); 25 this.width=width; 26 } 27 private void DrawBorder(int width){ 28 System.out.println("Decorate it with a line whose width is "+width); 29 } 30 public void Draw(){ 31 super.Draw(); 32 DrawBorder(width); 33 } 34 } 35 36 public class Test{ 37 38 public static void main(String[] args){ 39 40 new BorderDecorator(new TextView(),10).Draw(); 41 } 42 }
装饰模式典型的创建对象的过程如下代码所示。

1 new Decorator1( 2 new Decorator2( 3 new Decorator3( 4 new ConcreteComponent() 5 ) 6 ) 7 );
使用装饰模式要注意以下几点:
1、接口的一致性。装饰对象必须和它所装饰的Component的接口要一致,组件类和装饰类必须有一个公共的父类。
2、保持Component类的简单性。Component应集中定义接口(也就是方法),而不是用于存储数据,应该把数据的定义延迟到子类中。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?