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


486

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

結合と凝集は、ソフトウェア設計の良し悪しにどのようにつながりますか?

2つの違いの概要と、全体的なコード品質への影響を説明する例は何ですか?


2
それをチェックしてください
Inv3r53

3
この記事を指摘したいと思います:SOLIDソフトウェア開発、一度に1つのステップ。Grz、クリス。
クリスファンデルマスト

4
これはこの件に関する最新の投稿です
janisz

回答:


703

凝集度とは、クラス(またはモジュール)が実行できることを指します。凝集度が低いということは、クラスがさまざまな行動をとることを意味します-それは広範囲であり、何をすべきかに焦点を当てていません。凝集度が高いということは、クラスが何をすべきか、つまりクラスの意図に関連するメソッドのみに焦点を当てていることを意味します。

凝集度の低い例:

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

凝集度の高い例:

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

カップリングは、二つのクラス/モジュールが互いに向かってどのように関連または依存を指します。結合度の低いクラスの場合、1つのクラスでメジャーなものを変更しても、他のクラスには影響しません。結合度が高いと、コードの変更と保守が難しくなります。クラスは密接に結びついているため、変更を行うとシステム全体の修正が必要になる場合があります。

優れたソフトウェア設計は、高い凝集性低い結合を備えています。


12
いくつかのメソッドを削除する方法はわかりません。他のメソッドをいくつか追加すると、まとまりが増します。誰かがここで助けてくれますか?
Saket Jain

3
@SaketJainそれはいくつかのメソッドを削除して他のいくつかを追加するだけではありません。メソッドがクラスの目的にどのように関連付けられているかです(その説明がより明確である場合)。
mauris

4
上部の凝集度が低い例はかなりよく見えますが、「凝集度が高い」と誤って言ったと思います
2016年

37
@SaketJain Staffクラスは、メールのチェック、送信、検証を行う場所ではありません。これらの関数は架空のEmailクラス内に配置する必要があります。これが凝集度が低い理由です。2番目の例では、Staffクラスには、Staff関連データを設定および取得するための適切な情報のみが含まれています。他のクラスによって管理されるべきアクションを実行しません。
アントニオパンターノ2016年

3
@JonathanCの例は、(数学の証明のように)例であるために違いを証明する必要はありません。より役立つと思われる例については、お気軽に回答またはコメントしてください。setget機能は、「スタッフ」文脈に、より具体的な機能を説明する-より高い特異性を得られることたとえばその高い凝集を。
cellepo

81

凝集度は、モジュールの関係を示します。

結合は、モジュールの関係を示します。

ここに画像の説明を入力してください

凝集

  • 凝集度は、モジュール内の関係を示します。
  • 凝集度は、モジュールの相対的な機能強度を示します。
  • 凝集度は、コンポーネント/モジュールが単一のものに焦点を合わせる程度(品質)です。
  • 設計中は、システムの他のモジュールとほとんど相互作用せずに、単一のタスク(つまり、ひたむきな心)に重点を置いて、凝集度の高いコンポーネント、つまりモジュールに力を注ぐ必要があります。
  • 凝集度は、データ非表示の自然な拡張の一種です。たとえば、デフォルトの可視性を持つパッケージですべてのメンバーを可視にするクラスです。凝集性はイントラ–モジュールの概念です。

カップリング

  • カップリングは、モジュール間の関係を示します。
  • カップリングは、モジュール間の相対的な依存関係/相互依存関係を示します。
  • カップリングは、コンポーネント/モジュールが他のモジュールに接続される程度です。
  • 設計中は、カップリングを低く抑えるように努力する必要があります。つまり、モジュール間の依存関係を少なくする必要があります
  • プライベートフィールド、プライベートメソッド、非パブリッククラスを作成すると、疎結合になります。
  • 結合はモジュール間コンセプトです。

このリンクをチェック


77

モジュール内の高い凝集性とモジュール間の低い結合、オブジェクト指向プログラミング言語の高品質に関連すると見なされることがよくあります。

たとえば、各Javaクラス内のコードは高い内部凝集力を備えている必要がありますが、他のJavaクラスのコードと可能な限り疎結合でなければなりません。

の第3章 Meyerのオブジェクト指向ソフトウェア構築(第2版)のは、これらの問題の優れた説明です。


3
概念は実際にはオブジェクト指向プログラミングに限定されません。どちらかといえば、オブジェクト指向言語の目標は、プログラマーを高い結束性/低い結合の目的に向けて導くことであることをお勧めします。
ハッチ

57

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

カップリングとは、ソフトウェア要素が他の要素にどの程度強く接続されているかを指します。

ソフトウェア要素は、クラス、パッケージ、コンポーネント、サブシステム、またはシステムです。また、システムを設計する際には、凝集度高く低結合をサポートするソフトウェア要素を使用することをお勧めします。

凝集度が低いと、一体型のクラスになり、維持、理解、再利用が困難になります。同様に、高結合はクラスが密結合であり、変更は非ローカルではない傾向があり、変更が困難であり、再利用を減らします。

ConnectionPool次の要件を備えた典型的な監視可能なものを設計するという架空のシナリオを取ることができます。のような単純なクラスでは見た目が多すぎるかもしれませんConnectionPoolが、基本的な目的は、いくつかの単純な例で低カップリング高凝集性を示すことだけであり、役立つと思います。

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

低凝集我々は設計できConnectionPool強制的に以下のように、単一のクラスにすべての機能/責任を詰めることにより、クラスを。この単一のクラスが接続管理、データベースとの対話、接続統計の維持を担当していることがわかります。

凝集度の低い接続プール

高い凝集私たちは、クラス全体でこれらの責任を割り当て、それはより保守および再利用可能にすることができます。

高凝集度接続プール

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

低カップリング接続プール

注/単語または注意:この単純なシナリオではやり過ぎに見えるかもしれませんが、アプリケーションがトランザクションを完了するために複数のサードパーティサービスとやり取りする必要があるリアルタイムシナリオを想像する場合:コードをサードパーティサービスに直接結合するサードパーティのサービスに変更を加えると、複数の場所でコードが変更される可能性があります。代わりにFacade、これらの複数のサービスと内部的にやり取りし、サービスへの変更がにローカルになりFacade、サードパーティとの結合を弱めることができます。サービス。


3
正解です。可能であれば、他の例を使用できますか?接続プーリングは、誰にとっても明らかではない場合があります。とにかく、それは本当に私を助けました。ほんとありがと!
Saket Jain

ConnectionListenerインターフェイスを使用すると、カップリングを減らすのにどのように役立ちますか?理解しやすい例を提供できますか?
abhishek gupta

1
@abhishekguptaこの例では、オブザーバーパターンを使用して低/疎結合を実現していることに気付いたかもしれません。これを行うことは、オブザーバーが疎結合設計
Madhusudana Reddy Sunnapu 2016年

33

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

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.
    }
}

28

凝集度の最も良い説明はボブおじさんのクリーンコードから来ています:

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

一般に、このような最大限にまとまりのあるクラスを作成することはお勧めできません。一方、凝集力を高くしてほしい。凝集度が高い場合、それはクラスのメソッドと変数が相互依存しており、論理的に全体としてつながっていることを意味します。

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


これがおそらく最良の説明であることに同意します。これはボブおじさんが好きなことです。彼はいくつかのフレーズで実際の意味を説明できます。この定義を知っていると、その凝集度を高めるために与えられたクラスに対して何をすべきかを即座に見ることができます。
Pawel Dubiel

13

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

本質的に、凝集度が高いということは、相互に関連するコードベースの部分を1つの場所に保持することを意味します。同時に、低結合とは、コードベースの無関係な部分を可能な限り分離することです。

結束および結合の観点からのコードのタイプ:

理想は、ガイドラインに従うコードです。疎結合であり、非常にまとまりがあります。このようなコードを次の図で説明できます。ここに画像の説明を入力してください

神オブジェクトは、高い凝集性と高い結合を導入した結果です。これはアンチパターンであり、基本的にはすべての作業を一度に実行する単一のコードを表しています。 不適切な選択は、異なるクラスまたはモジュール間の境界が適切に選択されていない場合に発生しますここに画像の説明を入力してください ここに画像の説明を入力してください

破壊的なデカップリングは最も興味深いものです。プログラマーがコードベースを分離しようとすると、コードが完全にフォーカスを失ったときに発生することがあります。ここに画像の説明を入力してください

詳細はこちら


1
優秀な記事とイラスト!私が1つの考えの改善を提案するかもしれない場合、「不十分な選択」が無関係なセマンティクスを持つコンポーネントのグループを小さな群れにどのように保持するかが好きですが、それらの間には目に見えるより多くの矢印があるはずだと思います。結局のところ、4乗グラフでも、これは「カップリング」軸の上位範囲に該当するグラフです。
Slawomir Brzezinski

1
また、「選択が不十分」の場合、各群れ内の矢印は少なくなるはずです。記事の「フォルダ構造」の例を使用すると、「選択が不十分」なリポジトリまたはファクトリとして分類されるため、確実に互いに通信しません。
Slawomir Brzezinski

更新:私はこれらの提案を画像の元の作者に提示し、作者はそれらに同意しました
Slawomir Brzezinski

11

ソフトウェア工学における結束は、特定のモジュールの要素が一緒に属する程度です。したがって、これは、ソフトウェアモジュールのソースコードによって表される各機能がどれだけ強く関連しているかの尺度です。

カップリング簡単な言葉で、どのくらいの1コンポーネントは(再び、必ずしもクラスを想像して、ではないが)、それは他のコンポーネントの持っているつまり、どのくらいの知識、内部の仕組みや、他の1の内側の要素を知っているされています。

例や図面を使ってもう少し詳しく知りたい場合は、これについてブログ投稿しました。それはあなたの質問のほとんどに答えると思います。


4

ここに画像の説明を入力してください

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

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


2

結束(結束):共同手段一緒にhesion手段は固執します。異なる物質の粒子をくっつけるシステム。

実際の例:img礼儀
ここに画像の説明を入力してください

全体は部分の合計よりも大きい-アリストテレス。

  • 凝集力は通常のタイプの測定であり、通常「高い凝集力」または「低い凝集力」と表現されます。高い凝集力は、堅牢性、信頼性、再利用性、理解しやすさなど、ソフトウェアのいくつかの望ましい特性に関連付けられているため、凝集力の高いモジュールが望ましい傾向があります。対照的に、凝集度が低いと、維持、テスト、再利用、理解さえ困難になるなどの望ましくない特性が伴います。wiki

  • カップリングは、通常と対比される結束。低い結合はしばしば高い凝集力と相互に関連し、逆もまた同様です。多くの場合、低結合は、適切に構造化されたコンピューターシステムと優れた設計の兆候であり、高い凝集性と組み合わせると、高い可読性と保守性の一般的な目標をサポートします。wiki


1

違いは次のように考えることができます:

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

このブログ投稿では、それについて詳しく説明します。


1

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

  • 凝集モジュールは単一のタスクを実行し、プログラムの他の部分の他のコンポーネントとの相互作用をほとんど必要としません。簡単に言うと、まとまりのあるモジュールは(理想的には)1つのことだけを実行する必要があります。
  • 従来のビュー:

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

  • OOビュー:

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

  • co凝集力のレベル

    機能的

    レイヤー

    コミュニケーション

    順次

    手続き

    時間的

    ユーティリティ

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

  • 結合は、モジュール間のインターフェースの複雑さ、モジュールへのエントリまたは参照が行われるポイント、およびインターフェースを介して渡されるデータに依存します。

  • 従来のビュー:コンポーネントが他のコンポーネントおよび外部世界に接続されている度合い

  • オブジェクト指向ビュー:クラスが相互に接続されている度合いの定性的尺度

  • カップリングのレベル

    内容

    共通

    制御

    スタンプ

    データ

    ルーチンコール

    タイプの使用

    包含またはインポート

    外部#


1

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

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

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

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

例:

カップリング = 2つの異なる家族間のコミュニケーション... 結束 = 家族 内の父母母子間のコミュニケーション。


1
それでは、ソフトウェアへの影響のコンテキストでそれらを
Itban Saeed '19

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

1

簡単に言えば、まとまりとは、クラスが単一の概念を表す必要があることを意味します。

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

カップリングそれはクラスのオブジェクトを使用するように、一つのクラスは、他に依存します。

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

一般に、高い凝集性と低い結合は、高品質のOOPと見なされます。


0

結束という用語は、ソフトウェア設計における意味が実際に少し直観に反するものです。

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

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

一方でカップリングという用語は非常に直感的です。つまり、モジュールが他の多くのモジュールに依存しておらず、接続するモジュールは、たとえばliskov置換の原則に従って簡単に置き換えることができます。


なぜ人々はクラスの代わりにモジュールという言葉を使い続けるのですか?
ノーザン

1
@northernerそのより一般的な用語。
zar

0

理論の違い

凝集

  • 凝集力は、モジュールの相対的な機能強度を示します。
  • 凝集モジュールは単一のタスクを実行し、プログラムの他の部分の他のコンポーネントとの相互作用をほとんど必要としません。
  • 高い凝集力と低い結合力を持つモジュールは、他のモジュールから機能的に独立していると言われています。

凝集力の分類

1.偶然2.論理的3.時間的4.手続き的5.コミュニケーション6.順次7.機能的

カップリング

  • 結合は、モジュール間の相対的な相互依存性を示します。
  • 2つのモジュール間の結合度は、インターフェースの複雑さに依存します。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.