일반화보다 구성을 선호하는 것이 항상 올바른 선택인지 어떻게 알 수 있습니까?


9

물체의 물리적 존재 여부에 관계없이 다양한 방법으로 모델링 할 수 있습니다. 많은 경우에 일반화 나 구성을 임의로 사용할 수 있습니다. 그러나 "일반화보다 선호하는 구성 [sic]"의 GoF 원칙은 구성을 사용하도록 안내합니다. 예를 들어, 선을 모델링 할 때 Point (일반화)를 확장하는 대신 Point (구성) 유형의 PointA와 PointB 두 멤버를 포함하는 클래스를 만듭니다. 이것은 객체가 일반적으로 훨씬 더 복잡함에도 불구하고 모델링 할 컴포지션 또는 상속을 임의로 선택할 수있는 간단한 예입니다.

이것이 올바른 선택임을 어떻게 알 수 있습니까? 적어도 리팩토링이 잘못되어도 문제가 될 수 있습니까?


9
요점 이라고 말할 수 없기 때문에 예제가 실제로 작동하지 않으므로 Liskov 대체 원칙에 실패 하고 상속이 적합하지 않습니다.
Dean Harding

@Dean : 아시다시피, 예제는 핵심이 아닙니다. 레코드의 경우 선은 두 점을 통해 정의 된 방정식으로 표현 될 수 있습니다.
CarneyCode


1
@ 송고 : 당신이 요점을 완전히 놓친 것 같습니다.
CarneyCode

일반화 대신 전문화를 확장하지 않습니까?
Tulains Córdova

답변:


17

항상 올바른 선택은 아닙니다 . 그것은이다 유리한 대부분의 경우 하나. 컴포지트 모델에 변경 또는 확장이 필요한 경우 실수로 다른 클래스에 영향을 줄 염려없이 컴포지션을 변경할 수 있으므로 해당 모델에 대한 내성이 훨씬 뛰어납니다.

우리는 이것을 어떻게 알 수 있습니까? 경험과 다른 사람들의 경험에서.

방대한 클래스 계층 구조가 단순한 개념으로 시작된 것에서 자라 난 많은 상황을 보았습니다. 이곳에서 주요 리팩토링이 필요합니다. 한편 나는 컴포지션 구조가 상속으로 리팩토링되어야하는 상황을 본 적이 없다.

그러나 내 일화적인 증거로는 충분하지 않아야합니다. 인터넷을 둘러 보면 많은 사람들이 같은 경험을했습니다.


나는 그것을 좋아한다; 공감하다.
CarneyCode

"컴포지션 구조가 상속으로 리팩토링해야하는 상황을 본 적이 없습니다."
Kazark

7

"상속보다 선호하는 컴포지션"이상의 강력한 규칙을 원한다면 다음과 같이 제안 할 수 있습니다.

객체를 상속하는 두 가지 방법 (상속 및 구성) 중 하나는 객체를 전문화 할 기본 클래스에 대해 다형성 (대체 가능해야 함)이 필요한 경우에만 상속을 사용해야합니다.

그러나 모든 경험 법칙과 마찬가지로 규칙을 이해하면 규칙을 위반 할 수 있습니다. :)


0

나는 작곡과 일반화가 대안이 아니며 따옴표를 찾지 못했습니다 .
구성과 상속은 (전문화를 달성하기 위해), 추상화와 일반화는 (모듈화를 달성하기 위해) 주장 될 수 있습니다.

당신이 원하는 것은 디자인이 간단하고 그럴듯 해 지는데, 이것은 본질적으로 쉽게 측정되는 두 가지 특성입니다.
귀하의 경우에는 점의 개념을 확장하는 대신 자연스럽게 두 점으로 선을 정의하기 때문에 확장하는 대신 두 점의 선을 작성하는 것이 더 타당 해 보입니다.


더 자연 스럽습니까? 선은 단일 점 확장보다 두 점 이상입니까?
CarneyCode

2
나는 2+ 점으로 구성되어 있다는 사실을 포함하지 않는 선 정의를 본 적이 없다. 숫자의 도메인에 1 x 값만 있으면 선의 방정식을 사용하더라도 선이 아닌 점입니다.
Rig

0

호의는 두 후보가 모두 자격을 갖추면 발생합니다. 질문에 명시된 문제는 구성 옵션 만 있기 때문에이 계정에서 실패합니다.

"구성도 일반화를 사용할 수 있습니다." 이 말이 우리에게 의미가 있습니까? 그렇지 않다면 아직 '선호'규칙을 파악할 준비가되지 않은 것입니다.

컴포지션을 선호하는 이유는 컴포지션이 일반화보다 더 많은 확장 / 유연성 가능성을 제공하기 때문입니다. 이 확장 성 / 유연성은 대부분 런타임 / 동적 유연성 (인터페이스와 컴포지션의 조합으로 달성 됨)을 나타냅니다.

이점은 즉시 보이지 않습니다. 이점을 보려면 다음 예기치 않은 변경 요청을 기다려야합니다. 따라서 대부분의 경우 구성을 받아 들인 사람들과 비교할 때 일반화를 고수하는 사람들은 실패합니다 (나중에 언급 한 명백한 경우 제외). 따라서 규칙. 학습 관점에서 의존성 주입을 성공적으로 구현할 수 있다면 어느 것을 선호하고 언제 사용해야하는지 알아야합니다. 어떤 규칙을 선택해야할지 확실하지 않은 경우 규칙을 통해 결정을 내릴 수 있습니다. 다시 한 번에 두 가지 옵션을 모두 볼 수 있어야합니다.

요약 : 구성 : 더 작은 것을 더 큰 것으로 연결하면 커플 링이 줄어들고 더 큰 객체는 더 작은 객체를 다시 호출합니다. 생성 : 써드 파티 API 관점에서 메소드를 대체 할 수 있음을 정의하는 것은 메소드를 호출 할 수 있음을 정의하는 것보다 더 강력한 약속입니다 (일반화의 승리). 그리고 컴포지션을 사용하면 큰 클래스 대신 인터페이스에서 일반화도 사용한다는 것을 잊지 마십시오. 그러나 전체 크레딧은 불행히도 구성에 사용됩니다.


-4

오늘 저는 약 300 LoC를 썼습니다. 그리고 내가 위반하고 위반하지 않은 원칙을 기억할 수 없습니다. 리팩토링은 내 영혼을 구할 것입니다.

추상화가 3d 파티 API에 의해 지시되는 경우 일반적으로 상속을 사용하는 것이 좋습니다. 국내 디자인 실체는 추상적이거나 봉인되어야합니다. 추상 엔터티에는 잠재적으로 약 3 개의 상속자가 있어야합니다. 나는 하나의 가상 방법 확장 점을 좋아하지 않습니다. 위의 모든 것은 내 취향에 관한 것입니다. 나는 인터페이스 추상화에 대해 말하고 있지 않습니다. 완전한 이야기입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.