6

プロジェクト間の循環参照が多数含まれているVisualStudioソリューションを継承しました。

これがリモートで受け入れられる状況はありますか?

このアプリケーションがひどく設計されているという私の疑いを確認しようとしているだけです。前もって感謝します。

4

4 に答える 4

8

スパゲッティモデル、ラザニアモデル、ラビオリモデルの3種類のモデルを比較したコラムを読んだことがあります。

スパゲッティモデルでは、すべてのコードが相互にリンクされており、明確な構造はありません。それは恐ろしいことです、そして私たちはおそらくそれに同意することができます。

ラザニアモデルでは、コードはさまざまなレイヤーに分割されており、上位レベルのレイヤーのみが下位レベルのレイヤーにアクセスできます。その逆はありません。

Ravioliモデルでは、コードは小さなモジュールにグループ化されます。すべてのモジュールは、公開する必要があるものだけを公開しますが、すべてのモジュールは他のすべてのモジュールにアクセスできます。

約10年前、ラビオリモデルはラザニアモデルよりも優れているように思えました。結局のところ、Javaには、相互に簡単に呼び出すことができるJavaモジュールもあります(そして、すべての異なるJavaモジュールの間に実際の構造がないという印象を受けました)。私には、Lasagnaモデルは非オブジェクト指向の古いコードの結果であるように見えましたが、Ravioliモデルはより現代的でよりオブジェクト指向であるように見えました。

最近はラザニアモデルに戻る傾向がありますが、ラビオリモデルが組み込まれています。これは:

  • アプリケーションは、Lasagnaモデルのように、さまざまなレイヤーを使用して構築されています
  • ただし、レイヤー内では、Ravioliモデルのように、コードは相互にアクセスできる異なるモジュール間で分割されます。

特定の循環参照は、削除が困難または不可能な場合があります。例は次のとおりです。アプリケーションにFileWriterクラスとDebugクラスがあるとします。Debugクラスは、デバッグ情報を含むファイルを書き込む必要があるため、FileWriterクラスが必要になります。一方、FileWriterクラスもDebugクラスを使用したい場合があります。

この例の循環参照はすでに問題を引き起こしている可能性があることに注意してください(FileWriterクラスは行の書き込み中にDebugクラスを呼び出すことができますが、DebugクラスはFileWriterクラスを使用してデバッグ情報を書き込みます。結果:スタックオーバーフロー)。

この場合、問題はDebugクラスでFileWriterクラスを使用せずに、ネイティブiostreamを使用することで簡単に解決できます(C ++で開発している場合)。他の場合には、問題を解決するのがはるかに難しいかもしれません。

于 2010-08-27T16:22:25.077 に答える
2

優れたソフトウェアはレイヤーで設計されており、それらの間に明確な境界が設定されています。つまり、レイヤーがある場合、それが何をするのか、なぜそこにあるのか、何に依存するのかを明確に説明できる必要があります。循環性はこれを実現するのを困難にし、通常は除去する必要があります。(Microsoft は Windows 7 で多くの労力を費やして、Windows の階層化を改善し、Circularities を削除しました。)

このアプリケーションが恐ろしく設計されているという私の疑いを確認しようとしています.

これは間違いなくその理論を支持しますが、IMO、その結論を引き出すには、いくつかの循環参照以上のものが必要です.

元の質問に答えるには:はい、循環参照が役立つ場合があります。相互再帰関数は、そのようなことの良い例です。ただし...これは、モジュール内に安全に隠されている循環参照です。モジュール間の依存関係の場合、循環依存関係は通常、コードがモジュール間で正しく分割されていないことを意味し、これを修正するにはかなりのリファクタリングが必要になる場合があります。(ギャップを埋めるための新しい種類のアブスタクションの追加などを含む)

于 2010-08-27T16:02:37.813 に答える
2

具体的には、 NDepend を使用して依存関係のサイクルを検出して回避することをお勧めします。

代替テキスト

記事からの抜粋 (私が書いたもの):コンポーネントの依存関係を制御して、クリーンなアーキテクチャを実現する

コンポーネント間の依存関係のサイクルは、一般にスパゲッティ コードまたはもつれたコードと呼ばれるものにつながります。コンポーネント A が、A に依存する C に依存する B に依存する場合、コンポーネント A は、B および C から独立して開発およびテストすることはできません。このスーパーコンポーネントは、規模の不経済現象のため、A、B、および C のコストの合計よりもコストが高くなります (Steve McConnell による Software Estimation: Demystifying the Black Art で詳しく説明されています)。基本的に、これは、コードの分割できない部分を開発するコストが指数関数的に増加することを意味します。

これは、1,000 LOC (Lines Of Code) の開発と維持は、それぞれ 500 LOC の 2 つの独立した塊に分割できない限り、500 LOC の開発と維持よりも 3 倍から 4 倍のコストがかかることを示唆しています。したがって、保守できない絡み合ったコードを説明するスパゲッティとの比較です。アーキテクチャを合理化するには、コンポーネント間に依存関係のサイクルがないことを確認する必要がありますが、各コンポーネントのサイズが許容範囲内 (500 ~ 1000 LOC) であることも確認する必要があります。

于 2010-08-29T19:11:15.210 に答える
1

円形のプロジェクト参照は設計が悪いことを示しているため、可能な限り削除する必要があります。

循環参照を維持するために私が考えることができる唯一の正当化は、下位互換性の問題です。それでも、タイプフォワーダーと別のアセンブリを使用して修正できるようです

于 2010-08-27T15:57:02.540 に答える