高凝集度とは何ですか?それをどのように使用/作成しますか?


84

私はコンピュータープログラミングを学んでいて、いくつかの場所で凝集度の概念に出くわしました。ソフトウェアが「高い凝集度」を持つことが望ましいことを理解していますが、それはどういう意味ですか?私はJava、C、Pythonのプログラマーであり、索引に含まれていなくても凝集性について言及している本C ++ PrimerからC ++を学習していますが、このトピックに関するリンクをいくつか教えていただけますか?コンピューターサイエンスの結束についてのウィキペディアのページは、定性的な尺度であり、実際のコード例が示されていないため、有益ではありませんでした。



3
高い凝集度:一緒に座る関連する行動、および他の場所に座る無関係な行動。
テオマンシパヒ2015

回答:


240

高い凝集度とは、明確に定義された仕事をするクラスがある場合です。凝集度が低いとは、クラスが多くの共通点のない仕事をする場合です。

この例を見てみましょう:

2つの数値を加算するクラスがありますが、同じクラスが結果を表示するウィンドウを作成します。ウィンドウと追加操作にはあまり共通点がないため、これはまとまりの少ないクラスです。ウィンドウはプログラムの視覚的な部分であり、追加機能はその背後にあるロジックです。

凝集性の高いソリューションを作成するには、クラスWindowとクラスSumを作成する必要があります。ウィンドウはSumのメソッドを呼び出して結果を取得し、表示します。このようにして、アプリケーションのロジックとGUIを別々に開発します。


14
正直なところ、私はそのような結束を定義していません。あなたの定義はSRP(単一責任の原則)です。そして、結束は、パッケージに関して、同じ機能を周回するクラスが互いに近いかどうかについてです。
v.oddou 2015年

4
SRP(Single Responsiblity Principle)は、同じ概念を表現するもう1つの方法です。結束は、よりメトリックです。SRPは実用的なガイドラインであり、従うとまとまりのあるクラスになります。
comDubh 2016年

3
クラスウィンドウは、クラス合計や他のクラスの「存在」を知る必要がないようにすることを唯一の目的としているため、クラス合計のオブジェクトを呼び出すべきではないと思います。合計クラスであり、結果をクラスWindowに
渡し

1
わかりません。ボブおじさんからのクリーンなコードによると、これはまとまりではありません。これはSRPです
karlihnos 2017年

とてもきちんとした説明!ありがとう
VincentLlauderes19年

55

スティーブマコネルのコードコンプリートからの説明:

凝集度とは、クラス内のすべてのルーチンまたはルーチン内のすべてのコードが中心的な目的をどれだけ厳密にサポートするかを指します。強く関連する機能を含むクラスは、 強い凝集度を持っていると説明され、ヒューリスティックな目標は、凝集度をできるだけ強くすることです。クラス内のコードが中心的な目的をサポートするほど、脳はコードのすべてのことを覚えやすくなるため、凝集度は複雑さを管理するための便利なツールです。

ボブおじさんのクリーンコードからそれを達成するいくつかの方法:

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

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

結束の概念は、結合の概念と強く関連しています。また、単一責任原則(SOLIDのS)と呼ばれる、高凝集度のヒューリスティックに基づく原則があります。


1
あなたの答えは、SRPと結束の両方を説明しているため、受け入れられているものよりも完全であると思います。したがって、これら2つの概念の特異性と違いを理解するのに役立ちます。
一度-LER

18

高い凝集度は、ソフトウェアエンジニアリングの概念です。基本的に、それはクラスがそれがすることになっていることだけをするべきであると言い、そしてそれを完全に行います。想定されていない関数でオーバーロードしないでください。また、それに直接関連するものは、他のクラスのコードにも表示されないようにする必要があります。

スケールも考慮する必要があるため、例は非常に主観的です。単純なプログラムは、モジュール化されすぎないようにする必要があります。そうしないと、断片化されます。一方、複雑なプログラムでは、複雑さを処理するために、より多くのレベルの抽象化が必要になる場合があります。

例:Eメールクラス。cc、bcc、subject、bodyへのデータメンバーが含まれている必要があり、これらのメソッドsaveAsDraft()、send()、discardDraft()が含まれている場合があります。ただし、login()はここにあるべきではありません。これは、電子メールプロトコルが多数あるため、個別に実装する必要があるためです。


それはSRPの定義です:「クラスはそれがすることになっていることだけをするべきであり、それを完全に行う」。
AliN 1119年

11

凝集度は通常、LCOM(Lack of cohesion)メトリックの1つを使用して測定されます。元のLCOMメトリックは、ChidamberとKemererから取得されました。例を参照してください:http//www.computing.dcu.ie/~renaat/ca421/LCOM.html

より具体的な例:クラスに、たとえば1つのプライベートフィールドと3つのメソッドがある場合。3つのメソッドすべてがこのフィールドを使用して操作を実行する場合、クラスは非常にまとまりがあります。

凝集クラスの擬似コード:

class FooBar {
  private SomeObject _bla = new SomeObject();

  public void FirstMethod() {
    _bla.FirstCall();
  }

  public void SecondMethod() {
    _bla.SecondCall();
  }

  public void ThirdMethod() {
    _bla.ThirdCall();
  }
}

たとえば、クラスに3つのプライベートフィールドと3つのメソッドがある場合。3つのメソッドすべてが3つのフィールドの1つだけを使用する場合、クラスのまとまりは不十分です。

凝集性の低いクラスの擬似コード:

class FooBar {
  private SomeObject _bla = new SomeObject();
  private SomeObject _foo = new SomeObject();
  private SomeObject _bar = new SomeObject();

  public void FirstMethod() {
    _bla.Call();
  }

  public void SecondMethod() {
    _foo.Call();
  }

  public void ThirdMethod() {
    _bar.Call();
  }
}

1つの原則を実行するクラスは、Robert C. Martinに由来し、SOLID原則の1つである単一責任原則です。原則として、クラスを変更する理由は1つだけである必要があります。

単一責任の原則に近いままでいると、コードがよりまとまりのあるものになる可能性がありますが、私の意見では、これらは2つの異なるものです。


4

これは、凝集度が低い例です。

class Calculator
{


     public static void main(String args[])
     {

          //calculating sum here
          result = a + b;
          //calculating difference here
          result = a - b;
          //same for multiplication and division
     }
}

しかし、高い凝集度は、クラス内の関数が(名前が付けられているように)本来の機能を実行することを意味します。そして、他の機能の仕事をしている機能はありません。したがって、以下は高凝集度の例です。

class Calculator
{


     public static void main(String args[])
     {

          Calculator myObj = new Calculator();
          System.out.println(myObj.SumOfTwoNumbers(5,7));
      }


     public int SumOfTwoNumbers(int a, int b)
     {

          return (a+b);
     }

     //similarly for other operations

}

3

凝集の原理を考える一般的な方法は、コードを、それに依存する、または依存する他のコードと一緒に見つける必要があるということです。凝集度は、クラスレベルより上の構成レベルに適用できます。たとえば、パッケージまたは名前空間には、理想的には、いくつかの一般的なテーマに関連し、他のパッケージ/名前空間に依存するよりも相互依存性が高いクラスが含まれている必要があります。つまり、依存関係をローカルに保ちます。


1

凝集性とは、クラスまたはメソッドが1つの定義されたジョブのみを実行することを意味します。メソッドまたはクラスの名前も自明である必要があります。たとえば、電卓を作成する場合は、クラスに「asdfghj」ではなく「calculator」という名前を付ける必要があります。また、タスクごとにメソッドを作成することを検討する必要があります。たとえば、subtract()add()などです。将来プログラムを使用する可能性のあるプログラマーは、メソッドが何をしているかを正確に知っています。良い命名はコメントの努力を減らすことができます

また、原則はドライです-自分自身を繰り返さないでください


1

凝集という用語は、元々、モジュールのソースコードが互いにどの程度関連しているかを定性的に測定するものとして、ソースコードのモジュールを説明するために使用されていました。結束の考え方は、さまざまな分野で使用されています。たとえば、軍事ユニットなどの人々のグループはまとまりがある場合があります。つまり、ユニット内の人々は共通の目標に向かって協力します。

ソースコードのまとまりの本質は、モジュール内のソースコードが、明確に定義された共通の目標に向かって連携することです。モジュール出力を作成するために必要な最小限のソースコードはモジュール内にあり、それ以上はありません。インターフェイスは明確に定義されており、入力はインターフェイスを介して流入し、出力はインターフェイスを介して流出します。副作用はなく、ミニマリズムに重点が置かれています。

機能的にまとまりのあるモジュールの利点は、単体テストの開発と自動化が簡単なことです。実際、モジュールのまとまりの良い尺度は、モジュールの完全な単体テストのフルセットを作成することがいかに簡単かということです。

モジュールは、オブジェクト指向言語のクラス、関数型言語、またはCなどの非オブジェクト指向言語の関数です。凝集性の測定に関するこの分野の元の作業の多くは、IBMのCOBOLプログラムでの作業に主に関係していました。 1970年代なので、まとまりはオブジェクト指向の概念だけではありません。

凝集の概念および関連する結合の概念が由来する研究の本来の目的は、理解、維持、および拡張が容易なプログラムの特性がどこにあるかを研究することでした。目標は、プログラミングのベストプラクティスを学び、それらのベストプラクティスを体系化してから、他のプログラマーにそのプラクティスを教えることができるようにすることでした。

優れたプログラマーの目標は、環境と解決されている問題を考慮して、可能な限り凝集性の高いソースコードを作成することです。これは、大規模なアプリケーションでは、ソースコード本体の一部が、そのモジュールまたはクラス内のソースコードのまとまりのレベルに関して他の部分とは異なることを意味します。あなたが得ることができる最高のものについては、あなたが解決しようとしている問題のために、時間的または連続的な結束である場合があります。

最高レベルの凝集度は機能的凝集度です。関数の凝集度を持つモジュールは、入力のセットを提供し、特定の出力を取得するという点で数学関数に似ています。真に機能するモジュールは、出力に加えて副作用がなく、いかなる種類の状態も維持しません。代わりに、モジュールの内部を公開せずにモジュールの機能をカプセル化する明確に定義されたインターフェイスがあり、モジュールを使用する人は特定の入力セットを提供し、代わりに特定の出力を取得します。真に機能するモジュールは、スレッドセーフでもある必要があります。

多くのプログラミング言語ライブラリには、クラス、テンプレート、関数など、機能モジュールの例がいくつか含まれています。最も機能的なまとまりのある例は、sin、余弦、平方根などの数学関数です。

他の機能は、副作用があるか、ある種の状態を維持するため、それらの機能の使用がより複雑になる可能性があります。

たとえば、例外をスローしたり、グローバルエラー変数を設定したり(errnoCで)、シーケンスで使用する必要があるstrtok()関数(関数は、内部状態を維持するため、標準Cライブラリの例です)またはポインタを提供します。管理されるか、ログをログユーティリティに発行することはすべて、機能のまとまりがなくなった機能の例です。

YourdonとConstantineの元の本であるStructuredProgrammingの両方を読んだことがあります。ここでは、1980年代に最初に凝集のアイデアに出会い、MeilirPage-Jonesの本PracticalGuide to Structured Systems Designを読みました。そして、Page-Jonesははるかに優れた説明を行いました。結合と凝集の両方。ヨードンとコンスタンティンの本はもう少し学術的なようです。SteveMcConnellの本CodeCompleteは非常に優れており、実用的であり、改訂版には優れたプログラミング手法について多くのことが書かれています。


The minimum amount of source code needed to create the module outputs is in the module and no moreこれは結束に関係しているのではなく、DTSTTCPWに
v.oddou

@ v.oddou、コードの最小量は確かに凝集力に関連しています。モジュールの出力に関係のないモジュール内のコードが多いほど、コードに副作用がある可能性が高くなるため、凝集度が低くなります。すべての概念には異なる視点があり、特に結束などの概念はやや曖昧です。凝集力の測定は定性的であり、ある種のルーブリックを使用して特定のモジュールをあるカテゴリまたは別のカテゴリに割り当てるための一種のファジーロジックが必要です。出力の最小コードを言うことは、いくつかのうちの1つだけの高凝集度の十分な特性ではありません。
リチャードチェンバーズ

1

答えのほとんどは、結束とは何かを説明していません。それは、叔父のボブの本のきれいなコードで明確に定義されています。

クラスには少数のインスタンス変数が必要です。クラスの各メソッドは、これらの変数の1つ以上を操作する必要があります。一般に、メソッドが操作する変数が多いほど、そのメソッドはそのクラスに対してよりまとまりがあります。各変数が各メソッドで使用されるクラスは、最大限にまとまりがあります。一般に、このような最大限にまとまりのあるクラスを作成することはお勧めできません。一方で、結束力を高めたい。凝集性が高い場合は、クラスのメソッドと変数が相互に依存しており、論理的な全体として一緒にハングしていることを意味します。

クラス定義で説明させてください

class FooBar {
private _bla;
private _foo;
private _bar;

function doStuff()

   if(this._bla>10){
     this._foo = 10;
     this._bar = 20;
   }

}
function doOtherStuff(){

    if(this._foo==10){
       this._bar = 100;
       this._bla = 200;
    }
}

}

上記の例を見ると、クラスはまとまりがあります。つまり、変数はクラス間で共有されて連携し、より多くの変数が共有されます。つまり、クラスは非常にまとまりがあり、単一のユニットとして機能します。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.