循環パッケージの依存関係を解決する方法


11

ほとんどのクラスが1つのパッケージに配置されている大規模なコードベースをリファクタリングしています。モジュール性を高めるために、各機能のサブパッケージを作成しています。

パッケージ依存関係グラフにはループがあってはならないことをどこかで覚えていましたが、次の問題を解決する方法がわかりません:FigureパッケージfigureLayoutあり、パッケージlayoutLayoutあり、レイアウトを実行するために図が必要なので、パッケージlayoutはパッケージに依存しますfigure。しかし、一方で、a FigureFigure、その中に他のを含むことができ、独自のを持ちLayout、packageをpackageにfigure依存させますlayout

実装するContainerインターフェイスを作成FigureしてLayoutパッケージに入れるなど、いくつかのソリューションがあります。これは良い解決策ですか?他の可能性はありますか?

ありがとう


モジュール(異なるJarsなど)は循環依存関係を持つことができません。パッケージは、同じモジュールに属している限り、循環依存を持ち、しばしば循環依存を持ちます。
ロルス

@lorusだから、これは設計上の問題ではありませんか?
vainolo

2
いいえそうではありません。通常、パッケージは単なる名前空間です。これは、OSGi環境でコンテンツの可視性を変更するなど、他の目的で使用した場合にのみ変更される場合があります。そうでなければ気にしないでください。
ロルス

1
多くの当局が周期的な依存関係を非難し、時には正当な理由で非難しますが、盲目的にリファクタリングする前に、それらの理由のいずれかが実際に当てはまることを確認する必要があります。パッケージ構造に問題がなく、良心で、なぜそれが将来的になるのかを知ることができない場合、抽象的なアーキテクチャ値を満たすためだけに基本的なものを変更しないでください。
キリアンフォス

回答:


9

制御の反転について考える必要があります

基本的Layoutに、独自のパッケージでレイアウトクラスの近くにあるインターフェイスを定義します。そのため、実装パッケージとパブリックインターフェイスパッケージが必要になります。たとえば、呼び出しますLayoutable(適切な英語かどうかはわかりません)。現在-レイアウトはそのインターフェースではなくFigureクラスを実装します。同様にDrawable、たとえばFigureのインターフェースを作成します。

そう

my.public.package.Layoutable
my.implementation.package.Layout
my.public.package.Drawable
my.implementation.package.Figure

今-FigureはLayoutableを実装しているため、Layoutで使用できます(それがあなたの望むものかどうかはまだわかりません)-LayoutはDrawableを実装し、Figureに描画できます。ポイントは、何らかのサービスを公開するクラスがインターフェース(ここではLayoutとLayoutable)で利用できるようにすることです。そのサービスを使用するクラスはインターフェースを実装する必要があります。

次に、両方を一緒にバインドするクリエーターオブジェクトのようなものがあります。そのため、作成者はLayoutだけでなくにも依存しますFigureLayoutFigureそれ自体は独立しています。

それは大まかな考えです。

この問題を解決するための優れた情報源は、Kirk Knoernschildの著書Java Application Architectureです。


これContainerは質問で提案されているインターフェイスと同じではありませんか?
vaughandroid

はい-いいえ-私が述べたように両方を同じパッケージに入れません。そして、その背後にある理論はあまりありませんでした。この場合、片側でそれを行うだけでは不十分です。両側で行う必要があります。大丈夫?
michael_s

おっと、Container同じパッケージに入れることに関する最初の質問の一部を見逃しましたLayout。あなたのソリューションはそうですが、それはうまくいきません。
vaughandroid

ああ-
わかり

0

私はa Figureが何であるかについてあまり明確ではありませんが、おそらくそれはと同じパッケージにあるべきLayoutですか?

提案されたContainerインターフェイスソリューションは機能しません。Containerインターフェイスを3番目のパッケージに入れない限り、2つのパッケージ間に循環依存関係があります。機能するものについては、michael_sの回答を参照してください。

他の人が言及したように、別のこと-それはおそらく問題になることはありません。あなただけの場合は、将来的に問題に実行するつもりだFigureLayout別のになりたいモジュール。これが必要になった場合に対処できますが、2つのクラスが非常に密接に関連しているように思われる場合、これはほとんどありそうにないようです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.