当前位置: 首页 > news >正文

设计模式-装饰器模式 - MaC

装饰器模式是一种结构型设计模式,它允许在不修改原有对象结构的情况下,动态地给对象添加新的功能。装饰器模式通过创建一个包装对象(装饰器)来包裹真实的对象,从而在运行时扩展对象的功能。
装饰器模式包含以下角色:

  • 组件(Component):定义一个对象接口,可以给这些对象动态地添加职责
  • 具体组件(Concrete Component):定义一个对象,可以给这个对象添加一些职责
  • 装饰器(Decorator):维持一个指向Component对象的引用,并定义一个与Component接口一致的接口
  • 具体装饰器(Concrete Decorator):向组件添加职责

装饰器模式的优缺点

优点:

  • 灵活性高:比继承更加灵活,可以在运行时动态地添加或删除功能
  • 符合开闭原则:添加新功能时无需修改现有代码
  • 职责分离:每个装饰器只关注自己的功能,符合单一职责原则
  • 可组合性:可以使用多个装饰器来组合出复杂的功能
  • 避免类爆炸:避免了通过继承产生大量子类的问题

缺点:

  • 设计复杂:会产生很多小对象,增加系统复杂度
  • 调试困难:多层装饰器嵌套时,调试和排查问题比较困难
  • 性能影响:多层装饰可能会对性能产生一定影响

什么场景下使用装饰器模式

  1. 需要动态地给一个对象添加功能,这些功能也可以动态地被撤销
  2. 当不能采用继承的方式对系统进行扩充或者采用继承不利于系统扩展和维护时
  3. 需要为一组基本功能动态地添加不同的扩展功能
  4. 系统中存在大量独立的扩展,每种组合都可能被使用

代码举例

实际开发当中有很多地方用到装饰器模式,最典型的就是Java I/O流的InputStream、OutputStream及其各种装饰器类(BufferedInputStream、DataInputStream等),还有像设计一个多级缓存也可以用到,这里简单举例一个文本处理的例子

// 组件接口 - 文本处理器
interface TextProcessor {String process(String text);
}// 具体组件 - 基础文本处理器
class BasicTextProcessor implements TextProcessor {@Overridepublic String process(String text) {return text;}
}// 装饰器抽象类
abstract class TextProcessorDecorator implements TextProcessor {protected TextProcessor processor;public TextProcessorDecorator(TextProcessor processor) {this.processor = processor;}
}// 具体装饰器 - HTML转义装饰器
class HtmlEscapeDecorator extends TextProcessorDecorator {public HtmlEscapeDecorator(TextProcessor processor) {super(processor);}@Overridepublic String process(String text) {String processed = processor.process(text);return escapeHtml(processed);}private String escapeHtml(String text) {return text.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;").replace("\"", "&quot;").replace("'", "&#x27;");}
}// 具体装饰器 - Markdown转换装饰器
class MarkdownDecorator extends TextProcessorDecorator {public MarkdownDecorator(TextProcessor processor) {super(processor);}@Overridepublic String process(String text) {String processed = processor.process(text);return convertMarkdown(processed);}private String convertMarkdown(String text) {// 简化的Markdown转换return text.replace("**", "<strong>").replace("*", "<em>").replace("`", "<code>").replaceAll("^# (.*)$", "<h1>$1</h1>").replaceAll("^## (.*)$", "<h2>$1</h2>");}
}// 具体装饰器 - 敏感词过滤装饰器
class SensitiveWordFilterDecorator extends TextProcessorDecorator {private Set<String> sensitiveWords;public SensitiveWordFilterDecorator(TextProcessor processor) {super(processor);this.sensitiveWords = new HashSet<>(Arrays.asList("暴力", "色情", "赌博", "毒品"));}@Overridepublic String process(String text) {String processed = processor.process(text);return filterSensitiveWords(processed);}private String filterSensitiveWords(String text) {String result = text;for (String word : sensitiveWords) {result = result.replace(word, "*".repeat(word.length()));}return result;}
}// 具体装饰器 - 格式化装饰器
class FormattingDecorator extends TextProcessorDecorator {public FormattingDecorator(TextProcessor processor) {super(processor);}@Overridepublic String process(String text) {String processed = processor.process(text);return formatText(processed);}private String formatText(String text) {// 简单的文本格式化return text.trim().replaceAll("\\s+", " ").replaceAll("\n+", "\n");}
}// 客户端使用示例
public class TextProcessorDemo {public static void main(String[] args) {String inputText = "  # 标题\n\n这是一个**重要**的*消息*,包含`代码`。\n\n请注意,这里有一些敏感词汇:暴力和色情内容。  ";// 基础处理器TextProcessor basicProcessor = new BasicTextProcessor();// 添加格式化功能TextProcessor formattingProcessor = new FormattingDecorator(basicProcessor);// 添加Markdown转换功能TextProcessor markdownProcessor = new MarkdownDecorator(formattingProcessor);// 添加HTML转义功能TextProcessor htmlEscapeProcessor = new HtmlEscapeDecorator(markdownProcessor);// 添加敏感词过滤功能TextProcessor fullProcessor = new SensitiveWordFilterDecorator(htmlEscapeProcessor);System.out.println("=== 原始文本 ===");System.out.println(inputText);System.out.println("\n=== 处理后文本 ===");String result = fullProcessor.process(inputText);System.out.println(result);// 只使用部分装饰器System.out.println("\n=== 只使用Markdown和HTML转义 ===");TextProcessor simpleProcessor = new HtmlEscapeDecorator(new MarkdownDecorator(basicProcessor));String simpleResult = simpleProcessor.process("# 标题 <script>");System.out.println(simpleResult);}
}
http://www.wxhsa.cn/company.asp?id=1422

相关文章:

  • 【API接口】最新可用河马短剧接口
  • 第 16 章反射(reflection)
  • 自我介绍+软工5问
  • 电容器+动生电动势+自由落体模型
  • 引用(reference)
  • 设计模式-组合模式 - MaC
  • 【推荐】100%开源!大型工业跨平台软件C++源码提供,建模,组态
  • tmux 使用教程
  • 引用类型
  • CF1237C2
  • 力扣215. 数组中的第K个最大元素
  • 设计模式-桥接模式 - MaC
  • linux环境docker离线镜像elasticsearch-7.17.3镜像资源
  • Python 降序排序:轻松搞定列表、字典和自定义对象
  • 第02周 预习、实验与作业:Java基础语法2、面向对象入门
  • part 4
  • systemctl的service脚本写法
  • 9月份美联储的降息利好
  • 口胡记录
  • Day16内存分析及初始化
  • leveldb源码分析 #1 Slice WriteBatch WriteBatchInternal 【work记录】
  • 欧拉安装
  • 2025实测:6款主流公众号编辑器大比拼,解决你的排版难题!
  • 设计模式-适配器模式 - MaC
  • devc学C语言
  • HarmonyOS 5.1手势事件详解
  • Vue3项目中集成AI对话功能的实战经验分享
  • gulimall出现服务间调用org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient.choose 问题
  • Java02课前问题列表