【问题标题】:How to only expose certain classes and methods?如何只公开某些类和方法?
【发布时间】:2014-09-10 10:11:58
【问题描述】:

我的任务是创建一个可重用的软件作为库/API。现在,我在多个包中将每个类作为公共类,其中的方法大多是私有的。

由于这应该是一个 API,我希望隐藏所有的类,除了暴露一些类和方法。

我不能对类使用 private 修饰符,因为我在项目的其他包中引用它们。我也不想为了访问其中的方法而不必要地继承类。

我应该怎么做才能公开某些类和方法,同时保持在我的项目中访问它们的能力?

【问题讨论】:

  • 了解defaultprotected 访问控制。它们可能是您需要的。
  • 如果类相互需要,将它们放在同一个包中并为非 API 方法或类使用默认修饰符可能是有意义的。

标签: java api


【解决方案1】:

我真的建议您在开始设计 API 之前在纸上记录以下内容。

准备工作

  1. 您是否确定了所有类型的交互实体。每个实体都可以组成一个对象。

  2. 您希望在哪个层(控制器/外观/DAO 等)使用这些。

  3. 是预期通过网络传输的任何对象。

  4. 您的整个 API 将公开哪些数据。

设计 您通常需要执行以下操作:- 如果您的实体(在第 1 部分中)是相关的并且可能包含公共信息,请创建 1 个实体(示例 Common)以保留公共数据(如请求的时间戳、设备信息等)并创建其他可以包含此信息的实体,继承这个实体。确保公共实体的属性受到保护。 Common 看起来像

   public class Common{
         protected _deviceId;
         protected _reqTimeStamp;
         protected _osVersion;

         //Getters and Setters. 
   }

例如,如果您的 API 使用从移动应用接收的 JSON 请求数据,您可以让 Common 包含上面第 1 点中给出的数据。您可以创建另一个 Object,如下所示

public class UserInfo extends Common{
         private String _userName;
         private String _userMailId;

         //getters and setters 
}

尝试为层之间的数据传输保留最少的实体。如果您的 API 服务的服务层位于不同的服务器上,那么您可能希望使其保持可序列化并确保此类 DTO 不包含大量信息。

同样,当您分离 API 的功能时,请尝试查看哪些功能相似且通常需要。将它们移到抽象类中,并使对其他行为进行分类的接口实现扩展抽象类。

请参阅下面的示例。

public abstract class CommonBehaviour {

protected String _commonId;

public void commonBehaviourOne()
{
    //Behaviour common to implementations
}

    abstract public void overrideThisBehaviour(); 

    //getters and setters
  }

现在,如果您在实现中有两种类型的行为,它们之间具有共同的功能。

public interface Designable {

}

public class DesignerImpl extends CommonBehaviour implements Designable {

    @Override
    public void overrideThisBehaviour() {
        // TODO Auto-generated method stub

    }

}

一旦明确了先决条件,就可以轻松地决定将课程设为公开、私有还是默认。你必须集思广益,在利益相关者之间进行讨论,然后再次集思广益。你一定会想出一个好的 API

参考资料供您参考

互联网上有大量信息可供进入设计领域的人使用。 就书籍而言,我提到了“Head First Design Patterns”和Design Patterns by Gamma。虽然我发现 Gamma 更全面,但前者对新手有好处。

如果这对您有帮助,请告诉我。

【讨论】:

  • 感谢您的详细回答,它让我对设计 API 的理解更加清晰。但是,我看到示例代码使用受保护,这会阻止其他包中的代码访问类中的方法。有没有办法解决这个问题?
  • 你是对的@AmultexHeart 我的错!编辑了答案。使行为可访问。它应该是公开的
【解决方案2】:

在 API 上,您应该只公开接口和业务对象。通常,它们位于与接口实现不同的 Maven 工件上。

简而言之:为领域对象创建一个 maven 项目,另一个用于 API 接口,另一个用于 API 实现。然后仅将前两个分发给您的客户。

关于依赖关系:实现项目应该同时依赖于 API 和业务对象项目。 API 项目应该只依赖于业务对象项目。业务对象项目不应依赖两者。

【讨论】:

  • 不幸的是,我正在从事的项目使用 Ant 而不是 Maven。但是我可能需要更多地了解 Maven 以用于未来的项目。将 Maven 项目构建到 jar 文件中是否也包含依赖项?如果是这样的话,那么我的实现类也会暴露出来。
  • Maven 不包括对 jar 项目的依赖(它对战争项目有依赖,但事实并非如此)。我写了 Maven,因为它是最常用的,但如果你使用 Ant,概念是一样的。
【解决方案3】:

如果您有公开的方法,请将您的课程设为公开。 在其类中本地使用的方法必须是私有的 应该公开的方法,公开 应该在您的 API 中可见而不是外部的方法采用受保护的或默认的。

【讨论】:

  • 另一种解决方案是使用接口,但您应该自己管理实例化,以便在接口类型变量中放入已实现类的实例
  • 我正在使用一个接口并且有实现该接口的具体类。有没有办法让接口公开,但保持类私有/受保护,同时保持从其他包调用类的能力?
  • 你不能,因为可见性是从超类继承的。但是,您可以提供 Factory 或 Builder 来创建实例。
猜你喜欢
  • 2020-10-08
  • 2017-01-25
  • 1970-01-01
  • 2021-10-10
  • 2011-08-11
  • 1970-01-01
  • 2021-02-21
  • 1970-01-01
  • 2013-10-10
相关资源
最近更新 更多