web-dev-qa-db-ja.com

凝集とカップリングの違い

凝集と結合の違いは何ですか?

カップリングと結束はどのようにして良いまたは悪いソフトウェア設計につながるのでしょうか。

両者の違いと、それがコード全体の品質に与える影響を概説する例は何ですか?

415
JavaUser

Cohesion はクラス(またはモジュール)ができることを表します。結束力が低いということは、そのクラスが多種多様な行動をとることを意味します。凝集性が高いということは、そのクラスがやるべきこと、すなわちクラスの意図に関連する方法だけに焦点を当てているということです。

低凝集の例:

-------------------
| Staff           |
-------------------
| checkEmail()    |
| sendEmail()     |
| emailValidate() |
| PrintLetter()   |
-------------------

高凝集の例

----------------------------
| Staff                   |
----------------------------
| -salary                 |
| -emailAddr              |
----------------------------
| setSalary(newSalary)    |
| getSalary()             |
| setEmailAddr(newEmail)  |
| getEmailAddr()          |
----------------------------

カップリング に関しては、2つのクラス/モジュールが互いに関連しているか依存しているかを示します。結合度の低いクラスでは、あるクラスで大きな変更を行っても他のクラスには影響しません。カップリングが大きいと、コードを変更したり保守したりするのが難しくなります。クラスは密接に結び付いているため、変更を加えるにはシステム全体の見直しが必要になる可能性があります。

良いソフトウェア設計は 高い凝集力 そして 低い結合力 を持ちます。

606
mauris

高結束 モジュールおよび低結合 モジュールは、OOプログラミング言語では高品質に関連すると見なされることがよくあります。

たとえば、各Javaクラス内のコードは高い内部結合性を持つ必要がありますが、他のJavaクラス内のコードとできるだけ疎結合にする必要があります。

第3章/ - Meyerのオブジェクト指向ソフトウェア構築(第2版) は、これらの問題についての素晴らしい説明です。

69
CesarGon

Cohesionはモジュールの関係を示します。

Couplingは、関係{betweenモジュールの指標です。

enter image description here

結束

  • 結束は、モジュール内の関係を示しています。
  • 凝集力はモジュールの相対的な機能的強度を示します。
  • 結束度は、コンポーネント/モジュールが単一のものに焦点を合わせる程度(品質)です。
  • 設計している間、あなたはシステムの他のモジュールとほとんど相互作用することなく、高い凝集力、すなわち凝集力のあるコンポーネント/モジュールが単一のタスク(すなわち、志向性)に焦点を合わせるように努めるべきです。
  • Cohesionはデータ隠蔽の一種の自然な拡張であり、たとえば、デフォルトの可視性を持つパッケージを使ってすべてのメンバを可視にするクラスです。結束はモジュール内の概念です。

カップリング

  • カップリングはモジュール間の関係の指標です。
  • カップリングは、モジュール間の相対的な依存関係/相互依存関係を示します。
  • カップリングは、コンポーネント/モジュールが他のモジュールに接続されている程度です。
  • 設計している間あなたは低いカップリングに努めるべきです、すなわちモジュール間の依存はより少なくあるべきです
  • プライベートフィールド、プライベートメソッド、および非パブリッククラスを作成すると、疎結合が発生します。
  • カップリングはモジュール間の概念です。

チェック これ リンク

51
Buddhika Alwis

Cohesion は、ソフトウェア要素の責任がどの程度関連しており、その責任が集中しているかを示しています。

結合 は、ソフトウェア要素が他の要素にどれだけ強く接続されているかを示します。

ソフトウェア要素は、クラス、パッケージ、コンポーネント、サブシステムまたはシステムです。そしてシステムを設計する間、 高い凝集力 を持ち、 低い結合 を持つソフトウェア要素を持つことが推奨されます。

低凝集性 の結果、モノリシッククラスが維持、理解、および再利用が困難になります。同様に、 高い結合 は密接に結合されたクラスになり、変更は局所的ではなく、変更が困難で再利用が減少します。

次の要件を満たす典型的な監視可能なConnectionPoolを設計しているという仮定のシナリオを取ります。 ConnectionPoolのような単純なクラスを探しすぎるかもしれませんが、基本的な目的は単純な例を使って low coupling high cohesion を実証することです。

  1. 接続の取得をサポート
  2. 接続を解除する
  3. 接続数と使用数の統計情報を取得する
  4. 接続と時間の統計情報を取得する
  5. 後で検索できるように、接続の取得情報と解放情報をデータベースに格納します。

low cohesion を使うと、以下のようにこれらすべての機能/責任を1つのクラスに強制的に詰め込むことによってConnectionPoolクラスを設計できます。この単一クラスが接続管理、データベースとの対話、接続統計の管理を担当していることがわかります。

Low Cohesion Connection Pool

高い凝集力 を使うと、クラス間でこれらの責任を割り当て、それをより保守可能で再利用可能にすることができます。

High Cohesion Connection Pool

低結合 を実証するために、上の高凝集度ConnectionPool図を続けます。上の図を見てみると、高い凝集力をサポートしていますが、ConnectionPoolConnectionStatisticsクラスおよびPersistentStoreと密接に結び付いており、ConnectionListenerと直接相互作用します。結合を減らすために、ConnectionPoolインターフェースを導入し、これら2つのクラスにインターフェースを実装させ、それらをConnectionPoolクラスに登録させることができます。そしてFacadeはこれらのリスナーを繰り返し処理して接続の取得と解放のイベントを通知し、結合を減らすことができます。

Low Coupling ConnectionPool

注/ WordまたはCaution: この単純なシナリオではやり過ぎに見えるかもしれませんが、トランザクションを完了するためにアプリケーションが複数のサードパーティサービスと対話する必要があるリアルタイムのシナリオを想像すると、サードパーティサービスのコードは、サードパーティサービスの変更によって複数の場所でコードが変更される可能性があることを意味します。代わりに、これらの複数のサービスと内部的に対話するFacadeを持つことができます。また、サードパーティのサービスとの連携を低くします。

結合力の増加と結合の減少は、優れたソフトウェア設計につながります。

Cohesionはあなたの機能をそれが関連するデータに簡潔で最も近いものになるように分割し、一方デカップリングは機能の実装がシステムの他の部分から分離されることを確実にします。

デカップリング を使用すると、ソフトウェアの他の部分に影響を与えずに実装を変更できます。

Cohesion を使用すると、実装は機能に固有であり、同時に保守も容易になります。

結合を減少させ、凝集力を増加させる最も効果的な方法は 界面による設計 です。

つまり、主要な機能オブジェクトは、それらが実装しているインタフェースを通してのみお互いを「知る」べきです。インターフェースの実装は、当然の結果として結束をもたらします。

いくつかのシナリオでは現実的ではありませんが、作業することが設計上の目標であるはずです。

例(とても大ざっぱ)

public interface IStackoverFlowQuestion
      void SetAnswered(IUserProfile user);
      void VoteUp(IUserProfile user);
      void VoteDown(IUserProfile user);
}

public class NormalQuestion implements IStackoverflowQuestion {
      protected Integer vote_ = new Integer(0);
      protected IUserProfile user_ = null;
      protected IUserProfile answered_ = null;

      public void VoteUp(IUserProfile user) {
           vote_++;
           // code to ... add to user profile
      }

      public void VoteDown(IUserProfile user) {
          decrement and update profile
      }

      public SetAnswered(IUserProfile answer) {
           answered_ = answer
           // update u
      }
}

public class CommunityWikiQuestion implements IStackoverflowQuestion {
     public void VoteUp(IUserProfile user) { // do not update profile }
     public void VoteDown(IUserProfile user) { // do not update profile }
     public void SetAnswered(IUserProfile user) { // do not update profile }
}

コードベースの他の場所に、質問が何であるかにかかわらず、質問を処理するモジュールがある場合があります。

public class OtherModuleProcessor {
    public void Process(List<IStackoverflowQuestion> questions) {
       ... process each question.
    }
}
31
Adrian Regan

Cohesionの最も良い説明は、Uncle BobのClean Codeから来ています。

クラスは少数のインスタンス変数を持つべきです。クラスの各メソッドは、これらの変数の1つ以上を操作する必要があります。 一般に、メソッドが操作する変数が多いほど、そのメソッドはそのクラスに対してよりまとまりのあるものになります。各メソッドで各変数が使用されるクラスは、最大限凝集的です。

一般的に、このような最大凝集力のあるクラスを作成するのは賢明でも不可能でもありません。一方、結合力が高いことを望みます _。結束力が高い場合は、クラスのメソッドと変数が相互に依存し、論理的にまとまっていることを意味します。

関数を小さくし、パラメータリストを短くするという戦略は、メソッドのサブセットで使用されるインスタンス変数の急増につながることがあります。これが起こるとき、それはより常に大規模なクラスから抜け出そうとしている他のクラスが少なくとも1つあることを意味します。新しいクラスがよりまとまりのあるものになるように、変数とメソッドを2つ以上のクラスに分割するようにしてください。

24

ソフトウェア工学における Cohesion は、あるモジュールの要素がどの程度一緒に属しているかを表します。したがって、それはソフトウェアモジュールのソースコードによって表現された各機能性がどれほど強く関連しているかの尺度である。

カップリング 簡単に言うと、1つのコンポーネントが別のコンポーネントの内部の動作や内部の要素について知っている量(つまり、クラスを想像する必要はありません)です。

私はこれについてブログ記事を書いた 、あなたが例と図面でもう少し詳細を読みたいならば。私はそれがあなたの質問の大部分に答えていると思います。

11
TheBoyan

単純に、 Cohesion は、コードベースの一部が論理的に単一の原子単位を形成する度合いを表します。一方、 カップリング は、単一のユニットが他のユニットから独立している程度を表します。つまり、2つ以上のユニット間の接続数です。数が少ないほど、カップリングは低くなります。

本質的に、結束性が高いということは、互いに関連するコードベースの一部を1か所にまとめることを意味します。同時に、低カップリングとは、コードベースの無関係な部分をできるだけ分離することです。

結合と結合の観点から見たコードの種類

理想 は、ガイドラインに従うコードです。それは疎結合で非常に凝集性があります。私たちはこの絵でそのようなコードを説明することができます: enter image description here

ゴッドオブジェクト は、高い凝集力と高いカップリングをもたらした結果です。それはアンチパターンであり、基本的に一度にすべての作業を行う単一のコードを表します: enter image description here 不適切に選択された 異なるクラスまたはモジュール間の境界が不適切に選択された場合に発生する enter image description here

破壊的デカップリング が最も興味深いものです。プログラマーがコードベースを切り離そうとしてコードが完全にフォーカスを失うことを試みるとき、それは時々起こります: enter image description here

続きを読む ここ

enter image description here

結束とは、単一クラスの設計方法のすべてを指します。結束は、クラスが単一の、焦点を絞った目的で設計されていることを確認することと最も密接に関連しているオブジェクト指向の原則です。クラスの焦点が合っているほど、そのクラスのまとまりが強くなります。凝集度が高いことの利点は、凝集度が低いクラスよりも、そのようなクラスの方がはるかに保守が容易である(そして変更頻度が少ない)ことです。結束度が高いことのもう1つの利点は、目的が明確に定められているクラスが他のクラスよりも再利用可能になる傾向があることです。

上の画像では、低結束では1つのクラスだけが共通ではない多くのジョブの実行を担当しているため、再利用性とメンテナンスの可能性が低くなります。しかし、結束度が高い場合は、すべてのジョブが特定のジョブを実行するための個別のクラスが存在するため、使いやすさと保守性が向上します。

3
vkstream

Cohesion(Co-hesion):Cotogetherを意味し、hesionstickingを意味します。異なる物質の粒子をくっつけるシステム。

実際の例では、
enter image description here
img礼儀

全体は部品の合計よりも大きい - Aristotle。

  • Cohesionは通常の測定タイプで、通常は「高凝集」または「低凝集」と呼ばれます。高い凝集性は、堅牢性、信頼性、再利用性、および理解可能性を含むソフトウェアのいくつかの望ましい特性に関連しているため、高い凝集性を持つモジュールが好ましい傾向があります。対照的に、低い凝集性は、維持すること、テストすること、再利用すること、または理解することさえ困難であるなどの望ましくない特徴と関連している。 ウィキ

  • Couplingは通常cohesionと対比されます。低いカップリングはしばしば高い凝集力と相関し、そしてその逆もあります。低カップリングは、よく構造化されたコンピュータシステムと優れた設計の兆候であることが多く、高い凝集性と組み合わせると、高い読みやすさと保守性の一般的な目標をサポートします。 ウィキ

2
Premraj

違いは次のように説明できると思います。

  • 結束度は、コードベースの一部が論理的に単一の原子単位を形成する程度を表します。
  • カップリングは、単一のユニットが他のユニットから独立している程度を表します。
  • 結束力を損なうことなく完全なデカップリングをアーカイブすることは不可能であり、その逆も同様です。

このブログ記事では 私はそれについてもっと詳しく書いています。

1
Vladimir

結合 =相互作用/ 2つのモジュール間の関係... 結合 =モジュール内の2つの要素間の相互作用.

ソフトウェアは多くのモジュールから構成されています。モジュールは要素で構成されています。モジュールがプログラムであると考えてください。プログラム内の機能は要素です。

実行時には、プログラムの出力は別のプログラムの入力として使用されます。これは、モジュール間の対話またはプロセス間の通信と呼ばれます。これはカップリングとも呼ばれます。

単一プログラム内では、関数の出力は別の関数に渡されます。これはモジュール内の要素の相互作用と呼ばれます。これは凝集力とも呼ばれます。

例:

結合 = 2つの異なる家族の間のコミュニケーション... 結束 =家族の中の父 - 母 - 子供の間のコミュニケーション.

1
Dipankar Nalui

Cohesion はモジュールの相対的な機能強度を示します。

  • 結合モジュールは単一のタスクを実行し、プログラムの他の部分の他のコンポーネントとの対話はほとんど必要ありません。簡単に言うと、結合モジュールは(理想的には)ただ1つのことをするべきです。
  • 従来の考え方

    モジュールの「ひたむきさ」

  • OOビュー:

    Cohesionは、コンポーネントまたはクラスが、互いに密接に関連している属性と操作、およびクラスまたはコンポーネント自体にのみ関連している属性と操作のみをカプセル化することを意味します

  • 結束度

    機能的

    レイヤー

    コミュニケーション

    シーケンス

    手続き

    一時的

    有用性

カップリング はモジュール間の相対的な相互依存関係を示します。

  • カップリングは、モジュール間のインターフェースの複雑さ、モジュールへの入力または参照が行われる時点、およびインターフェースを通過するデータの種類によって異なります。

  • 従来の見方:コンポーネントが他のコンポーネントや外部の世界とどの程度つながっているか

  • オブジェクト指向:クラスが互いにどの程度関連しているかの定性的尺度

  • 結合レベル

    コンテンツ

    共通

    管理

    スタンプ

    データ

    定期通話

    タイプ使用

    包含または輸入

    外部番号

1
zee

cohesionという用語は、実際、ソフトウェア設計での意味を理解するための直感に反する小さなカウンターです。

凝集の一般的な意味は、うまくくっつくものが団結することであり、分子引力のような強い結合によって特徴付けられます。ただし、ソフトウェア設計では、理想的には1つのことだけを行うクラスを目指して努力することを意味するため、複数のサブモジュールは関係しません。

おそらくこのように考えることができます。パーツは、それが唯一のパーツである場合に最も凝集力があります(1つのことのみを行い、さらに分解することはできません)。これがソフトウェア設計で望まれていることです。結束は、単に「単一責任」または「懸念の分離」の別名です。

一方で、用語coupleは非常に直感的です。つまり、モジュールが他の多くのモジュールに依存していない場合、接続するモジュールは簡単になります。 liskov置換原理 に従うために置き換えられました。

0
zar

簡単に言うと、 cohesion はクラスが単一の概念を表すべきであることを意味します。

クラスのすべての機能がそのクラスが表す概念に関連している場合、クラスのパブリックインタフェースはまとまりがあります。たとえば、CashRegisterクラスとCoinクラスを使用する代わりに、CashRegisterクラスとCoinクラスの2つのクラスにまとめます。

coupling では、クラスのオブジェクトを使うので、あるクラスは別のクラスに依存します。

高カップリングの問題点は、副作用が発生する可能性があることです。あるクラスを1回変更すると、他のクラスで予期しないエラーが発生し、コード全体が破損する可能性があります。

一般的に、高い凝集力と低いカップリングは、高品質のOOPと見なされます。

0
Varun Joshi