28

私は自分の Java プロジェクトでいくつかのメトリックを実行してきましたが、どうやらパッケージ間に多くの依存関係の循環があるようです。ものをパッケージにまとめる方法を本当に知らなかったので、自分にとって意味のあることをしただけで、明らかに間違っています。

私のプロジェクトはニューラル ネットワーク フレームワークです。ニューラル ネットワークにはニューロンがあり、これらは Connections で相互に接続されています。彼らはお互いに依存する必要があります。ただし、Neuron にもさまざまな種類があるので、それらをすべて独自の「neurons」パッケージに入れることをお勧めします。明らかに Connection は Neuron ではないため、パッケージに含めるべきではありませんが、相互に参照しているため、循環依存関係があります。

これはほんの一例ですが、このような状況は他にもあります。このような状況にどのように対処しますか?

また、パッケージ階層の上位にあるパッケージのクラスは、より深いパッケージのクラスを参照することは想定されていないことを読みました。これは、パッケージ 'nn' の NeuralNetwork クラスがパッケージ 'nn.neurons' の Neuron を参照できないことを意味します。皆さんはこの原則に従っていますか?NeuralNetwork を「nn.networks」などに移動するとどうなるでしょうか。その場合、子パッケージではなく兄弟パッケージを参照します。それはより良い習慣ですか?

4

5 に答える 5

13

antcontrib VerifyDesign タスクは、必要なことを行うのに役立ちます。

たとえば、1 つのソース ツリーに 3 つのパッケージがある場合

* biz.xsoftware.presentation
* biz.xsoftware.business
* biz.xsoftware.dataaccess

当然、プレゼンテーションはビジネス パッケージのみに依存し、ビジネスはデータアクセスに依存する必要があります。このように設計を定義し、これに違反すると、verifydesign ant タスクが呼び出されたときにビルドが失敗します。たとえば、biz.xsoftware.presentation でクラスを作成し、そのクラスが biz.xsoftware.dataaccess のクラスに依存している場合、ビルドは失敗します。これにより、設計がドキュメントに記載されている内容に実際に従っていることが保証されます (少なくともある程度は)。これは、自動ビルドでは特に便利です

したがって、編成方法を決定したら、コンパイル時に要件を適用できます。また、細かい制御ができるため、特定のケースでこれらの「ルール」を破ることを許可できます。したがって、いくつかのサイクルを許可できます。

やりたいことによっては、「utils」パッケージが理にかなっていることがあります。

あなたが引用した特定のケースについて...私は次のようなことをするかもしれません:

  • パッケージ nn には Nueron と Connection が含まれています
  • パッケージ nn.neurons には Nueron のサブクラスが含まれています

Neuron と Connection はどちらも NeuralNetowrk で使用される高レベルの概念であるため、これらをすべてまとめることは理にかなっています。Neuron クラスと Connection クラスは相互に参照できますが、Connection クラスは Neuron サブクラスについて知る必要はありません。

于 2009-03-22T16:17:02.327 に答える
5

あなたが説明したような循環的な依存関係が悪いとは思いません。相互に依存する概念が同じ抽象化レベルにあり、アーキテクチャの同じ部分に関連している限り、これらを互いに隠す必要はありません。私の理解では、ニューロンと接続はこの法案に適合します。

このような結合を減らす一般的な方法は、インターフェイスを抽出し、場合によってはこれらを別のモジュールに入れることです。1 つのプロジェクト内でパッケージごとに整理するだけでは、実装の詳細を十分に隠すことはできません。実装を実際に隠すことができる一般的なパターンは次のとおりです。

クライアント コード ----> インターフェイス <--- 実装

このパターンでは、「実装」モジュールをクライアント コードから非表示にします。つまり、「クライアント コード」モジュールのコードには実装コードが表示されません。

パッケージの入れ子には、いくつかの目的があります。 一部のプロジェクトには、パッケージで編成されたドメイン モデルがある場合があります。この場合、パッケージはドメインのグループ化を反映しており、参照はパッケージを上/下に移動する可能性があります。サービスの実装などに関しては、提案されたパターンは非常に一般的であり、従うのは良いことです. パッケージ階層が深くなるほど、クラスはより具体的であると考えられます。

于 2009-03-22T12:52:30.277 に答える
5

どのようなコードサイズについて話しているのですか? クラスが 10 ~ 20 個しかない場合は、コードをパッケージ化するためだけに過度に編成する必要はおそらくありません (すべきではありません)。

プロジェクトが大きくなるにつれて、最初に区別したいのは、ユーザー インターフェイス コードを基になるデータ モデルとロジックから分離することです。適切な単体テストを行うには、レイヤーを明確に分離することが重要です。

循環依存関係を取り除くのに問題がある場合は、おそらくクラスが実際には相互依存しており、同じパッケージに存在する必要があります。

抽象化レイヤーを正しく設定することは、コード構造全体を設計する際におそらく最も重要な側面の 1 つです。

于 2009-03-22T12:53:27.137 に答える
5

このような状況にどのように対処しますか?

循環依存は本質的に悪いものではありません。実際、これは「病気よりも悪い治療法」のケースである場合があります。インターフェイスを抽出すると、コードの複雑さが増し、別の間接レイヤーが追加されます。これは、非常に単純な関係にはおそらく価値がありません。

于 2009-03-22T12:55:41.813 に答える