java - 部分可变的 API 类,具有供客户端使用的通用变量持有者

标签 java api design-patterns immutability

我正在构建一个 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 获取。这就是为什么我打算简单地为他们提供一个他们可以方便使用的字段。

问题:

  1. 这是一个糟糕的设计吗?为什么?我以前从未做过这样的事情,也没有见过 API 类带有任意数据持有者变量以方便客户端。

  2. 可以说这是一个糟糕的设计。什么是适用的设计模式来轻松传播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/

相关文章:

Java文件上传到Windows共享文件夹并进行身份验证

php - API 需要 SSH key ,这通常是如何完成的?

design-patterns - 惯用的元编程

Java - 类存在两次(在类路径和应用程序 jar 上)。链接错误: ClassCastException

java - Java NIO 中 File.deleteOnExit() 的替代方案?

java - 将单元格合并到 MigLayout?

c# - 类似 Gmail 的标签系统

ruby-on-rails - Rails 4 - 使用 Moz API 在 View 中显示信息

php - php 中的 Reddit API 返回用于提交故事的错误验证码

C++单例模板类