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

java中装饰模式

目录

一 装饰模式案例说明

1.1 说明

1.2 代码

1.2.1 定义数据服务接口

1.2.2 定义基础数据库服务实现

1.2.3  日志装饰器

1.2.4 缓存装饰器

1.2.5 主程序调用

1.3 装饰模式的特点


一 装饰模式案例说明

1.1 说明

本案例是:数据查询增加缓存,使用到了装饰模式

1.装饰器链构建

new CachingDecorator(new LoggingDecorator(new DatabaseService()))

2.顺序是:缓存装饰器包裹日志装饰器,日志装饰器包裹基础数据库服务

3.流程

  1. 第一次查询 (user_123):

    • 进入缓存装饰器:缓存中没有,继续向下

    • 进入日志装饰器:记录开始日志

    • 进入数据库服务:执行实际查询

    • 返回日志装饰器:记录完成日志

    • 返回缓存装饰器:缓存结果

    • 最终返回结果给主程序

  2. 第二次查询 (user_123):

    • 缓存装饰器发现缓存中存在,直接返回

    • 不会触发日志和数据库查询

1.2 代码

1.2.1 定义数据服务接口

public interface DataService {String fetchData(String userId);
}

1.2.2 定义基础数据库服务实现

public class DatabaseService implements DataService {@Overridepublic String fetchData(String userId) {// Simulate fetching data from a databasereturn "db中数据00: " + userId;}
}

1.2.3  日志装饰器

public class LoggingDecorator  implements DataService {private final DataService wrappedService;public LoggingDecorator(DataService wrappedService) {this.wrappedService = wrappedService;}@Overridepublic String fetchData(String userId) {System.out.println("查询db中内容: " + userId);String result = wrappedService.fetchData(userId);System.out.println("logging查询db: " + result);return result;}
}

1.2.4 缓存装饰器

public class CachingDecorator implements DataService {private final DataService wrappedService;private final Map<String, String> cache = new HashMap<>();public CachingDecorator(DataService wrappedService) {this.wrappedService = wrappedService;}@Overridepublic String fetchData(String userId) {if (cache.containsKey(userId)) {System.out.println("查询缓存获取内容: " + userId);return cache.get(userId);} else {String result = wrappedService.fetchData(userId);cache.put(userId, result);return result;}}
}

1.2.5 主程序调用

public class TestZs {public static void main(String[] args) {DataService service = new CachingDecorator(new LoggingDecorator(new DatabaseService()));String result = service.fetchData("user_123");System.out.println("main方法显示结果:"+result);System.out.println("====================");// Fetching again to demonstrate cachingresult = service.fetchData("user_123");System.out.println(result);}
}

结果:

1.3 装饰模式的特点

关键点说明
装饰器顺序很重要:

如果把缓存装饰器放在最内层,日志每次都会记录

当前顺序确保了缓存命中时不会产生日志

线程安全:

使用 ConcurrentHashMap 保证缓存操作的线程安全

扩展性:

可以轻松添加其他装饰器(如性能监控、权限检查等)

透明性:

客户端代码不需要知道具体实现细节

这种设计模式非常适合需要动态添加功能的场景,同时保持了代码的整洁和可维护性

http://www.xdnf.cn/news/13077.html

相关文章:

  • Go内存池设计与实现:减少GC压力
  • ASM,LVM,扫描并扩容步骤-linux
  • 什么是双脉冲测试?
  • 【C++】第十一节—一文详解vector(使用+杨辉三角+深度剖析+模拟实现+细节详细补充)
  • 为什么要引入内联函数?
  • Python Selenium登录网易邮箱
  • FastAPI实战起步:从Python环境到你的第一个“Hello World”API接口
  • day 18进行聚类,进而推断出每个簇的实际含义
  • token和md5
  • Spring Boot 完全指南:快速构建企业级应用
  • vue中Echarts的使用
  • 【评测】Qwen3-Embedding模型初体验
  • frida Hook入门
  • [FreeRTOS]1.FreeRTOS基础知识
  • Java处理字符数组转换为开始日期和结束日期
  • 【学习笔记】深入理解Java虚拟机学习笔记——第3章 垃圾收集器与内存分配策略
  • LLMs之MCP:《Evaluation Report on MCP Servers》翻译与解读
  • 『uniapp』自定义隐私政策弹窗 调整颜色和多语言国际化支持超链接 演示本地插件的使用,和一般性的插件自定义(保姆级图文)
  • CppCon 2015 学习:Live Lock-Free or Deadlock
  • AI架构师修炼之道
  • Linux系统编程中的_GNU_SOURCE宏
  • Promise 基础:异步编程的救星
  • 使用idea开发工具创建javaweb项目工程
  • CQF预备知识:Python相关库 -- 傅里叶变换 scipy.fft
  • 第十八章 归档与备份
  • python打卡第48天
  • linux库(AI回答)
  • SpringBoot的5种日志输出规范策略
  • 深入理解 x86 汇编中的符号扩展指令:从 CBW 到 CDQ 的全解析
  • 《光子技术成像技术》第三章 预习2025.6.8