少し前に、Javaパッケージのきめ細かな組織に関する質問に答えました。たとえば、my.project.util
、my.project.factory
、my.project.service
など。
私は今それを見つけることができないので、質問をすることもできます。
Javaのパッケージの構成に関して、ベストプラクティスはありますか?
Javaプロジェクトでクラスをどのように整理しますか?
たとえば、私が数人で作業しているプロジェクトには、beansというパッケージがあります。単純なBeanを含むプロジェクトから始まりましたが、(ほとんど経験のない)時間をかけて(すべて)を含むプロジェクトになりました。いくつかのファクトリクラスをファクトリパッケージ(Beanを作成する静的メソッドを持つクラス)に入れることで少しクリーンアップしましたが、ビジネスロジックを実行する他のクラスと、取得などの単純な処理(ビジネスロジックではなく)を実行する他のクラスがありますプロパティファイルからのコードのメッセージ。
あなたの考えやコメントを歓迎します。
パッケージの編成またはパッケージの構造化は、通常、白熱した議論です。以下に、パッケージの命名と構造化に関するいくつかの簡単なガイドラインを示します。
com.company.product.modulea
com.company.product.module.web
またはcom.company.product.module.util
など。com.company.product.model
およびcom.company.product.util
など。いくつかの実験とトライアルを行った後、自分が満足できる構造を思いつくことができるはずです。 1つの慣習に固執するのではなく、変更に対してオープンになります。
パッケージを整理します機能別。パターンや実装の役割ではありません。私のようなパッケージだと思う:
beans
factories
collections
間違っている。
例えば、私は好む:
orders
store
reports
パッケージの可視性で実装の詳細を隠すことができます。注文のファクトリはorders
パッケージに含まれている必要があるため、注文の作成方法の詳細は非表示になっています。
簡単な答え:モジュール/機能ごとに1つのパッケージ。サブパッケージがある場合もあります。密接に関連するものを同じパッケージにまとめます。パッケージ間の循環依存を避けます。
長い答え: この記事の大部分に同意します
レイヤーより前の機能が好きですが、それはプロジェクトに依存していると思います。あなたの力を考慮してください:
例:
com/company/module
+ feature1/
- MainClass // The entry point for exploring
+ api/ // Public interface, used by other features
+ domain/
- AggregateRoot
+ api/ // Internal API, complements the public, used by web
+ impl/
+ persistence/
+ web/ // presentation layer
+ services/ // Rest or other remote API
+ support/
+ feature2/
+ support/ // Any support or utils used by more than on feature
+ io
+ config
+ persistence
+ web
これは単なる例です。とてもフォーマルです。たとえば、feature1の2つのインターフェイスを定義します。通常、これは必須ではありませんが、別の人が別の方法で使用する場合は良い考えです。内部APIに公開を拡張させることができます。
「impl」または「support」の名前は好きではありませんが、重要度の低いものと重要なもの(ドメインおよびAPI)を区別するのに役立ちます。ネーミングに関しては、できるだけ具体的になることが好きです。 20個のクラスを持つ「utils」というパッケージがある場合、StringUtils
をsupport/stringに、HttpUtil
をsupport/httpなどに移動します。
Javaのパッケージの構成に関して、ベストプラクティスはありますか?
本当にありません。たくさんのアイデアと意見がありますが、「ベストプラクティス」は常識を使うことです!
ただし、おそらく広く受け入れられているプリンシパルが1つあります。パッケージ構造は、アプリケーションの(非公式の)モジュール構造を反映する必要があり、モジュール間の循環依存関係を最小限に抑える(または理想的には完全に回避する)ことを目指してください。
(パッケージ/モジュール内のクラス間の循環依存関係は問題ありませんが、パッケージ間サイクルはアプリケーションのアーキテクチャを理解するのを難しくする傾向があり、コードの再利用の障壁になる可能性があります。特に、Mavenを使用すると、パッケージ間/モジュール間の依存関係は、相互接続された混乱全体が1つのMavenアーティファクトでなければならないことを意味します。
また、パッケージ名に関する広く受け入れられているベストプラクティスの1つisを追加する必要があります。そして、パッケージ名は組織のドメイン名から逆順で始まる必要があります。この規則に従えば、(完全な)クラス名が他の人と衝突することによって引き起こされる問題の可能性を減らすことができます。
「レイヤーごとのパッケージ」よりも「機能ごとのパッケージ」を宣伝する人がいますが、長年にわたってかなりのアプローチを使用し、「機能ごとのパッケージ」よりも「レイヤーごとのパッケージ」の方がはるかに優れていることがわかりました。
さらに、「機能ごとのパッケージ」の多くの利点があるため、「モジュールごと、レイヤーごと、機能ごとに」というハイブリッド戦略が実際には非常にうまく機能することがわかりました。
ここで詳細に説明します: Javaパッケージ名の構造と組織 しかし、私の標準のパッケージ構造は次のとおりです。
revdomain.moduleType.moduleName.layer。[layerImpl] .feature.subfeatureN.subfeatureN + 1 ...
どこ:
revdomainリバースドメインcom.mycompany
moduleType[app * | framework | util]
moduleName例:モジュールタイプがアプリの場合はmyAppName、会計フレームワークの場合は「finance」
layer[model | ui | persistence | securityなど、]
layerImpl例:wicket、jsp、jpa、jdo、hibernate(注:レイヤーがモデルの場合は使用されません)
feature例えば、finance
subfeatureN例、会計
subfeatureN + 1例:減価償却
* moduleTypeがアプリケーションの場合、「app」が省略されることもありますが、そこに配置すると、パッケージ構造がすべてのモジュールタイプで一貫します。
パッケージ編成の標準的な慣行を知りません。私は通常、ある程度広い範囲をカバーするパッケージを作成しますが、プロジェクト内で差別化することができます。たとえば、現在作業中の個人プロジェクトには、カスタマイズされたUIコントロール(swingクラスをサブクラス化するクラスのフル)専用のパッケージがあります。データベース管理用のパッケージ、作成した一連のリスナー/イベント用のパッケージなどがあります。
一方、私は同僚に彼がやったことのほとんどすべてのために新しいパッケージを作成してもらいました。彼が欲しかった異なるMVCにはそれぞれ独自のパッケージがあり、MVCセットが同じパッケージに含まれることが許可されたクラスの唯一のグループであるように見えました。ある時点で、彼には5つの異なるパッケージがあり、それぞれに単一のクラスが含まれていました。彼の方法は極端なものだと思います(そして、チームは彼が単に処理できなかったときにパッケージ数を減らすことを強制しました)が、重要なアプリケーションでは、すべてを同じパッケージに入れます。それは、あなたとあなたのチームメイトが自分で見つけなければならないバランスポイントです。
あなたができることの1つは、あなたがプロジェクトに紹介された新しいメンバーであったか、あなたのプロジェクトがオープンソースまたはAPIとしてリリースされた場合、あなたが望むものを見つけるのはどれくらい簡単/困難ですか?私にとって、それは私がパッケージから本当に欲しいもの、つまり組織だからです。コンピューターのフォルダーにファイルを保存する方法と同様に、ドライブ全体を検索しなくても、それらのファイルを再び見つけることができると期待しています。パッケージ内のすべてのクラスのリストを検索することなく、必要なクラスを見つけることができることを期待しています。