57

最近、機能ごとに Java コードをパッケージ化するという Javalobby の投稿http://java.dzone.com/articles/how-ching-java-packageに出会いました。

このアイデアは気に入っていますが、このアプローチについていくつか質問があります。質問をしましたが、満足のいく回答が得られませんでした。StackOverflow の誰かが私の質問を明確にしてくれることを願っています。

コーディング中にパッケージ間を移動する時間を大幅に短縮し、関連するすべてのものを 1 つの場所 (パッケージ) にまとめる機能別パッケージのアイデアが気に入っています。しかし、異なるパッケージ内のサービス間の相互作用についてはどうでしょうか?

ブログ アプリを構築していて、すべてのユーザー関連の操作 (コントローラー/サービス/リポジトリ) をcom.mycompany.myblog.usersパッケージに入れているとします。また、すべてのブログ投稿関連の操作 (コントローラー/サービス/リポジトリ) がcom.mycompany.myblog.postsパッケージ化されています。

ここで、彼が投稿したすべての投稿とともにユーザー プロフィールを表示したいと思います。myblog.posts.PostsService.getPostsByUser(userId)から電話する必要がありmyblog.users.UserController.showUserProfile()ますか?

パッケージ間のカップリングはどうですか?

また、機能ごとのパッケージについて読んだところはどこでも、誰もがそれが良い習慣だと言っています。では、なぜ多くの本の著者やフレームワークでさえ、層ごとにグループ化することを推奨しているのでしょうか? 知りたいだけです:-)

4

3 に答える 3

36

ボブおじさんのパッケージ デザイン原則を見てみましょう。彼は、これらの原則の背後にある理由と動機を説明しています。以下で詳しく説明します。

一緒に再利用されるクラスは一緒にパッケージ化して、パッケージを利用可能な完全な製品の一種として扱うことができるようにする必要があります。また、一緒に再利用されるものは、再利用されないものから分離する必要があります。たとえば、ロギング ユーティリティ クラスは必ずしもファイル io クラスと一緒に使用されるとは限りません。したがって、すべてのログを個別にパッケージ化します。ただし、ロギング クラスは互いに関連している可能性があります。したがって、ロギング用の一種の完全な製品を作成します。たとえば、より良い名前が必要な場合は、commons-logging パッケージを (再) 使用可能な jar にパッケージ化し、io ユーティリティ用の別の完全な製品を、より良い名前が必要な場合に作成します。 io.jar. commons-io ライブラリを更新して Java nio をサポートする場合、必ずしもロギング ライブラリに変更を加えたくない場合があります。したがって、それらを分離することをお勧めします。

ここで、splunk などのツールによるある種のログ分析のために、ログ ユーティリティ クラスで構造化ログをサポートする必要があるとします。ロギング ユーティリティの一部のクライアントは、新しいバージョンへの更新を希望する場合があります。他の人はそうではないかもしれません。したがって、新しいバージョンをリリースするときは、必要なすべてのクラスをパッケージ化し、移行のために一緒に再利用してください。したがって、ユーティリティ クラスの一部のクライアントは、古い commons-logging jar を安全に削除し、commons-logging-new jar に移動できます。他の一部のクライアントは、古い jar で問題ありません。ただし、古いパッケージ化された jar にいくつかのクラスを使用するように強制したという理由だけで、クライアントがこれらの jar (新しいものと古いもの) の両方を持つ必要はありません。

循環依存を避けます。a は b に依存します。bのc; cのd; しかし、d は a に依存します。レイヤーやモジュールなどを定義することは非常に難しく、それらを互いに独立して変更することはできないため、このシナリオは明らかに抑止力になります。

また、レイヤーまたはモジュールが変更された場合に、他のモジュールまたはレイヤーを必ずしも変更する必要がないように、クラスをパッケージ化することもできます。したがって、たとえば、古い MVC フレームワークから残りの API アップグレードに移行することにした場合、ビューとコントローラーのみを変更する必要があります。あなたのモデルはそうではありません。

于 2012-07-31T07:04:40.350 に答える
16

パッケージ設計のための結合以外にも多くの側面があります。OOADの原則、特に次のようなパッケージ設計の原則を検討することをお勧めします。

REPリリース再利用の同等性の原則 再利用のグラニュールはリリースのグラニュールです。

CCP一緒に変更される共通閉鎖原則 クラスは一緒にパッケージ化されます。

CRP一緒に使用される共通再利用原則 クラスは一緒にパッケージ化されています。

ADP非周期的依存関係の原則 パッケージの依存関係グラフにはサイクルがあってはなりません。

SDP安定した依存関係の原則安定性の方向に依存します。

SAP安定した抽象化の原則抽象性は安定性とともに向上します。

詳細については、「アジャイルソフトウェア開発、原則、パターン、および実践」というを読むことができます。

于 2012-07-31T04:58:40.453 に答える
15

個人的には「機能ごとのパッケージ」アプローチが好きですが、パッケージの境界線をどこに引くかについてかなり多くの判断を下す必要があります。これは確かに、多くの状況で実現可能で賢明なアプローチです。

おそらく、パブリック インターフェイスを使用してパッケージとモジュール間のカップリングを実現する必要があります。これにより、カップリングがクリーンで管理しやすくなります。

「blog posts」パッケージが「users」パッケージを呼び出すのは、適切に設計されたパブリック インターフェイスを使用する限り、まったく問題ありません。

ただし、このアプローチを取る場合の大きなアドバイスの 1 つは、依存関係について十分に考慮し、特にパッケージ間の循環依存関係を避けることです。優れた設計は、依存関係ツリーのように見える必要があります。より高いレベルの機能領域は、ユーティリティ関数のライブラリなどに依存する一連の共通サービスに依存します。ある程度、これはフロントを備えたアーキテクチャの「レイヤー」のように見え始めます。バックエンド サービスを呼び出すパッケージを終了します。

于 2012-07-31T05:02:50.940 に答える