문제

이러한 관계를 상상해보십시오 :

  • 1 A에는 많은 B가 있습니다
  • 1 B에는 많은 C가 있습니다.

반대로:

  • C는 1 b를 가지고있다
  • B는 1a입니다
  • 전이성에 의해, C는 1 a를 갖는다

DB 에서이 관계를 모델링하려면 다음과 같습니다.

TableA
a_id

TableB
b_id
a_id (fk to TableA)

TableC
c_id
b_id (fk to TableB)

이 관계를 OO로 모델링하려면 다음과 같습니다.

objA
objB
objC

그리고 ...- OBJB는 obja에 대한 언급을 가지고 있습니다 - OBJC는 OBJB에 대해 언급합니다.

OBJC가 OBJA 메소드를 호출 해야하는 메소드가 있다면 어떻게 하시겠습니까?

옵션 1.

b.getA().runMethodX()

내가 아는 많은 ppl 이이 일을 할 것이지만, 나는 또한 geta ()가 순수한 OO 의미에서 B의 행동이 아니기 때문에 이것이 좋지 않다는 것을 배웠다. 그렇게하는 것은 절차 적 프로그래밍과 같습니다. 동의 동의하지 않음?

옵션 2.

OBJC가 생성자 주입 / 세터를 통해 OBJA 및 OBJB를 직접 참조하십시오.

이것이 좋은 생각입니까? 그러나 OBJB는 OBJC가 OBJA에 대한 참조를 가지고 있음을 참조합니다. 괜찮아? 또는 주기적 객체 참조의 경우가 아닌 한 허용 되는가?

옵션 3.

문제의 메소드를 OBJA로 이동하고 매개 변수 별 OBJC를 전달하십시오.

이것이 옵션으로 간주되는지 확실하지 않습니다. 나는 그것이 모든 경우에 효과가 없다고 생각합니다. OBJC의 방법이 상태에서만 작동하는 최소한으로 줄이고 Obja가 OBJA가 필요한 모든 일을 전후에해야 할 일을하도록하십시오.

옵션 4. (대표단)

runmethodxina ()를 B에 추가하면 호출됩니다

a.runMethodX()

C 호출

b.runMethodXinA()

나는이 방법을 전에 시도했지만 B는 A만큼 많은 방법을 가질 가능성이 높으며 B에 1 개의 방법이없고 건조를 위반하지 않습니까?

그래도 뭐야? 다른 옵션이 있습니까? 코멘트? 제안?

도움이 되었습니까?

해결책

옵션 2는 환경에 따라 참조 그래프 모양에서 나올 수있는 모든 문제 외에도 정보의 상당히 위험한 복제입니다.

방법이 일종의 이중 발송으로 OBJA 유형에 의존하는 경우 옵션 3이 이해 될 수 있습니다.

옵션 1은 Demeter의 법칙에 위배되지만 가장 방해가되지 않는 옵션 인 것 같습니다.

OBJB를 OBJA로 전달하는 OBJB의 전달 방법을 고려할 수도 있습니다.

다른 팁

선택 목록에서 선택은 옵션 4입니다. 데메테르의 법칙

  • 옵션 1은 Demeter의 법칙을 위반합니다
  • 옵션 2는 중복 참조를 소개합니다 그리고 Demeter의 법을 간접적으로 위반합니다
  • 옵션 3은 오브젝트 A를 오염 물체 C에 대한 지식으로 오염시킵니다.

옵션 4를 떠납니다

옵션 5가있을 수 있지만 원래 질문의 범위를 벗어납니다 ;-)

문제는 어떤 종류의 모델을 위해 노력하고 있다고 생각합니다. 전체 구조를 미리 알고 변경되지 않는 관계형 모델을 사용하는 경우 옵션 1이 허용됩니다. 즉, 데이터/방법은 a 특정 조직 패턴에서 C에 필요합니다.

옵션 2는 좋은 생각처럼 보일 수 있습니다. 그러나 당신은 본질적으로 같은 객체에 대한 두 가지 참조를 저장하고 있습니다. 이제 B가 다른 A에 매핑되면 B는 참조를 변경하기 위해 C에 알려야합니다. 좋지 않다.

그러나 옵션 4는 진정으로 OO 접근 방식을 찾는 올바른 방법 인 것 같습니다. 요점은 A가 구조를 바꿀 수 있고 B- 직계 아이 만 적응하면됩니다. C는 A가 어떻게 구현되는지 알지 못하고 신경 쓰지 않으며 A가 단순히 존재하고 B가 무엇을 해야하는지 알고있는 것으로 충분합니다.

실제로 C에서 B 로의 백 포인터가 필요합니까, 아니면 C에서 A에 액세스 할 수 있도록 만 가지고 있습니까? 어쩌면 A는 B와 C를 만들고 관계를 관리하는 데 책임을 져야 할 수도 있습니다. 이 시나리오에서 A는 C를 생성 할 때 C에 자체를 삽입 할 수 있습니다 (예 : C에는 A를 취하는 생성자가있을 수 있습니다).

C가 필요한 기능을 분리하고 인터페이스를 만들 수 있습니다. 인터페이스 (a 대신)는 구성시 C로 전달됩니다. 그것은 A에서 C를 분리 할 것입니다.

상황에 따라 1 번 또는 4 번. 내 금속 절단 소프트웨어에는 객체의 부모/원점을 알아야하는 많은 사례가 있습니다. 예를 들어 피팅에 대한 경로 컬렉션이 있으며 각 경로에는 피팅이 생성 된 피팅을 반환하는 피팅 속성이 있습니다.

그러나 연결된 객체가 단순히 원래 객체가 수학 지원과 같은 목적을 달성하는 데 도움이되기 때문에 단순히 존재하는 경우 위임이 더 나은 접근 방식 일 수 있습니다.

연결된 객체가 원래 객체를 수정하면 방문자 패턴을 사용하는 것이 좋습니다.

유일한 경고는 대부분의 OOP에서 이중 연결된 객체에주의해야한다는 것입니다. 쓰레기 수집은 종종 부모-자식 링크가 서로 연결되는 물체에서 실패합니다. 그리고 부모-자식 링크를 정리하는 것을 잊어 버리는 것은 일반적인 실수입니다.

이벤트 작성 및 소비를 지원하는 OOPS를 사용하면이 문제를 해결할 수 있습니다. 프록시를 사용하여. 부모는 자녀에게 그 자체가 아니라 프록시 객체를 건네줍니다. 자녀가 부모가 필요하면 프록시 객체에서 참조를 얻게됩니다. 프록시 객체는 부모가 스스로 돌아 오게하는 이벤트로 차례로 발생합니다. 하드 링크가 없으므로 프로그래머 나 쓰레기 수집가의 문제가 청소되지 않는 문제가 완화됩니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top