web-dev-qa-db-ja.com

データ結合とは正確には何ですか?その欠点は何ですか?

私はそれに遭遇しました この記事

メソッドを呼び出して、制御フローに影響を与えないパラメータを渡します。

これはまだ結合していますが、それほど悪くない種類に到達し始めています。時々あなたはパラメータが必要です!すべての結合を削除したい場合、オブジェクト間でデータを渡すことができなくなります。

class ScreenPrinter
  # This method is coupled to its parameter, because a change to that argument
  # can cause breakage (if we undefined to_s, for example).
  def print(text)
    output_to_screen(text.to_s)
  end
end

textが単なる文字列で、printtextoutput_to_screenに渡した場合なし次のように、そのプロパティにアクセスするか、そのメソッドを呼び出す:

class ScreenPrinter
  def print(text)
    output_to_screen(text)
  end
end

それでもデータ結合ですか?答えは「はい」のように思えます。どのデータが渡されるかを知らなければ、printが何をするかを予測することはできません。

そのような場合のデータ結合は悪いことですか?

2
Adam Zerner

実質的な参照のみ 「データカップリング」を見つけることができる Wikipedia および記事の定義とはかなり異なります。

LDRA論文 では、データ結合は

ソフトウェアコンポーネントのデータへの依存は、そのソフトウェアコンポーネントの制御下に限定されません。

彼らの例は:

このデータカップリングの不具合のデモンストレーションでは、2つの関数、CalculateAirspeedとDisplay-Airspeedを検討します。どちらも同じメインプログラム(上記の図)から呼び出され、グローバル変数「speed」を共有します。 Calculate-Airspeedは、変数「speed」の値、つまりセット操作を計算します。一方、関数Display-Airspeedは、「speed」の値を表示デバイス、つまり使用操作に出力します。メインプログラムは、以下に示す形式の場合があります。

int main(){
 int speed, order;
loop:
 get(order);
 switch( order ){
 case 1: calculate_airspeed(speed);
 case 2: display_airspeed(speed);
 }
 goto loop;
}

この論文は、display_airspeeddisplay_airspeedとは独立して宣言および設定されているため、speedに結合されていると述べています。 display_airspeedは、操作の順序を上に切り替えると壊れます。

データ結合という用語の精神はより広いと思うので、この定義は好きではありません。はい、display_airspeedspeedに結合されたデータですが、これはプログラムの実行やフローとは無関係です。ウィキペディアのエントリによると、彼らの例は「一般的な結合」をよりよく示しています。

ウィキペディアのエントリーとあなたが読んだ記事は、データ結合のより広い定義を取ります。ウィキペディアが使用するもの:

データ結合は、モジュールがパラメーターなどを介してデータを共有するときに発生します。各データは基本要素であり、これらは共有される唯一のデータです(たとえば、平方根を計算する関数に整数を渡す)。

テキストが単なる文字列であり、そのプロパティにアクセスしたり、メソッドを呼び出したりせずに、渡されたテキストをoutput_to_screenに出力した場合はどうなりますか?...それでもデータ結合ですか?

はい。 printは引き続き2つの方法でデータ結合されます。

  1. パラメータtextの存在自体は、定義に従ってデータカップリングです。これは、パラメータを削除してprintパラメータなしにするか、パラメータを追加すると、重大な変更になるためです。したがって、printは、単一のパラメーターが渡されることに結合されたデータです。
  2. @Aelexeが言うように、printtextの型に結合されます。あなたの例のような動的に型付けされた言語でも、output_to_screenFooが渡されることを期待している場合、printを呼び出してBarを渡します。 printが壊れます(printが誤ってoutput_to_screenを呼び出しているため)。したがって、printは、output_to_screenのため、Foo型に推移的にデータ結合されます。これがデータ結合であるかどうかは実際にはわかりません。実際には、textのタイプへの「外部結合」である可能性があります。

to_sへの呼び出しを削除することで、「スタンプカップリング(データ構造化カップリング)」と私が信じているものを(Wikipediaの定義から)削除しました

スタンプカップリングは、モジュールが複合データ構造を共有し、その一部、場合によっては異なる部分のみを使用する場合に発生します

この場合、printは実際には文字列のみを必要としますが、パラメーターは異なるタイプであり、printtextto_sメンバーにアクセスして文字列値を取得します。したがって、printtextstructureに結合し、to_sの変更または未定義は重大な変更です。

1
Samuel