我正在构建一个API。它的功能之一是执行一些资源分析(想象一个文档,URI或DB,并不重要),并返回一个List<Finding>
,其中Finding
是POJO。我希望Finding
从API返回后是不变的,并且所有数据都由API返回,但是,我希望有一个setUserNote(String)
方法以方便客户使用。
这样做的原因是,客户端获得Finding
的列表,它可以在使用setUserNote
将其自身的数据保存在对象本身中时对其进行处理,就像一个普通的注释。我认为这是一种整洁的便利,而不是客户端必须扩展Finding
只是添加一个变量或将其封装为实例变量,然后为ExtendedFinding.someMethod() { return this.finding.someMethid(); }
中的每个方法封装Finding
。此外,至少可以这样说,客户端从他从API获得的ExtendedFinding
中构造Finding
会很麻烦。这就是为什么我计划只给他们一个方便他们使用的领域。
问题:
这是不好的设计吗?为什么?我以前从未做过这样的事情,也从未见过API类为方便客户而带有任意数据持有者变量。
假设这是一个糟糕的设计。有什么适用的设计模式可以轻松地传播查找结果,从而由客户端构造ExtendedFinding?当然,您可以使用public ExtendedFinding(Finding) { /* copy vars one by one */ }
之类的东西,但这远非优雅
最佳答案
首先,您的第三点final
绝不会使类成为不可变的-它表示该类不能继承。因此,您不能extend
一个final
类。
对于您的主要问题,为什么不将POJO强制转换为interface
并返回该列表而不是基础POJO。然后,您可以将实际的POJO类包设为私有,以便客户端无法将其回退:
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;
}