これがシナリオです。公に認可されたオープン ソース API の作成者として、私のグループは Java ベースの Web ユーザー インターフェイス フレームワークを作成しました (それ以外に何が新しいのでしょうか?)。Java で物事を適切に整理するために、命名規則 org.mygroup.myframework.x を持つパッケージを使用しました。x は、コンポーネント、バリデーター、コンバーター、ユーティリティなどのようなものです (繰り返しますが、他には何がありますか?新着?)。
ここで、クラス org.mygroup.myframework.foo.Bar のどこかにvoid doStuff()
、フレームワークに固有のロジックを実行する必要があるメソッドがあり、フレームワークの他のいくつかの場所 (org. mygroup.myframework.far.Boo. Boo が Bar のサブクラスでもまったく同じパッケージでもないことを考えると、メソッド doStuff() は、Boo から呼び出せるように public として宣言する必要があります。
ただし、私のフレームワークは、他の開発者がクライアント用によりシンプルで洗練された RIA を作成できるようにするためのツールとして存在します。しかし、com.yourcompany.yourapplication.YourComponent が doStuff() を呼び出すと、予期しない望ましくない結果が生じる可能性があります。私は、これが決して起こらないことを望みます。 Bar には、真にパブリックな他のメソッドが含まれていることに注意してください。
象牙の塔の世界では、Java 言語を書き直して、トークン化されたアナログをデフォルト アクセスに挿入します。これにより、選択したパッケージ構造内の任意のクラスが私のメソッドにアクセスできるようになります。おそらく次のようになります。
[org.mygroup.myframework.*] void doStuff() { .... }
ここで、ワイルドカードは、パッケージが org.mygroup.myframework で始まるすべてのクラスを呼び出すことができますが、他の誰も呼び出すことができないことを意味します。
この世界が存在しないことを考えると、他にどのような良い選択肢があるでしょうか?
これは実際のシナリオに基づいていることに注意してください。有罪を保護するために名前が変更されました。実際のフレームワークが存在し、Javadoc 全体に散りばめられたパブリック メソッドには、「このメソッドは MYFRAMEWORK の内部であり、パブリック API の一部ではありません。呼び出さないでください!!!!!!」とコメントされています。少し調査したところ、これらのメソッドはフレームワーク内の別の場所から呼び出されていることがわかりました。
実は、私は問題のフレームワークを使用している開発者です。私たちのアプリケーションはデプロイされ、成功していますが、私のチームは非常に多くの課題を経験したため、上司にこのフレームワークを二度と使用しないよう説得したいと考えています。私たちはこれを、フレームワークの開発者が下した不適切な設計上の決定をよく考え抜いた形で提示したいと考えています。単なる暴言としてではありません。この問題は、(いくつかの) ポイントの 1 つですが、どうすれば別の方法で解決できたのかはわかりません。私の職場ではすでに活発な議論が行われているので、他の人はどう思うだろうかと思いました。
更新: これまでのところ 2 人の回答者に不快感を与えることはありませんが、的を外したか、うまく表現できなかったと思います。いずれにせよ、私が物事を照らそうとすることを許可してください. できるだけ簡単に言えば、フレームワークの開発者は次のことをどのようにリファクタリングするべきでしたか。これは非常に大まかな例であることに注意してください。
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 で内部アクセスをシミュレート/エミュレートする方法は?」ということだったかもしれません。とはいえ、私は新しい答えを探しているわけではありません。私たちの上司は最終的に上記の懸念に同意しました