순환 참조의 문제점은 무엇입니까? 사용할 수 없으므로 테스트 할 수 없음”,

나는 오늘 프로그래밍 토론에 참여하여 기본적으로 순환 참조 (모듈, 클래스간에 관계없이)가 일반적으로 좋지 않다는 것을 기본적으로 가정했다. 피치를 마치면 동료가 “원형 참조에 어떤 문제가 있습니까?”

나는 이것에 대해 강한 감정을 가지고 있지만, 간결하고 구체적으로 말로 표현하기가 어렵습니다. 내가 설명 할 수있는 모든 설명은 나도 공리를 고려하는 다른 항목 ( “단독으로 사용할 수 없으므로 테스트 할 수 없음”, “참여 대상에서 상태가 변할 때 알 수없는 / 정의되지 않은 동작”)에 의존하는 경향이 있습니다. .)하지만 순환 참조가 나쁜 이유에 대한 간결한 이유를 듣고 싶습니다. 왜냐하면 내 두뇌가하는 믿음의 도약을 취하지 않고 이해하고 수정하기 위해 오랜 시간을 보내고 있습니다. 다양한 코드 비트를 확장합니다.

편집 : 이중 연결 목록 또는 부모에 대한 포인터와 같은 동종 원형 참조에 대해서는 묻지 않습니다. 이 질문은 libA를 호출하는 libA를 호출하는 libA와 같이 “더 큰 범위”순환 참조에 대해 실제로 묻습니다. 원하는 경우 ‘lib’대신 ‘module’을 사용하십시오. 지금까지 모든 답변에 감사드립니다!



답변

큰 있습니다 많은 순환 참조 문제 것들 :

  • 원형 클래스 참조는 높은 결합을 만듭니다 . 클래스마다 다시 컴파일해야 하나 그들 중 변경됩니다.

  • B는 A에 의존하지만 B가 완료 될 때까지 A를 조립할 수 없기 때문에 원형 조립품 참조 는 정적 연결을 방지 합니다.

  • 원형 객체 참조는 스택 오버플로로 순진한 재귀 알고리즘 (예 : serializer, 방문자 및 pretty-printer)과 충돌 할 수 있습니다 . 고급 알고리즘은 사이클 감지 기능을 가지며보다 구체적인 예외 / 오류 메시지와 함께 실패합니다.

  • 원형 객체 참조는 또한 의존성 주입을 불가능 하게 하여 시스템 의 테스트 가능성 을 크게 줄 입니다.

  • 순환 참조가 매우 많은 객체 는 종종 신 객체 입니다. 그렇지 않더라도 스파게티 코드 로 이어지는 경향이 있습니다 .

  • 순환 엔터티 참조 (특히 데이터베이스 및 도메인 모델)는 null아닌 제약 조건을 사용하지 못하게하므로 결국 데이터가 손상되거나 최소한 불일치가 발생할 수 있습니다.

  • 일반적으로 순환 참조 는 프로그램이 어떻게 작동하는지 이해하려고 할 때 단순히 혼란스럽고 인지 부하를 크게 증가시킵니다.

아이들을 생각하십시오. 가능하면 순환 참조를 피하십시오.


답변

원형 기준은 비 원형 기준의 결합의 두 배입니다.

Foo가 Bar에 대해 알고 있고 Bar가 Foo에 대해 알고 있다면 변경해야 할 두 가지 사항이 있습니다 (요구 사항이있을 때 Foos와 Bars는 더 이상 서로에 대해 알 필요가 없음). Foo는 Bar에 대해서는 알고 있지만 Bar는 Foo에 대해서는 모른다면 Bar를 터치하지 않고 Foo를 변경할 수 있습니다.

순환 참조는 또한 최소한 오래 지속되는 환경 (배포 된 서비스, 이미지 기반 개발 환경)에서 부트 스트랩 문제를 일으킬 수 있습니다. 여기서 Foo는로드하기 위해 Bar 작업에 의존하지만 Bar는 하중.


답변

두 비트의 코드를 함께 묶으면 하나의 큰 코드 조각을 효과적으로 갖게됩니다. 약간의 코드를 유지하기가 어렵다는 것은 최소한 크기의 제곱이며 가능하면 더 높습니다.

사람들은 종종 단일 클래스 (/ 함수 / 파일 / 등) 복잡성을보고 가장 작은 분리 가능 (캡슐화 가능) 단위의 복잡성을 실제로 고려해야한다는 것을 잊어 버립니다. 순환 종속성이 있으면 해당 장치의 크기가 눈에 보이지 않게 증가합니다 (파일 1을 변경하려고 시도하고 파일 2-127도 변경해야한다는 것을 알 때까지).


답변

그것들은 스스로가 아니라 나쁜 디자인의 지표로 나빠질 수 있습니다. Foo가 Bar에 의존하고 Bar가 Foo에 의존한다면, 고유 한 FooBar 대신에 왜 두 가지인지 의문을 갖는 것이 정당합니다.


답변

흠 … 그것은 순환 의존성에 의해 당신이 의미하는 바에 달려 있습니다. 실제로 매우 유익하다고 생각되는 순환 의존성이 있기 때문입니다.

XML DOM을 고려하십시오. 모든 노드가 부모를 참조하고 모든 부모가 자식 목록을 갖는 것이 좋습니다. 구조는 논리적으로 트리이지만 가비지 수집 알고리즘 또는 이와 유사한 관점에서 구조는 원형입니다.


답변

등인가 , 닭 또는 계란의 문제.

순환 참조가 불가피하고 유용한 많은 경우가 있지만, 예를 들어 다음과 같은 경우에는 작동하지 않습니다.

프로젝트 A는 프로젝트 B에 의존하고 B는 A에 의존합니다. A는 B에 사용하기 위해 컴파일되어야합니다.


답변

나는 여기서 대부분의 의견에 동의하지만 “부모”/ “자식”순환 참조에 대한 특별한 경우를 요구하고 싶습니다.

클래스는 종종 부모 또는 소유 클래스, 아마도 기본 동작, 데이터의 파일 이름, 열을 선택한 sql 문 또는 로그 파일의 위치 등에 대해 알아야합니다.

이전에 “부모”였던 것이 이제는 형제가되도록 포함 클래스를 사용하여 순환 참조없이이 작업을 수행 할 수 있지만,이를 위해 기존 코드를 항상 리팩토링 할 수있는 것은 아닙니다.

다른 대안은 자녀가 생성자에 필요할 수있는 모든 데이터를 전달하는 것입니다.