web-dev-qa-db-ja.com

高粘着性とは何ですか?それを使用/作成する方法は?

私はコンピュータープログラミングを学んでおり、いくつかの場所で結束の概念に出くわしました。ソフトウェアが「高い結束力」を持つことが望ましいことを理解していますが、それはどういう意味ですか。私はJavaで、C = Python C++ PrimerからC++を学ぶプログラマーは、インデックスに含まれていない凝集性について言及しています。それは定性的な尺度であり、実際のコード例を示していないだけだからです。

75

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

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

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

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

221
Andrei M

Steve McConnellのCode Completeからの説明:

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

ボブおじさんのClean Codeからそれを達成する何らかの方法:

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

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

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

41
m3th0dman

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

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

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

17
nhahtdh

凝集度は通常、LCOM(凝集度不足)メトリックの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つの原則を実行するクラスは、 Single Responsibility Principle です。これは、Robert C. Martinによるもので、 [〜#〜] solid [〜#〜] 原則の1つです。原則は、クラスには変更する理由が1つだけであることを規定しています。

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

10
RBaarda

これは低凝集の例です:

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

}
4
Kazekage Gaara

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

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

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

機能的に結合したモジュールの利点は、単体テストの開発と自動化が簡単であることです。実際、モジュールの凝集度の適切な尺度は、モジュールの完全な単体テストのセットを簡単に作成できることです。

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

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

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

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

多くのプログラミング言語ライブラリには、クラス、テンプレート、関数などの機能モジュールの例が多数含まれています。最も機能的な凝集の例は、sin、cos、square rootなどの数学関数です。

他の関数には、副作用があったり、何らかの状態が維持されたりして、それらの関数の使用がより複雑になる場合があります。

たとえば、例外をスローする関数、グローバルエラー変数を設定する関数(Cではerrno)、またはシーケンスで使用する必要がある関数(strtok()関数は、標準Cライブラリの例です)内部状態を維持する)または管理する必要のあるポインターを提供するか、何らかのログユーティリティにログを発行するものはすべて、もはや機能的結合ではない関数の例です。

YourdonとConstantineのオリジナルの本、Structured Programmingの両方を読んだことがあります。1980年代に結束のアイデアに出会ったのはMeilir Page-JonesのPractical Guide to Structured Systems Designです。結合と凝集の両方。 Yourdon and Constantineの本はもう少しアカデミックなようです。 Steve McConnellの著書 『Code Complete』は非常に実用的であり、改訂版には優れたプログラミングの実践について多くのことが書かれています。

1

凝集とは、クラスまたはメソッドが定義済みのジョブを1つだけ実行することを意味します。メソッドまたはクラスの名前も一目瞭然です。たとえば、電卓を作成する場合は、クラスに「asdfghj」ではなく「calculator」という名前を付ける必要があります。また、各タスクのメソッドを作成することを検討する必要があります。減算()add()など...将来プログラムを使用する可能性のあるプログラマーは、メソッドが何をしているかを正確に知っています。適切なネーミングにより、コメントの労力を減らすことができます

また、原則はDRY-繰り返さないでください

1
tagtraeumer

MSDN's この記事は、おそらくこの場合のウィキペディアよりも有益です。

0
Jeff Watkins