높은 응집력이란 무엇이며 어떻게 사용 / 만드는가?


84

저는 컴퓨터 프로그래밍을 배우고 있으며 여러 곳에서 응집의 개념을 우연히 발견했으며 소프트웨어가 "고 응집력"을 갖는 것이 바람직하다는 것을 이해합니다. 그러나 그것은 무엇을 의미합니까? 저는 색인에 포함되지 않고 응집력을 언급하는 책 C ++ 입문서에서 C ++를 배우는 Java, C 및 Python 프로그래머입니다.이 주제에 대한 링크를 알려 주시겠습니까? 컴퓨터 과학 응집력에 관한 위키피디아 페이지는 정보를 얻지 못했습니다. 단지 질적 측정이라고 말하고 실제 코드 예제를 제공하지 않기 때문입니다.



3
높은 응집력 : 함께 앉는 관련 행동, 다른 곳에 앉는 관련없는 행동.
Teoman shipahi

답변:


240

높은 응집력은 잘 정의 된 작업을 수행하는 클래스가있는 경우입니다. 낮은 응집력은 수업이 공통점이 많지 않은 많은 일을 할 때입니다.

이 예를 보겠습니다.

두 개의 숫자를 더하는 클래스가 있지만 동일한 클래스가 결과를 표시하는 창을 만듭니다. 이것은 창과 추가 작업이 공통점이 많지 않기 때문에 응집력이 낮은 클래스입니다. 창은 프로그램의 시각적 부분이고 추가 기능은 그 뒤에있는 논리입니다.

응집력이 높은 솔루션을 만들려면 Window 클래스와 Sum 클래스를 만들어야합니다. 창은 Sum의 메서드를 호출하여 결과를 가져와 표시합니다. 이렇게하면 애플리케이션의 로직과 GUI를 별도로 개발할 수 있습니다.


14
솔직히 저는 Cohesion을 그렇게 정의하지 않습니다. 귀하의 정의는 SRP (단일 책임 원칙)입니다. 그리고 응집력은 패키지 현명한 동일 기능 궤도 클래스가 서로 가까이 있는지 여부에 관한 것입니다.
v.oddou

4
SRP (Single Responsiblity Principle)는 동일한 개념을 표현하는 또 다른 방법입니다. 응집력은 더 많은 측정 기준입니다. SRP는 실용적 지침으로 준수하면 응집력있는 수업으로 이어질 것입니다.
ComDubh

3
클래스 창은 클래스 합계 또는 다른 클래스의 "존재"에 대해 알 필요가 없도록 렌더링하는 유일한 목적이므로 클래스 합계의 객체를 호출해서는 안된다고 생각합니다. 결과를 가져와야하는 Driver라고하는 다른 클래스가 있어야합니다. 합 클래스 및 렌더링하는 클래스 창에 결과를 전달할 것
Eklavyaa

1
이해가 안 돼요. 이것은 Bob 삼촌의 깨끗한 코드에 따르면 응집력이 아닙니다. 이것은 SRP입니다
karlihnos

매우 깔끔한 설명! 감사합니다
빈센트 Llauderes

55

Steve McConnell의 Code Complete 에서 설명 :

응집력은 클래스의 모든 루틴 또는 루틴의 모든 코드 가 중심 목적 을 얼마나 밀접하게 지원 하는지를 나타냅니다 . 밀접하게 관련된 기능 을 포함 하는 클래스는 강력한 응집력을 갖는 것으로 설명되며 휴리스틱 목표는 응집력을 가능한 한 강력하게 만드는 것입니다. 응집력은 복잡성을 관리하는 데 유용한 도구입니다. 클래스에 더 많은 코드가 중심 목적을 지원할수록 두뇌가 코드가 수행하는 모든 것을 더 쉽게 기억할 수 있기 때문입니다.

Uncle Bob의 Clean Code 에서이를 달성하는 방법 :

클래스에는 적은 수의 인스턴스 변수 가 있어야 합니다 . 클래스의 각 메서드는 이러한 변수 중 하나 이상을 조작해야합니다. 일반적으로 메서드가 더 많은 변수를 조작할수록 해당 메서드는 클래스에 대해 더 응집력이 있습니다. 각 메서드에서 각 변수를 사용하는 클래스는 최대한 응집력이 있습니다.

일반적으로 이러한 최대로 응집력있는 클래스를 만드는 것은 바람직하지도 가능하지도 않습니다. 반면에 우리는 응집력이 높기를 바랍니다. 응집력이 높으면 클래스의 메서드와 변수가 서로 의존적이며 논리적 전체로 함께 묶여 있음을 의미합니다.

응집의 개념은 결합의 개념과 밀접한 관련이 있습니다. 또한 Single Responsibility Principle (SOLID의 S)이라는 높은 응집성의 휴리스틱을 기반으로하는 원칙이 있습니다.


1
SRP와 응집력을 모두 설명하고 있으므로이 두 개념의 특이성과 차이점을 이해하는 데 도움이되기 때문에 귀하의 답변이 허용 된 답변보다 더 완전하다고 생각합니다.
The Once-ler

18

높은 응집력은 소프트웨어 엔지니어링 개념입니다. 기본적으로 클래스는해야 할 일만해야하며 완전히 수행해야한다고 말합니다. 하지 말아야 할 함수로 오버로드하지 마십시오. 직접적으로 관련된 것은 다른 클래스의 코드에도 나타나지 않아야합니다.

규모도 고려해야하므로 예제는 매우 주관적입니다. 간단한 프로그램은 너무 모듈화되어서는 안됩니다. 그렇지 않으면 조각화 될 것입니다. 복잡한 프로그램은 복잡성을 처리하기 위해 더 많은 수준의 추상화가 필요할 수 있습니다.

예 : 이메일 클래스. 여기에는 참조, 숨은 참조, 제목, 본문에 대한 데이터 멤버가 포함되어야하며 saveAsDraft (), send (), 폐기 Draft () 메소드를 포함 할 수 있습니다. 하지만 여기에는 많은 이메일 프로토콜이 있기 때문에 login ()이 없어야하며 별도로 구현해야합니다.


이것은 SRP의 정의입니다. "클래스는해야 할 일만 수행해야하며 완전히 수행해야합니다."
AliN11

11

응집력은 일반적으로 LCOM (응집력 부족) 메트릭 중 하나를 사용하여 측정되며 원래 LCOM 메트릭은 Chidamber 및 Kemerer에서 제공됩니다. 예 : http://www.computing.dcu.ie/~renaat/ca421/LCOM.html

보다 구체적인 예 : 예를 들어 클래스에 하나의 개인 필드와 세 개의 메소드가있는 경우; 세 가지 방법 모두이 필드를 사용하여 작업을 수행하면 클래스가 매우 응집력이 있습니다.

응집력있는 클래스의 의사 코드 :

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

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

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

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

예를 들어 클래스에 3 개의 개인 필드와 3 개의 메소드가있는 경우; 세 가지 방법 모두 세 필드 중 하나만 사용하면 클래스의 응집력이 떨어집니다.

응집력이 낮은 클래스의 의사 코드 :

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();
  }
}

한 가지 원칙을 수행하는 클래스 는 Robert C. Martin이 제공 하는 단일 책임 원칙 이며 SOLID 원칙 중 하나입니다 . 원칙은 클래스가 변경할 이유가 하나만 있어야한다고 규정합니다.

Single Responsibility Principle에 가깝게 유지하면 더 일관된 코드를 만들 수 있지만 제 생각에는 두 가지가 다릅니다.


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

응집력이란 클래스 나 메서드가 정의 된 작업을 하나만 수행함을 의미합니다. 메서드 또는 클래스의 이름도 자명해야합니다. 예를 들어 계산기를 작성하는 경우 클래스 이름은 "asdfghj"가 아니라 "calculator"로 지정해야합니다. 또한 각 작업에 대한 메서드를 만드는 것을 고려해야합니다. 예를 들어 subtract () add () 등 ... 나중에 프로그램을 사용할 프로그래머는 메서드가 수행하는 작업을 정확히 알고 있습니다. 좋은 이름 지정은 댓글 작성 노력을 줄일 수 있습니다.

또한 원칙은 DRY입니다-반복하지 마십시오


1

응집력이라는 용어는 원래 모듈의 소스 코드가 서로 얼마나 잘 관련되어 있는지에 대한 질적 척도로서 소스 코드의 모듈을 설명하는 데 사용되었습니다. 응집력의 개념은 다양한 분야에서 사용됩니다. 예를 들어, 군대와 같은 사람들의 그룹은 응집력이있을 수 있습니다. 즉, 부대의 사람들이 공동의 목표를 향해 함께 일합니다.

소스 코드 응집의 본질은 모듈의 소스 코드가 공통되고 잘 정의 된 목표를 향해 함께 작동한다는 것입니다. 모듈 출력을 생성하는 데 필요한 최소한의 소스 코드는 모듈에 있으며 더 이상 필요하지 않습니다. 인터페이스는 잘 정의되어 있고 입력은 인터페이스를 통해 흐르고 출력은 인터페이스를 통해 다시 흐릅니다. 부작용이 없으며 미니멀리즘에 중점을 둡니다.

기능적으로 응집 된 모듈의 장점은 단위 테스트를 개발하고 자동화하는 것이 간단하다는 것입니다. 사실 모듈의 응집력에 대한 좋은 척도는 모듈에 대한 전체 단위 테스트 세트를 만드는 것이 얼마나 쉬운 지입니다.

모듈은 객체 지향 언어의 클래스이거나 기능적 언어 또는 C와 같은 비 객체 지향 언어의 함수일 수 있습니다. 응집력 측정의이 영역에서 원래 작업의 대부분은 IBM의 COBOL 프로그램과 관련된 작업이었습니다. 1970 년대의 응집력은 객체 지향 개념이 아닙니다.

응집의 개념과 결합의 관련 개념이 나온 연구의 원래 의도는 이해, 유지, 확장하기 쉬운 프로그램의 특성이 무엇인지에 대한 연구였습니다. 목표는 프로그래밍의 모범 사례를 배우고 이러한 모범 사례를 코드화 한 다음 다른 프로그래머에게 사례를 가르치는 것이 었습니다.

좋은 프로그래머의 목표는 환경과 해결되는 문제를 고려할 때 가능한 한 응집력이 높은 소스 코드를 작성하는 것입니다. 이는 대규모 응용 프로그램에서 소스 코드 본문의 일부 부분이 해당 모듈 또는 클래스에있는 소스 코드의 결합 수준에 따라 다른 부분과 다를 수 있음을 의미합니다. 당신이 얻을 수있는 최선의 경우는 당신이 해결하려는 문제로 인한 일시적 또는 순차적 응집력입니다.

최고의 응집력은 기능적 응집력입니다. 기능적 응집력이있는 모듈은 일련의 입력을 제공하고 특정 출력을 얻는다는 점에서 수학적 함수와 유사합니다. 진정으로 작동하는 모듈은 출력 외에 부작용이 없으며 어떤 종류의 상태도 유지하지 않습니다. 대신 모듈의 내부를 노출하지 않고 모듈의 기능을 캡슐화하는 잘 정의 된 인터페이스를 갖게되며 모듈을 사용하는 사람은 특정 입력 세트를 제공하고 그 대가로 특정 출력을 얻습니다. 실제로 기능하는 모듈도 스레드로부터 안전해야합니다.

많은 프로그래밍 언어 라이브러리에는 클래스, 템플릿 또는 함수와 같은 기능 모듈의 여러 예제가 포함되어 있습니다. 가장 기능적으로 응집 된 예는 sin, cosine, square root 등과 같은 수학 함수입니다.

다른 함수는 부작용이 있거나 어떤 종류의 상태를 유지하여 이러한 함수의 사용을 더 복잡하게 만들 수 있습니다.

예를 들어 예외를 던지거나 전역 오류 변수를 설정하거나 ( errnoC에서) 시퀀스에서 사용해야하는 strtok()함수 ( 함수는 내부 상태를 유지하는 표준 C 라이브러리의 예) 또는 다음을 수행해야하는 포인터를 제공하는 함수 관리되거나 일부 로그 유틸리티에 로그를 발행하는 것은 더 이상 기능적 결합이 아닌 기능의 모든 예입니다.

Yourdon과 Constantine의 원본 책 Structured Programming을 모두 읽었습니다. 1980 년대에 응집력에 대한 아이디어를 처음 발견했고 Meilir Page-Jones의 책 Practical Guide to Structured Systems Design을 발견했으며 Page-Jones는 훨씬 더 잘 설명했습니다. 결합과 응집력 모두. Yourdon and Constantine 책은 좀 더 학문적으로 보입니다. Steve McConnell의 저서 Code Complete는 매우 훌륭하고 실용적이며 개정판에는 좋은 프로그래밍 관행에 대해 많은 의견이 있습니다.


당신은 말할 The minimum amount of source code needed to create the module outputs is in the module and no more이가 응집 관련이 있지만하지 않는 것입니다 DTSTTCPW
v.oddou

@ v.oddou, 최소 코드 양은 실제로 Cohesion과 관련이 있습니다. 모듈 출력과 관련이없는 모듈의 코드가 많을수록 코드에 부작용이 발생할 가능성이 높아져 응집력이 낮아집니다. 모든 개념은 서로 다른 관점, 특히 다소 모호한 응집력과 같은 개념을 가지고 있습니다. Cohesion에 대한 측정은 어떤 종류의 루 브릭을 사용하여 특정 모듈을 한 범주 또는 다른 범주에 할당하기 위해 일종의 퍼지 논리를 요구하는 질적입니다. 출력에 대한 최소 코드는 높은 응집력에 대한 충분한 특성이 아니라 여러 가지 중 하나입니다.
Richard Chambers

1

대부분의 답변은 응집력이 무엇인지 설명하지 않습니다. bobs 삼촌 책 정리 코드에 잘 정의되어 있습니다.

클래스에는 적은 수의 인스턴스 변수가 있어야합니다. 클래스의 각 메서드는 이러한 변수 중 하나 이상을 조작해야합니다. 일반적으로 메서드가 조작하는 변수가 많을수록 해당 메서드는 클래스에 대해 더 응집력이 있습니다. 각 변수가 각 메서드에서 사용되는 클래스는 최대한 응집력이 있습니다. 일반적으로 이러한 최대로 응집력있는 클래스를 만드는 것은 바람직하지도 가능하지도 않습니다. 반면에 우리는 응집력이 높기를 바랍니다. 응집력이 높으면 클래스의 메서드와 변수가 서로 의존적이며 논리적 전체로 함께 묶여 있음을 의미합니다.

클래스 정의로 설명하겠습니다.

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.