我正在构建一个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;
}

10-06 08:41