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