面向对象配合泛型wrapper实现接口统一状态码动态装配,核心是解耦数据与状态信息、泛型保障类型安全、策略模式按需装配code/msg/extras。

用面向对象配合泛型 Wrapper 实现接口统一状态码的动态装配,核心是把「数据」和「状态信息」解耦封装,再通过泛型保持类型安全,最后借助面向对象的多态或策略能力实现不同业务场景下状态码、消息、扩展字段的按需装配。
设计一个泛型响应 Wrapper 类
这是基础容器,承载业务数据 + 通用元信息(code、msg、timestamp 等):
- 使用泛型 T 表示实际业务返回的数据类型,保证编译期类型安全
- code、msg、success 等字段声明为可读写,便于后续动态填充
- 提供静态工厂方法(如 ok(T data)、fail(int code, String msg)),简化常用构造
- 避免在构造时硬编码具体状态码(如 200/500),留出运行时装配空间
定义状态码策略接口与具体实现
面向对象的关键在于抽象行为。为支持“动态装配”,把状态码逻辑抽成策略:
- 声明接口 StatusStrategy
,含方法 assemble(Wrapper wrapper, T data, Object... args) - 不同业务模块实现该接口:比如 LoginStatusStrategy 在登录成功时塞入 token 字段和 2001 登录专用码;OrderStatusStrategy 对下单失败返回 4002 + 订单校验详情
- 策略内部可访问 Spring 上下文、当前用户、请求参数等上下文,实现真正“动态”
在 Controller 层或统一拦截器中装配
不建议每个接口手动 new Wrapper 并 setCode,而是集中装配:
- 方式一:Controller 方法返回 Wrapper
,由自定义 @ResponseBodyAdvice 拦截,检查是否已装配,未装配则根据返回值类型或注解(如 @ApiStatus(Login.class))自动匹配并执行对应 StatusStrategy - 方式二:封装一个 ResultBuilder 工具类,接收 data 和 strategy 类型,内部调用策略完成装配后返回 Wrapper,Controller 中直接写 return ResultBuilder.build(data, LoginStatusStrategy.class);
- 关键点:Wrapper 本身不持有策略,策略也不依赖具体 Wrapper 实现,符合开闭原则
支持扩展字段与多环境差异化
真正的动态装配还包括非标准字段(如 traceId、debugInfo)和环境适配:
- 在 Wrapper 中添加 Map
extras 字段,并提供 putExtra(key, value) 方法 - 策略实现中可判断 Profile == "dev",自动注入 SQL 日志或堆栈片段到 extras
- 用注解(如 @WithDebug、@Traceable)标记接口方法,由 Advice 解析并触发额外字段注入逻辑
- 避免把所有可能字段都提前定义在 Wrapper 类里,靠 Map + 约定 key 实现灵活扩展
这套设计让状态码不再散落在各处 if-else 里,而是收口到策略中;泛型保障了数据不丢失类型信息;面向对象提供了替换、组合、复用的能力。只要策略写得清晰,新增一种业务状态,只需加一个 Strategy 实现类,Controller 几乎不用改。











