这是场景。作为公开许可的开源 API 的创建者,我的团队创建了一个基于 Java 的 Web 用户界面框架(那么还有什么新东西?)。为了在 Java 中保持良好和有序,我们使用了命名约定为 org.mygroup.myframework.x 的包,其中 x 表示组件、验证器、转换器、实用程序等(同样,还有什么是新的?)。
现在,在 org.mygroup.myframework.foo.Bar 类中的某处是void doStuff()
我需要执行特定于我的框架的逻辑的方法,并且我需要能够从我的框架中的其他几个地方调用它,例如 org. mygroup.myframework.far.Boo。鉴于 Boo 既不是 Bar 的子类,也不是在完全相同的包中,所以必须将方法 doStuff() 声明为 public 才能被 Boo 调用。
然而,我的框架作为一种工具存在,允许其他开发人员为他们的客户创建更简单、更优雅的 RIA。但是如果 com.yourcompany.yourapplication.YourComponent 调用 doStuff(),它可能会产生意想不到的不良后果。我宁愿这永远不会被允许发生。 请注意, Bar 包含其他真正公开的方法。
在象牙塔世界中,我们将重写 Java 语言并插入一个标记化的模拟来默认访问,这将允许我们选择的包结构中的任何类访问我的方法,可能看起来类似于:
[org.mygroup.myframework.*] void doStuff() { .... }
其中通配符表示包以 org.mygroup.myframework 开头的任何类都可以调用,但不能调用其他类。
鉴于这个世界不存在,我们还有什么其他好的选择?
请注意,这是由现实生活场景驱动的;为了保护罪犯,他们改名了。存在一个真正的框架,在其整个 Javadoc 中,人们会发现公共方法被注释为“此方法是 MYFRAMEWORK 的内部,而不是其公共 API 的一部分。请勿调用!!!!!!” 一些研究表明,这些方法是从框架内的其他地方调用的。
事实上,我是一名使用相关框架的开发人员。尽管我们的应用程序已部署并取得了成功,但我的团队经历了如此多的挑战,以至于我们想说服我们的老板不要再使用这个框架了。我们希望通过对框架开发人员做出的糟糕设计决策进行深思熟虑的介绍来做到这一点,而不仅仅是咆哮。这个问题将是我们的一个(几个)观点,但我们无法指出我们可能会如何以不同的方式做到这一点。在我的工作场所已经有一些热烈的讨论,所以我想知道世界其他人会怎么想。
更新:到目前为止,这两个回答者没有冒犯,但我认为你错过了标记,或者我表达得不好。无论哪种方式,都可以让我尝试阐明事物。尽可能简单地说,框架的开发人员应该如何重构以下内容。请注意,这是一个非常粗略的示例。
package org.mygroup.myframework.foo;
public class Bar {
/** Adds a Bar component to application UI */
public boolean addComponentHTML() {
// Code that adds the HTML for a Bar component to a UI screen
// returns true if successful
// I need users of my framework to be able to call this method, so
// they can actually add a Bar component to their application's UI
}
/** Not really public, do not call */
public void doStuff() {
// Code that performs internal logic to my framework
// If other users call it, Really Bad Things could happen!
// But I need it to be public so org.mygroup.myframework.far.Boo can call
}
}
另一个更新:所以我刚刚了解到 C# 具有“内部”访问修饰符。因此,表达这个问题的更好方法可能是“如何在 Java 中模拟/模拟内部访问?” 尽管如此,我并不是在寻找新的答案。我们的老板最终同意了上面提到的担忧