6

私はしばらくの間、Sonar コード品質管理プラットフォームを使用してきましたが、ほとんどの場合、コード ベースの隠れた設計上の欠陥を明らかにするのに非常に役立ちます。

しかし、ヘルプよりも厄介なルールが 1 つあります。それは、「循環パッケージ参照」違反のチェックです。

パッケージ間のこのような依存関係がどこで悪いのかを完全に理解していると思います。たとえば、典型的な 3 層のプレゼンテーション/サービス/パーシステンス レイヤー設計では、ほとんどの場合、データベース処理コードに UI 関連クラスへの参照を持たせることはお勧めできません。「違反」と呼んでも問題ありません。

しかし、IDE ライクなアプリケーションの設計など、他のケースを考えてみましょう。たとえば、アプリケーションのビューを参照するメソッドをApplication定義するインターフェイスを含むメイン パッケージがあるとします。List<View> Application.getViews()

ただし、ViewインターフェイスにApplication getApplication()親アプリケーションを参照するメソッドがある場合 (これは非常に一般的な設計だと思います)、各インターフェイスがそれぞれ 、com.myapp.ui、および で区切られていれば、循環参照が導入されcom.myapp.ui.viewます。

もちろん、Viewインターフェイスを に挿入しcom.myapp.uiてサイクルを断ち切ることもできます。しかし、ビューに関連するさまざまな API が にある場合、それらの多くは、、などcom.myapp.ui.viewの別の抽象 APIです。管理目的でそれらを別のパッケージに保持する方が賢明ではないかと思います。AbstractViewContentViewAbstractContentView

com.myapp.ui.actionそして、上記のアプリケーションには、 、 などのような他の多くの同様のケースがあると考えてください。それらをすべてそこに入れると、パッケージcom.myapp.ui.perspectiveが本当に混雑します。com.myapp.ui

では、このような状況に対処するためにどのようなアプローチをお勧めしますか? 本当にすべての循環パッケージ参照は悪いことですか? または、彼らと一緒に暮らす必要がある場合、問題のある実際のサイクルのみをチェックするように Sonar をどのように設定しますか?

4

2 に答える 2

6

すべての絶対 - これを除いて ;) - は時々間違っています。では、すべての循環参照は悪いのでしょうか? いいえ、ご自身の判断で行ってください。

しかし、循環依存を導入する場合は、本当にそれが必要かどうか、またその理由を尋ねる価値があります。tl;dr は、多くの場合、サイクルを断ち切ることでモジュール性、特にコンポーネントを個別にテストする能力が向上することに気付くかもしれません。

あなたの例を使用するには、getApplication()おそらく比較的「重い」オブジェクト(つまり、それ自体がデータベース、ネットワークなどを必要とするオブジェクト)を返すと思われるビューが本当に必要ですか?たぶん...でもそうではないかもしれません。それから本当に必要なgetApplicationものがいくつかのコールバックを持つものである場合 (ユーザーが何らかのアクションを開始したときなど)、そのコールバック用の共通パッケージでインターフェイスを作成すると便利な場合があります。したがって、ではなく:

com.foo.app.Application
com.foo.view.View
    Application getApplication()

あなたが持っているでしょう:

com.foo.common.Callback // maybe just a Callable, Runnable, etc?
com.foo.app.Application
    provides a Callback for some action foo
com.foo.view.View
    Callback getFooCallback()

あなたが尋ねるべき質問は次のとおりです。それは私に何をもたらしますか? スタブアウトする必要がありすぎて、あまり得られない可能性があります-ただし、クラスをいくつか分解できることを示唆しているかもしれません。しかし、実際にはビューのテストが簡単になる可能性があります。なぜなら、単体テストで (1) アプリケーション全体をスピンアップせずにビューをテストし、(b) ファイルの保存などを行う「ダミー」コールバックを提供できるからです。アクションを説明する文字列を指定すると、単体テストは正しい文字列を保存したことをアサートします。

于 2013-05-14T05:24:16.870 に答える
0

実際、父/子パッケージ間のサイクルを品質上の欠陥と見なすことを防ぐためのオープンな JIRA チケットがあります: http://jira.codehaus.org/browse/SONAR-3452

于 2013-05-26T09:21:07.750 に答える