【问题标题】:How to avoid polluting API classes with internal methods?如何避免使用内部方法污染 API 类?
【发布时间】:2014-08-13 21:49:39
【问题描述】:

背景:

  • 在 C# 中,您可以将 internal 方法限定为程序集 (JAR)
  • 内部方法可以由该程序集中的其他类调用,但不能在外部调用。
  • Java 没有这样的类比。
  • 创建 API 时,我的内部方法必须是公开的,以便我的 API 的其他部分可以调用它们。
  • 这会污染我的 API,并可能允许用户调用内部方法。

TLDR:鉴于这些方法是公开的,我如何指示(或者更好的是保护)我的 API 的内部方法不被我的 API 类之外的用户调用?

典型示例:

  // public class in com.ashes999.components
  class SpriteComponent {
    // This method should be internal
    public void dispose() { ... } 
  }

  // public class in com.ashes999.management
  class SceneManager {
    public void changeScene(Scene s) {
      for (SpriteComponent s : this.allEntities.allSprites) {
        s.dispose();
      }
    }
  }  

我只会在com.ashes999.* 自己的班级中致电SpriteComponent.dispose。我永远不会期望(甚至希望)其他用户会直接调用它;这样做会导致混乱、破坏、混乱和未受管理的资源被过早处置,从而导致崩溃。

【问题讨论】:

  • 你在 Java 中有包私有访问权限。
  • “包私有”?如果这些方法在同一个包中,则可以由其他类中的方法调用,但不能从其他地方的其他类中调用。如果方法没有 publicprivateprotected 修饰符,则它是包私有的。
  • 我在一些库(例如 Apache Wicket)中看到在他们的文档中指出不要使用/覆盖某些方法,例如 HtmlSpecialTag
  • 另外,this other question 可能有帮助吗?
  • @MikeK 史诗失败...干得好:)

标签: java access-modifiers api-design


【解决方案1】:

可以使用修饰符 public 声明一个类,在这种情况下,该类对任何地方的所有类都是可见的。 如果一个类没有修饰符(默认值,也称为 package-private),则它仅在其自己的包中可见(包是相关类的命名组 - 您将在稍后了解它们教训。)

在成员级别,您还可以使用公共修饰符或不使用修饰符(包私有),就像顶级类一样,和同一个意思。对于成员,还有两个额外的访问修饰符:private 和 protected。 private 修饰符指定该成员只能在其自己的类中访问。 protected 修饰符指定该成员只能在其自己的包中访问(与 package-private 一样),此外,它的类在另一个包中的子类也可以访问。

(Access control)

【讨论】:

  • 如果您的 API 中有两个包,并且不同包中的两个或多个类需要使用彼此的方法,会发生什么情况?包私有范围不会导致问题吗?
  • 也许我误解了你的答案。我添加了一些说明性代码。在这种情况下,我在com.ashes999.components 中有一个公共方法,我从com.ashes999.management 调用它,但我必须公开该方法;我不能把它包私有,因为包不同。
  • @MikeK 如果您在不同的包中有类需要访问彼此的方法,那么它们应该是公共的或者在同一个包中。你必须选择。
  • @Eran 这是我问题的症结所在。在 C# 中,您不必选择,只需说“JAR-visible”。当然,我不是第一个在 Java 中错过这个的人,也不是第一个为此寻找解决方法(文档?)的人。
  • @ashes999 看来这两种机制各有优缺点。我听说喜欢 Java 机制的人认为 internal 没用。我们可能想要的是一个像public(com.ashes999.*) 这样的修饰符,上面写着“使这个名称对匹配该模式的包可见,而在其他任何地方不可见。Java 没有这样的东西,AFAIK 也没有 C#。所以也许我们应该说服一个语言团队添加此功能并希望另一个复制它。:) :)
猜你喜欢
  • 2010-10-25
  • 1970-01-01
  • 2017-06-04
  • 1970-01-01
  • 2014-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多