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

设计模式之上下文对象设计模式

目录

一、模式介绍

二、架构设计

三、Demo 示例

四、总结


一、模式介绍

上下文对象(Context Object)模式 最早由《Core J2EE Patterns》第二版提出,其核心目标是在多层或多组件间共享与当前作用域(如一次请求、一次会话、一次业务流程)相关的所有状态和服务,消除各组件对底层环境细节(如协议、线程、本地存储等)的直接依赖,从而提高系统的可复用性、可维护性和可测试性。Context Object 封装了与某个 Scope 相关的数据与行为,使各层或模块只需依赖该 Context,即可获得所需服务或状态,而无需显式传递大量参数或直接引用环境 API。

使用场景与历史背景

  • 在传统多层应用中,每一层如果要访问共享信息(如用户凭证、事务、配置参数),通常需要将其作为参数显式传递,导致方法签名臃肿、可读性差、易出错。

  • 随着 J2EE 应用复杂度提升,设计者发现将环境细节直接嵌入业务逻辑耦合度过高,维护成本激增。

  • 《Core J2EE Patterns》第二版总结了当时业界实践,将这种“共享环境数据”抽象为 Context Object 模式,对应 ApplicationContext/ServletContext、Hibernate SessionContext 等典型用法。

解决问题

  • 解耦:业务组件不必直接依赖环境(HTTP、JNDI、线程等)接口,一律通过 Context 获取所需信息或服务。

  • 集中管理:所有上下文相关的信息集中维护,便于调试、监控及扩展。

  • 生命周期一致性:Context 在作用域开始时创建,结束时统一销毁,资源释放更可控。

典型实现:

  • Apache Spark – SparkContext / SQLContext / StreamingContext

    聚合集群配置、调度、序列化、监控接口,并暴露 RDD/DataFrame/流计算等 API。

  • Flink – StreamExecutionEnvironment / ExecutionEnvironment

    封装执行引擎配置、并行度、checkpoint、状态后端等,用于构建批/流作业。


二、架构设计

以下为 Context Object 模式的标准 UML 类图:

主要组件说明

  • Context(接口):定义获取与存放上下文数据的方法。

  • ConcreteContext(实现类):内部维护一张属性映射,负责实际存取。

  • ContextFactory(工厂类):(可选)根据环境创建对应的 Context 实例。

  • Client:业务组件,通过构造器或工厂获取 Context 实例,并向其读写数据或调用存入的服务。


三、Demo 示例

问题场景:在一个 Web 应用或微服务中,常常需要在多个业务层(如控制层、服务层、数据访问层)之间传递用户会话信息、跟踪操作日志对象以及可复用的工具服务实例。直接在每个方法签名中传递这些参数,不仅会导致参数列表臃肿,还容易遗漏,增加维护成本。

解决方案:使用上下文对象模式,将所有需跨层共享的数据与服务封装到一个 Context 对象中,由各层直接从 Context 中获取,而不必在方法之间显式传递这些参数。

// 1. 定义 Context 接口,提供读写属性和服务获取功能
public interface RequestContext {<T> T get(String key, Class<T> type);void set(String key, Object value);
}
​
// 2. Context 实现,内部维护属性映射
public class RequestContextImpl implements RequestContext {private final Map<String, Object> data = new HashMap<>();
​@Overridepublic <T> T get(String key, Class<T> type) {return type.cast(data.get(key));}
​@Overridepublic void set(String key, Object value) {data.put(key, value);}
}
​
// 3. Context 工厂,初始化必要属性
public class RequestContextFactory {public static RequestContext create(String userId) {RequestContext ctx = new RequestContextImpl();// 初始化用户信息和日志追踪器ctx.set("userId", userId);ctx.set("traceId", UUID.randomUUID().toString());return ctx;}
}
​
// 4. 控制层:创建 Context 并启动业务流程
public class Controller {public void handleRequest(String userId) {RequestContext ctx = RequestContextFactory.create(userId);new BusinessService(ctx).process();}
}
​
// 5. 业务层:直接从 Context 获取 userId 和 TraceId,执行业务逻辑
public class BusinessService {private final RequestContext ctx;
​public BusinessService(RequestContext ctx) {this.ctx = ctx;}
​public void process() {String userId = ctx.get("userId", String.class);String traceId = ctx.get("traceId", String.class);// 输出日志时无需额外传参System.out.println("[" + traceId + "] Processing business logic for user " + userId);
​// 调用下一层服务new DataService(ctx).execute();}
}
​
// 6. 数据访问层:继续复用同一个 Context
public class DataService {private final RequestContext ctx;
​public DataService(RequestContext ctx) {this.ctx = ctx;}
​public void execute() {String traceId = ctx.get("traceId", String.class);// 使用 traceId 进行 SQL 日志关联System.out.println("[" + traceId + "] Executing SQL queries");}
}

说明

  • Controller 层只需创建并初始化一次 RequestContext,并传递给后续各层,不再维护多个参数。

  • 任何业务或数据访问类均可通过 ctx.get(...) 获取所需信息,简化方法签名。

  • 可扩展到添加更多上下文数据(如用户权限列表、国际化配置、第三方服务客户端等),只需在 Context 中新增属性,而无需改动各层接口。


四、总结

上下文对象模式 通过封装作用域相关的所有状态与服务,实现组件与环境的最大解耦,提升系统的灵活性和可维护性。

  • 价值

    • 模块化:各功能模块仅依赖 Context 接口,无须关注如何获取底层资源。

    • 扩展性:新增上下文数据或服务时,只需修改 Context 实现,无需改动业务层代码。

    • 测试友好:可为单元测试提供 Mock Context,对业务逻辑进行隔离测试。

  • 注意事项

    • 避免 Context 过于庞大,必要时可拆分为多个子 Context(如 ConfigContext、SecurityContext)。

    • 随着系统复杂度上升,建议引入成熟的 IoC/DI 容器(如 Spring ApplicationContext)来管理对象生命周期和依赖注入。

Context Object 模式是企业级应用架构中常见且行之有效的方案,既可手写实现,也可借助框架。它在《Core J2EE Patterns》一书中的提炼,为现代微服务与云原生开发中的“作用域数据共享”提供了理论基础与实践指导。

http://www.lryc.cn/news/578365.html

相关文章:

  • IntelliJ IDEA 2025- 下载安装教程图文版详细教程(附激活码)
  • 使用nlohmann/json.hpp实现json文件读写
  • SpringBoot全局异常详解
  • 【实时Linux实战系列】实时数据库与数据存储方案
  • 学习threejs,使用自定义GLSL 着色器,生成艺术作品
  • 使用Rust原生实现小波卡尔曼滤波算法
  • 408第三季part1 - 操作系统 - 基本分页
  • 算法赋能管理:工厂安全与效率双突破
  • 【仿muduo库实现并发服务器】Channel模块
  • 回转体航行器控制系统中深度控制与俯仰姿态控制的解耦策略
  • 基于springboot的养老院管理系统
  • C# Linq to XML 详解:强大的XML处理工具
  • (自用)Java学习-5.21(支付宝沙箱支付、Vue总结)
  • 插入排序解析
  • sqlmap学习笔记ing(1.Easy_SQLi(时间,表单注入))
  • Django打造智能Web机器人控制平台
  • HarmonyOS应用开发高级认证知识点梳理 (一) 布局与样式
  • 记本好书:矩阵力量:线性代数全彩图解+微课+Python编程
  • 深蓝海域承建某大型保险集团产险知识库升级项目
  • 主流零信任安全产品深度介绍
  • 11OAuth2
  • 从零到一搭建远程图像生成系统:Stable Diffusion 3.5+内网穿透技术深度实战
  • 【深度学习1】ModernBert学习
  • 发布/订阅模式:解耦系统的强大设计模式
  • Spring Boot 集成 Dufs 通过 WebDAV 实现文件管理
  • 从零到一:VNC+内网穿透技术搭建企业级远程控制系统的完整路径
  • ubuntu系统安装docker 和 mongdb,YaPi(包含中间过程不能拉去依赖问题)
  • langchain从入门到精通(三十二)——RAG优化策略(八)自查询检索器实现动态数据过滤
  • 自由学习记录(66)
  • 聚观早报 | 知乎直答新升级;特斯拉V4超级充电桩首批上线;苹果将推出廉价版Macbook