凝集と結合の違いは何ですか?
カップリングと結束はどのようにして良いまたは悪いソフトウェア設計につながるのでしょうか。
両者の違いと、それがコード全体の品質に与える影響を概説する例は何ですか?
Cohesion はクラス(またはモジュール)ができることを表します。結束力が低いということは、そのクラスが多種多様な行動をとることを意味します。凝集性が高いということは、そのクラスがやるべきこと、すなわちクラスの意図に関連する方法だけに焦点を当てているということです。
低凝集の例:
-------------------
| Staff |
-------------------
| checkEmail() |
| sendEmail() |
| emailValidate() |
| PrintLetter() |
-------------------
高凝集の例
----------------------------
| Staff |
----------------------------
| -salary |
| -emailAddr |
----------------------------
| setSalary(newSalary) |
| getSalary() |
| setEmailAddr(newEmail) |
| getEmailAddr() |
----------------------------
カップリング に関しては、2つのクラス/モジュールが互いに関連しているか依存しているかを示します。結合度の低いクラスでは、あるクラスで大きな変更を行っても他のクラスには影響しません。カップリングが大きいと、コードを変更したり保守したりするのが難しくなります。クラスは密接に結び付いているため、変更を加えるにはシステム全体の見直しが必要になる可能性があります。
良いソフトウェア設計は 高い凝集力 そして 低い結合力 を持ちます。
高結束 内 モジュールおよび低結合 間 モジュールは、OOプログラミング言語では高品質に関連すると見なされることがよくあります。
たとえば、各Javaクラス内のコードは高い内部結合性を持つ必要がありますが、他のJavaクラス内のコードとできるだけ疎結合にする必要があります。
第3章/ - Meyerのオブジェクト指向ソフトウェア構築(第2版) は、これらの問題についての素晴らしい説明です。
Cohesionはモジュールの関係内を示します。
Couplingは、関係{betweenモジュールの指標です。
結束
カップリング
チェック これ リンク
Cohesion は、ソフトウェア要素の責任がどの程度関連しており、その責任が集中しているかを示しています。
結合 は、ソフトウェア要素が他の要素にどれだけ強く接続されているかを示します。
ソフトウェア要素は、クラス、パッケージ、コンポーネント、サブシステムまたはシステムです。そしてシステムを設計する間、 高い凝集力 を持ち、 低い結合 を持つソフトウェア要素を持つことが推奨されます。
低凝集性 の結果、モノリシッククラスが維持、理解、および再利用が困難になります。同様に、 高い結合 は密接に結合されたクラスになり、変更は局所的ではなく、変更が困難で再利用が減少します。
次の要件を満たす典型的な監視可能なConnectionPool
を設計しているという仮定のシナリオを取ります。 ConnectionPool
のような単純なクラスを探しすぎるかもしれませんが、基本的な目的は単純な例を使って low coupling と high cohesion を実証することです。
low cohesion を使うと、以下のようにこれらすべての機能/責任を1つのクラスに強制的に詰め込むことによってConnectionPool
クラスを設計できます。この単一クラスが接続管理、データベースとの対話、接続統計の管理を担当していることがわかります。
高い凝集力 を使うと、クラス間でこれらの責任を割り当て、それをより保守可能で再利用可能にすることができます。
低結合 を実証するために、上の高凝集度ConnectionPool
図を続けます。上の図を見てみると、高い凝集力をサポートしていますが、ConnectionPool
はConnectionStatistics
クラスおよびPersistentStore
と密接に結び付いており、ConnectionListener
と直接相互作用します。結合を減らすために、ConnectionPool
インターフェースを導入し、これら2つのクラスにインターフェースを実装させ、それらをConnectionPool
クラスに登録させることができます。そしてFacade
はこれらのリスナーを繰り返し処理して接続の取得と解放のイベントを通知し、結合を減らすことができます。
注/ 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.
}
}
Cohesionの最も良い説明は、Uncle BobのClean Codeから来ています。
クラスは少数のインスタンス変数を持つべきです。クラスの各メソッドは、これらの変数の1つ以上を操作する必要があります。 一般に、メソッドが操作する変数が多いほど、そのメソッドはそのクラスに対してよりまとまりのあるものになります。各メソッドで各変数が使用されるクラスは、最大限凝集的です。
一般的に、このような最大凝集力のあるクラスを作成するのは賢明でも不可能でもありません。一方、結合力が高いことを望みます _。結束力が高い場合は、クラスのメソッドと変数が相互に依存し、論理的にまとまっていることを意味します。
関数を小さくし、パラメータリストを短くするという戦略は、メソッドのサブセットで使用されるインスタンス変数の急増につながることがあります。これが起こるとき、それはより常に大規模なクラスから抜け出そうとしている他のクラスが少なくとも1つあることを意味します。新しいクラスがよりまとまりのあるものになるように、変数とメソッドを2つ以上のクラスに分割するようにしてください。
ソフトウェア工学における Cohesion は、あるモジュールの要素がどの程度一緒に属しているかを表します。したがって、それはソフトウェアモジュールのソースコードによって表現された各機能性がどれほど強く関連しているかの尺度である。
カップリング 簡単に言うと、1つのコンポーネントが別のコンポーネントの内部の動作や内部の要素について知っている量(つまり、クラスを想像する必要はありません)です。
私はこれについてブログ記事を書いた 、あなたが例と図面でもう少し詳細を読みたいならば。私はそれがあなたの質問の大部分に答えていると思います。
単純に、 Cohesion は、コードベースの一部が論理的に単一の原子単位を形成する度合いを表します。一方、 カップリング は、単一のユニットが他のユニットから独立している程度を表します。つまり、2つ以上のユニット間の接続数です。数が少ないほど、カップリングは低くなります。
本質的に、結束性が高いということは、互いに関連するコードベースの一部を1か所にまとめることを意味します。同時に、低カップリングとは、コードベースの無関係な部分をできるだけ分離することです。
結合と結合の観点から見たコードの種類
理想 は、ガイドラインに従うコードです。それは疎結合で非常に凝集性があります。私たちはこの絵でそのようなコードを説明することができます:
ゴッドオブジェクト は、高い凝集力と高いカップリングをもたらした結果です。それはアンチパターンであり、基本的に一度にすべての作業を行う単一のコードを表します: 不適切に選択された 異なるクラスまたはモジュール間の境界が不適切に選択された場合に発生する
破壊的デカップリング が最も興味深いものです。プログラマーがコードベースを切り離そうとしてコードが完全にフォーカスを失うことを試みるとき、それは時々起こります:
続きを読む ここ
結束とは、単一クラスの設計方法のすべてを指します。結束は、クラスが単一の、焦点を絞った目的で設計されていることを確認することと最も密接に関連しているオブジェクト指向の原則です。クラスの焦点が合っているほど、そのクラスのまとまりが強くなります。凝集度が高いことの利点は、凝集度が低いクラスよりも、そのようなクラスの方がはるかに保守が容易である(そして変更頻度が少ない)ことです。結束度が高いことのもう1つの利点は、目的が明確に定められているクラスが他のクラスよりも再利用可能になる傾向があることです。
上の画像では、低結束では1つのクラスだけが共通ではない多くのジョブの実行を担当しているため、再利用性とメンテナンスの可能性が低くなります。しかし、結束度が高い場合は、すべてのジョブが特定のジョブを実行するための個別のクラスが存在するため、使いやすさと保守性が向上します。
Cohesion(Co-hesion):Coはtogetherを意味し、hesionはstickingを意味します。異なる物質の粒子をくっつけるシステム。
実際の例では、
img礼儀
全体は部品の合計よりも大きい - Aristotle。
Cohesionは通常の測定タイプで、通常は「高凝集」または「低凝集」と呼ばれます。高い凝集性は、堅牢性、信頼性、再利用性、および理解可能性を含むソフトウェアのいくつかの望ましい特性に関連しているため、高い凝集性を持つモジュールが好ましい傾向があります。対照的に、低い凝集性は、維持すること、テストすること、再利用すること、または理解することさえ困難であるなどの望ましくない特徴と関連している。 ウィキ
Couplingは通常cohesionと対比されます。低いカップリングはしばしば高い凝集力と相関し、そしてその逆もあります。低カップリングは、よく構造化されたコンピュータシステムと優れた設計の兆候であることが多く、高い凝集性と組み合わせると、高い読みやすさと保守性の一般的な目標をサポートします。 ウィキ
違いは次のように説明できると思います。
このブログ記事では 私はそれについてもっと詳しく書いています。
結合 =相互作用/ 2つのモジュール間の関係... 結合 =モジュール内の2つの要素間の相互作用.
ソフトウェアは多くのモジュールから構成されています。モジュールは要素で構成されています。モジュールがプログラムであると考えてください。プログラム内の機能は要素です。
実行時には、プログラムの出力は別のプログラムの入力として使用されます。これは、モジュール間の対話またはプロセス間の通信と呼ばれます。これはカップリングとも呼ばれます。
単一プログラム内では、関数の出力は別の関数に渡されます。これはモジュール内の要素の相互作用と呼ばれます。これは凝集力とも呼ばれます。
例:
結合 = 2つの異なる家族の間のコミュニケーション... 結束 =家族の中の父 - 母 - 子供の間のコミュニケーション.
Cohesion はモジュールの相対的な機能強度を示します。
従来の考え方
モジュールの「ひたむきさ」
OOビュー:
Cohesionは、コンポーネントまたはクラスが、互いに密接に関連している属性と操作、およびクラスまたはコンポーネント自体にのみ関連している属性と操作のみをカプセル化することを意味します
結束度
機能的
レイヤー
コミュニケーション
シーケンス
手続き
一時的
有用性
カップリング はモジュール間の相対的な相互依存関係を示します。
カップリングは、モジュール間のインターフェースの複雑さ、モジュールへの入力または参照が行われる時点、およびインターフェースを通過するデータの種類によって異なります。
従来の見方:コンポーネントが他のコンポーネントや外部の世界とどの程度つながっているか
オブジェクト指向:クラスが互いにどの程度関連しているかの定性的尺度
結合レベル
コンテンツ
共通
管理
スタンプ
データ
定期通話
タイプ使用
包含または輸入
外部番号
cohesionという用語は、実際、ソフトウェア設計での意味を理解するための直感に反する小さなカウンターです。
凝集の一般的な意味は、うまくくっつくものが団結することであり、分子引力のような強い結合によって特徴付けられます。ただし、ソフトウェア設計では、理想的には1つのことだけを行うクラスを目指して努力することを意味するため、複数のサブモジュールは関係しません。
おそらくこのように考えることができます。パーツは、それが唯一のパーツである場合に最も凝集力があります(1つのことのみを行い、さらに分解することはできません)。これがソフトウェア設計で望まれていることです。結束は、単に「単一責任」または「懸念の分離」の別名です。
一方で、用語coupleは非常に直感的です。つまり、モジュールが他の多くのモジュールに依存していない場合、接続するモジュールは簡単になります。 liskov置換原理 に従うために置き換えられました。
簡単に言うと、 cohesion はクラスが単一の概念を表すべきであることを意味します。
クラスのすべての機能がそのクラスが表す概念に関連している場合、クラスのパブリックインタフェースはまとまりがあります。たとえば、CashRegisterクラスとCoinクラスを使用する代わりに、CashRegisterクラスとCoinクラスの2つのクラスにまとめます。
coupling では、クラスのオブジェクトを使うので、あるクラスは別のクラスに依存します。
高カップリングの問題点は、副作用が発生する可能性があることです。あるクラスを1回変更すると、他のクラスで予期しないエラーが発生し、コード全体が破損する可能性があります。
一般的に、高い凝集力と低いカップリングは、高品質のOOPと見なされます。