1

私はJavaが初めてです。コードを構造化しようとしているときに、Java はソース ファイルの編成 (ディレクトリ構造) をパッケージ構造に、パッケージ構造をクラスの外部可視性 (クラスは他のすべてのパッケージから可視であるか、まったく可視ではない) に密接に結び付けていることを発見しました。

これにより、適切なカプセル化を維持しながら、公開ライブラリの内部実装の詳細を関連する機能の論理ユニットに編成することが非常に困難になります。JSR 294はそれを最もよく説明しています:

現在、実装は複数のパッケージに分割できます。このような実装のサブパーツは、周囲のソフトウェア環境よりも、相互に緊密に結合する必要があります。今日、設計者は、実装の他の部分で必要とされるプログラムの要素を public として宣言することを余儀なくされています。

または、実装全体を 1 つのパッケージに入れることもできます。これは上記の問題を解決しますが、扱いにくく、すべてのサブパーツのすべての内部を相互に公開します。

私の質問は、この制限に対してどのような回避策があり、長所と短所は何ですか? JSR で 2 つ言及されています。論理グループ化にパッケージを使用します (カプセル化に違反しています)。すべてを 1 つのパッケージに入れます (扱いにくい)。これらの回避策に他の長所/短所はありますか? 他の解決策はありますか?(OSGi バンドルについては漠然と認識していますが、それらがどのように機能し、長所と短所が何であるかを理解するのは難しいことがわかりました (おそらくそれは短所です)。通常のパッケージに比べて非常に煩わしいようです。開発と展開へ。

注:私は良い答えに賛成票を投じますが、最良の答えは、他の人の長所と短所を包括的に折り畳むものです(盗作!)。

関連する (ただし、重複しないでください!) 質問

「重複の可能性」の叫びを予想して、SOで見つけた同様の質問を次に示します。参考のためにここにそれらを提示し、私の質問に答えない理由を説明します.

4

3 に答える 3

0

ProGuardなどのツールを使用してJARを再パッケージ化し、構成ファイルで指定したクラスのみを公開できます。(これは、最適化、インライン化、および難読化に加えて行われます。)MavenまたはAntビルドなどでProGuardをセットアップできる場合があるため、ライブラリーを公開するメソッドをパブリックとして記述し、ProGuardを使用してそれらをパブリックから削除します。生成されたJAR。

于 2012-03-08T00:53:59.937 に答える
0

これが問題だと思ったことはありません。回避策 (と呼びたい場合) は、優れた API 設計と呼ばれます。

ライブラリを適切に設計すれば、ほとんどの場合、次のことができます。

  • 「my.package.core」または単に「my.package」など、メインのパブリック API を 1 つのパッケージに入れます。
  • (論理グループに従って) ヘルパー モジュールを他のパッケージに入れますが、それぞれに独自のパブリック API サブセットを与えます (たとえば、"my.package.foobarimpl.FoobarFactory" のようなファクトリ クラス)。
  • メインのパブリック API パッケージは、ヘルパー モジュールのパブリック API のみを使用します
  • また、テストは主にパブリック API に対して実行する必要があります (これは、回帰または機能の観点から関心があるためです)。

したがって、パッケージの「適切なレベルのカプセル化」とは、パッケージを依存関係として効果的に使用できる十分なパブリック API を公開することです。それ以上でもそれ以下でもありません。同じライブラリ内の別のパッケージで使用されているか、外部ユーザーによって使用されているかは問題ではありません。この原則に基づいてパッケージを設計すると、効果的な再利用の可能性が高まります。

パッケージの一部を「グローバルにアクセスできる」ようにしても、API が適切に設計されている限り、実際には何の害もありません。パッケージはオブジェクト インスタンスではないため、カプセル化はそれほど重要ではないことに注意してください。通常、パッケージの要素を公開することは、クラスの内部実装の詳細を公開することよりもはるかに害が少なくなります (これはほとんど常に非公開にする必要があることに同意します)。保護されています)。

たとえば、java.lang.String を考えてみましょう。これには大きな公開 API がありますが、公開 API で何をしても、java.lang.String の他のユーザーに干渉することはできません。同時に複数の場所から依存関係として使用しても完全に安全です。一方、java.lang.String のユーザーが内部の文字配列に直接アクセスできるようにすると、すべての地獄が解き放たれます (これにより、不変の文字列のインプレース ミューテーションが可能になります....厄介です!!)。

PS OSGi は非常に優れたテクノロジであり、多くの状況で非常に役立つため、OSGi は特別に言及されています。ただし、そのスイート スポットは、モジュールの展開とライフサイクル管理 (停止/開始/読み込みなど) に関するものです。コード編成のIMHOには実際には必要ありません。

于 2012-03-08T01:41:50.970 に答える
0

私はボールを転がします。この答えを盗んで、それに追加/修正/精巧にしてください!

複数の論理グループに複数のパッケージを使用する

長所: 関連するコードの効果的な論理グループ化。

短所: 異なるパッケージ内の内部実装の詳細クラスが相互に使用する必要がある場合、エンド ユーザーに対しても公開する必要があり、カプセル化に違反します。(これを回避するには、.internal や .impl などの内部実装の詳細を含むパッケージの標準命名規則を使用します)。

すべてを 1 つのパッケージに入れる

長所: 効果的なカプセル化

短所: ライブラリに多くのクラスが含まれている場合、ライブラリの開発/保守には扱いにくい

OSGi バンドルを使用する

長所:?(彼らは問題を解決しますか?)

短所: 単に .jar ファイルを展開する場合と比較して、開発 (ライブラリ ユーザーと作成者の両方にとって) と展開が非常に煩わしいようです。

Java 8 でジグソーを待つ

http://openjdk.java.net/projects/jigsaw/

長所:問題を完全に修正しますか?

短所: まだ存在していません。具体的なリリース日は不明です。

于 2012-03-08T00:59:42.070 に答える