code

커플 링, 응집력 및 데메테르의 법칙

codestyles 2020. 11. 25. 07:59
반응형

커플 링, 응집력 및 데메테르의 법칙


데메테르법칙은 당신이 직접 알고있는 사물에만 말해야 함을 나타냅니다. 즉, 다른 개체와 통신하기 위해 메서드 체인을 수행하지 마십시오. 이렇게하면 중개 개체와 부적절한 연결을 설정 하여 코드를 다른 코드에 부적절하게 결합 하게 됩니다.

그 나쁜.

해결책은 자신이 알고있는 클래스가 관계가있는 객체에 책임을 위임하는 간단한 래퍼를 본질적으로 노출하는 것입니다.

잘 됐네요.

그러나 이는 클래스의 응집력 이 낮은 것으로 보입니다 . 더 이상 정확히 무엇을하는지에 대한 책임을지는 것이 아니라 어떤 의미에서 관련 객체의 인터페이스 부분을 복제하여 코드의 응집력을 떨어 뜨리는 델리게이트도 있습니다.

그 나쁜.

정말 응집력이 낮아 지는가? 두 가지 악 중 덜한 것입니까?

선이 어디에 있는지 토론 할 수있는 회색 영역 중 하나입니까? 아니면 선을 그릴 위치와 그 결정을 내리는 데 사용할 수있는 기준을 결정하는 강력하고 원칙적인 방법이 있습니까?


"객체 지향 분석 및 설계"의 Grady Booch :

"응집성의 개념은 구조화 된 설계에서도 비롯됩니다. 간단히 말해서 응집력은 단일 모듈 (그리고 객체 지향 설계의 경우 단일 클래스 또는 객체)의 요소 간의 연결 정도를 측정합니다. 가장 바람직하지 않은 형태의 응집력은 우연입니다. 완전히 관련되지 않은 추상화가 동일한 클래스 또는 모듈에 던져지는 응집력입니다. 예를 들어, 행동이 전혀 관련이없는 개와 우주선의 추상화로 구성된 클래스를 생각해보십시오. 가장 바람직한 응집 형태는 기능적 응집력입니다. 클래스 또는 모듈의 모든 기능이 함께 작동하여 잘 묶인 동작을 제공합니다. 따라서 Dog 클래스의 의미가 개, 전체 개, 개만 포함하는 경우 기능적으로 응집력이 있습니다. "

위의 고객으로 개를 대체하면 좀 더 명확해질 수 있습니다. 따라서 목표는 기능적 응집을 목표로하고 가능한 한 우연한 응집에서 벗어나는 것입니다. 추상화에 따라 간단 할 수도 있고 리팩토링이 필요할 수도 있습니다.

응집성은 단일 클래스, 즉 함께 작동하는 클래스 그룹보다 "모듈"에 적용됩니다. 따라서이 경우 Customer 및 Order 클래스는 이러한 강력한 관계를 가지고 있고 고객이 주문을 만들고 주문이 고객에게 속하기 때문에 여전히 적절한 응집력을 가지고 있습니다.

Martin Fowler는이를 "Demeter의 제안"이라고 부르는 것이 더 편하다고 말합니다 ( Mocks are n't stubs ) :

"Mockist 테스터들은 getThis (). getThat (). getTheOther () 스타일의 메소드 체인 인 '기차 난파선'을 피하는 것에 대해 더 많이 이야기합니다. 메소드 체인을 피하는 것은 데메테르의 법칙을 따르는 것으로도 알려져 있습니다. 메소드 체인은 냄새이지만, 전달 방법으로 부풀어 오른 중년 남성 객체의 반대 문제도 냄새입니다. (나는 항상 데메테르의 제안 이라고 불린다면 데메테르의 법칙이 더 편할 것이라고 느꼈습니다 .) "

그것은 내가 어디에서 왔는지를 멋지게 요약합니다. 그것은 완벽하게 받아 들여지고 종종 "법"에 대한 엄격한 준수가 요구하는 것보다 낮은 수준의 응집력을 가져야합니다. 우연한 응집을 피하고 기능적 응집을 목표로하지만, 디자인 추상화에 더 자연스럽게 맞추기 위해 필요한 부분을 조정하는 데 얽매이지 마십시오.


데메테르의 법칙을 위반하는 경우

int price = customer.getOrder().getPrice();

해결책은 getOrderPrice ()를 생성하지 않고 코드를

int price = customer.getOrderPrice();

그러나 이것이 코드 냄새 라는 점에 주목하고 결합력을 높이고 결합을 낮추는 관련 변경을 수행하십시오. 안타깝게도 여기에 항상 적용되는 간단한 리팩토링은 없지만 적용해야 할 것입니다. tell do n't ask


응집력이 무엇을 의미하는지 오해했을 수도 있습니다. 다른 여러 클래스의 관점에서 구현 된 클래스는 명확한 개념을 나타내고 명확한 목적을 가지고 있다면 응집력이 반드시 낮은 것은 아닙니다. 예를 들어, class Person클래스 Date(생년월일) Address, 및 Education(그 사람이 다녔던 학교 목록 ) 측면에서 구현 된를 가질 수 있습니다 . 다른 수업과 관련하여 시행 Person되는 사실이 노출되지 않도록 출생 연도, 마지막으로 다닌 학교 또는 그가 살고있는 주를 가져 오는 래퍼를 제공 할 수 있습니다 Person. 이것은 결합을 감소시킬 것이지만 Person응집력을 떨어 뜨리지 않습니다.


회색 영역입니다. 이러한 원칙은 작업에 도움을주기위한 것입니다. 만약 당신이 그들을 위해 일하고 있다는 것을 알게된다면 (즉, 그들이 당신의 길을 가로막고 있거나 코드를 복잡하게 만드는 것을 발견한다면) 당신은 너무 열심히 준수하고 있고 당신은 필요합니다. 물러서.

당신을 위해 일하게 만들고 그것을 위해 일하지 마십시오.


이것이 실제로 응집력을 낮추는 지 모르겠습니다.

집계 / 구성은 공개 메서드를 통해 노출되는 계약을 충족하기 위해 다른 클래스를 활용하는 클래스에 관한 것입니다. 클래스는 관련 객체의 인터페이스를 복제 할 필요가 없습니다. 실제로 메서드 호출자로부터 이러한 집계 된 클래스에 대한 지식을 숨기고 있습니다.

여러 수준의 클래스 종속성이있는 경우 Demeter의 법칙을 준수하려면 각 수준에서 집계 / 구성 및 좋은 캡슐화를 적용하면됩니다.

즉, 각 클래스는 다른 클래스에 대한 하나 이상의 종속성을 갖지만 이러한 종속성은 속성 / 메소드에서 반환 된 개체가 아니라 참조 된 클래스에 대한 종속성 일뿐입니다.


결합과 응집 사이에 절충안이있는 것처럼 보이는 상황에서는 "다른 사람이 이미이 논리를 작성했고 버그를 찾고 있었으면 어디에서 먼저 살펴 볼까요?"라고 자문 할 것입니다. 그런 식으로 코드를 작성하십시오.

참고 URL : https://stackoverflow.com/questions/163071/coupling-cohesion-and-the-law-of-demeter

반응형