我正在构建一个 API。它的功能之一是执行一些资源分析(想象一个文档、URI 或 DB,什么不重要)并返回 List<Finding>
哪里Finding
是一个 POJO。我想要Finding
一旦从 API 返回,所有数据都由 API 返回,就变得不可变,但是,我想要一个 setUserNote(String)
方便客户的方法。
这样做的原因是为了让客户端获得 Finding
的列表。 s,它可以在使用 setUserNote
时处理它们将自己的数据保存在对象本身中,就像普通的笔记一样。我认为这比客户必须扩展 Finding
更方便。只需添加一个变量或将其封装为实例变量,然后 ExtendedFinding.someMethod() { return this.finding.someMethid(); }
对于 Finding
中的每个方法。此外,至少可以说,客户端构建 ExtendedFinding
会很困惑。出Finding
他从 API 获取。这就是为什么我打算简单地为他们提供一个他们可以方便使用的字段。
问题:
这是一个糟糕的设计吗?为什么?我以前从未做过这样的事情,也没有见过 API 类带有任意数据持有者变量以方便客户端。
可以说这是一个糟糕的设计。什么是适用的设计模式来轻松传播Finding以由客户端构建ExtendFinding?当然,你可以有类似 public
ExtendedFinding(Finding) { /* copy vars one by one */ }
的东西但这远非优雅
最佳答案
首先你的第三点,final
决不会使一个类变得不可变——它意味着该类不能被继承。所以你不能扩展
一个final
类。
对于您的主要问题,为什么不将 POJO 转换为接口(interface)
并返回该列表而不是底层 POJO。然后,您可以将实际的 POJO 类包设为私有(private),以便客户端无法将其转换回来:
public static interface Finding {
//all public getters
void setUserNote();
}
static final class FindingImpl implements Finding {
@Override
public void setUserNote() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
private final Collection<FindingImpl> findingImpls = new ArrayList<>();
public Collection<Finding> getFindings() {
final Collection<Finding> findings = new ArrayList<>();
for (final FindingImpl fi : findingImpls) {
findings.add(fi);
}
return findings;
}
关于java - 部分可变的 API 类,具有供客户端使用的通用变量持有者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15593832/