如何解决Java Records嵌套场景下的迪米特法则违规问题?
解决嵌套Java Record访问字段违反迪米特法则的问题
针对你的嵌套Record结构,要规避迪米特法则的问题,核心是在顶层KYAAutoResponse中封装对requestId的访问逻辑,对外只暴露简洁的访问方法,同时处理中间层级可能为null的情况,避免空指针异常。
错误原因分析
你之前尝试在KYAAutoResponse中添加Statements字段返回null,是因为JSON结构里Statements是嵌套在深层节点的,Jackson无法将JSON中的深层节点直接映射到顶层的Statements字段,因此该字段始终为null。
正确实现方式
在顶层KYAAutoResponse中添加一个直接获取requestId的方法,内部处理所有嵌套层级的null安全访问,外部调用者无需了解内部的嵌套结构:
public record KYAAutoResponse( DataTransFlowAccessOutputRecord dataTransFlowAccessOutputRecord ) { // 直接对外暴露获取requestId的方法 public Optional<String> getRequestId() { return Optional.ofNullable(dataTransFlowAccessOutputRecord) .map(DataTransFlowAccessOutputRecord::data) .map(Data::document) .map(Document::statements) .map(Statements::requestId); } public record DataTransFlowAccessOutputRecord( Data data ) { public record Data( Document document ) { public record Document( Statements statements ) { @JsonInclude(JsonInclude.Include.NON_NULL) public record Statements( @JsonProperty("request-id") String requestId ) {} } } } }
使用方式
外部调用时,只需调用顶层的getRequestId()方法即可,完全不需要关心内部的嵌套结构:
KYAAutoResponse response = ...; // 反序列化得到的响应对象 String requestId = response.getRequestId().orElse(null); // 或者用orElseGet处理默认值
额外优化方案
如果希望在反序列化时就直接把requestId映射到顶层的一个字段,可以使用Jackson的@JsonGetter,让序列化时也能输出顶层的request-id字段(可选):
public record KYAAutoResponse( DataTransFlowAccessOutputRecord dataTransFlowAccessOutputRecord ) { @JsonGetter("request-id") public Optional<String> getRequestId() { return Optional.ofNullable(dataTransFlowAccessOutputRecord) .map(DataTransFlowAccessOutputRecord::data) .map(Data::document) .map(Document::statements) .map(Statements::requestId); } // 嵌套Record结构保持不变 // ... }
这种方式既遵守了迪米特法则(外部只和直接的KYAAutoResponse对象交互),又解决了null的问题,同时保持了Record的不可变性特性。
内容的提问来源于stack exchange,提问作者Alex_Pap
相关产品推荐
相关产品推荐

