核心在于通过访问者模式解耦遍历与清洗逻辑:定义visitable接口统一访问契约,visitor接口按类型重载visit方法;各嵌套对象实现visitable并递归委托accept,清洗等行为由cleaningvisitor等具体visitor实现,业务代码仅需两行调用。

核心在于把“遍历”和“清洗”从具体数据结构中解耦出来,让不同层级、不同类型的数据节点,按自身语义决定如何被访问或清理——这正是多态性的本质。
用接口统一访问契约
定义一个通用处理接口,屏蔽嵌套深度与类型差异:
interface Visitable {
void accept(Visitor visitor);
}
interface Visitor {
void visit(String key, Object value); // 基础字段
void visit(String key, Map, ?> nestedMap); // 嵌套Map
void visit(String key, List> nestedList); // 可扩展其他结构
}
让每层嵌套对象(如自定义的 NestedMap 或包装类)实现 Visitable,在 accept 中调用对应 visit 方法。这样,遍历逻辑完全由 visitor 决定,无需 if-else 判断类型。
清洗行为按需注入,不侵入数据结构
清洗不是硬编码在遍历循环里,而是 visitor 的一种实现:
- 写一个
CleaningVisitor,对特定 key(如"tempData")或 value 类型(如String.class且含"_tmp")执行清除或替换 - 写一个
LoggingVisitor做审计,一个SanitizingVisitor做脱敏——全部复用同一套遍历骨架 - 清洗时可抛出
VisitSkipException跳过子树,或返回VisitResult.CONTINUE控制流程
配合泛型与递归委托,保持类型安全
避免 Object 强转带来的运行时风险:
class TypedNestedMap<k v> implements Visitable {
private final Map<k v> delegate;
@Override
public void accept(Visitor visitor) {
for (Map.Entry<k v> e : delegate.entrySet()) {
if (e.getValue() instanceof Map) {
visitor.visit((K) e.getKey(), (Map, ?>) e.getValue());
// 递归委托给子 map 自己的 accept
((Visitable) e.getValue()).accept(visitor);
} else {
visitor.visit((K) e.getKey(), e.getValue());
}
}
}
}
</k></k></k>
关键点:子结构也实现 Visitable,遍历时自动向下分发,上层无需知道下层是否是 Map、List 还是 POJO。
实际使用只需两行
把复杂性收在 visitor 实现里,业务代码极简:
NestedMap config = loadConfig();
config.accept(new CleaningVisitor()
.excludeKeys("metadata", "debug")
.removeEmptyEntries()
);
不需要写 for 循环,不关心嵌套几层,也不用反复判断 instanceof——行为由对象自己声明,调用由 visitor 驱动,真正实现“优雅”二字。











