사용 사례가없는 느슨한 커플 링은 안티 패턴입니까? 개발자에게 잘 설계된 소프트웨어의 성배입니다. 가까운 미래에

느슨한 커플 링은 일부 개발자에게 잘 설계된 소프트웨어의 성배입니다. 가까운 미래에 발생할 수있는 변경에 직면하여 코드를 더 유연하게 만들거나 코드 복제를 피할 때 확실히 좋습니다.

반면에, 구성 요소를 느슨하게 결합하려는 노력은 프로그램에서 간접적 인 양을 증가 시켜서 복잡성을 증가 시키며, 종종 이해하기 어렵고 종종 효율성을 떨어 뜨립니다.

느슨한 커플 링 (예 : 코드 중복 방지 또는 예측 가능한 미래에 발생할 수있는 변경 계획)과 같은 사용 사례가없는 느슨한 커플 링에 초점을두고 있습니까? 느슨한 커플 링이 YAGNI의 우산 아래에 떨어질 수 있습니까?



답변

약간.

일부 모듈을 분리해야하는 특정 요구 사항이없는 경우에도 너무 많은 노력없이 제공되는 느슨한 커플 링이 적합합니다. 그대로 매달린 과일.

반면에, 엄청나게 많은 양의 변화에 ​​대한 과도한 엔지니어링은 많은 불필요한 복잡성과 노력이 될 것입니다. YAGNI는 당신이 말하는 것처럼 머리에 부딪칩니다.


답변

프로그래밍 연습 X가 좋거나 나쁘습니까? 분명히 대답은 항상 “의존”입니다.

코드를보고 어떤 “패턴”을 삽입 할 수 있는지 궁금하다면 잘못하고있는 것입니다.

관련없는 객체가 서로 뒤섞이지 않도록 소프트웨어를 빌드하는 경우 올바르게 수행하는 것입니다.

솔루션을 무한정 확장하고 변경할 수 있도록 솔루션을 “엔지니어링”하는 경우 실제로 솔루션을 더욱 복잡하게 만듭니다.

나는 하루가 끝날 때, 당신은 단 하나의 진실에 빠져 있다고 생각합니다. 그것들을 결합하는 것이 덜 복잡하면 올바른 해결책입니다. 그것들을 분리하는 것이 덜 복잡하다면, 이것이 올바른 해결책입니다.

(저는 현재 매우 복잡한 방식으로 간단한 작업을 수행하는 상당히 작은 코드베이스에서 작업하고 있으며 그렇게 복잡하게 만드는 요소 중 하나는 원래 부분의 “커플 링”및 “응집”이라는 용어에 대한 이해가 부족하다는 것입니다. 개발자.)


답변

나는 당신이 여기서 얻는 것은 응집력 의 개념이라고 생각합니다 . 이 코드는 좋은 목적을 가지고 있습니까? 그 목적을 내면화하고 무슨 일이 일어나고 있는지의 “큰 그림”을 이해할 수 있습니까?

소스 파일이 더 많기 때문에 (별도의 클래스라고 가정 할 때) 단일 클래스가 목적을 가지고 있지 않기 때문에 따르기 어려운 코드로 이어질 수 있습니다.

민첩한 관점에서 볼 때 이러한 느슨한 결합은 반 패턴이 될 것입니다. 응집력이 없거나 사용 사례가 없으면 합리적인 단위 테스트를 작성할 수 없으며 코드의 목적을 확인할 수 없습니다. 이제 애자일 코드는 테스트 중심 개발이 사용될 때 커플 링이 느슨해 질 수 있습니다. 그러나 올바른 테스트가 올바른 순서대로 생성되면 응집력과 느슨한 결합이 모두있을 수 있습니다. 그리고 당신은 분명히 응집력이없는 경우에 대해서만 이야기하고 있습니다.

민첩한 관점에서 다시 말하지만, 어쨌든 필요하지 않은 무언가에 노력이 낭비되기 때문에 이러한 인공적인 간접적 수준을 원하지 않습니다. 실제로 필요한 경우 리팩토링하는 것이 훨씬 쉽습니다.

전반적으로, 당신은 당신의 모듈 내에서 높은 결합을 원하고 그것들 사이의 느슨한 결합을 원합니다. 높은 커플 링이 없으면 응집력이 없을 것입니다.


답변

이와 같은 대부분의 질문에 대한 대답은 “의존”입니다. 전반적으로 디자인이 논리적으로 느슨하게 결합되어 합리적으로 결합 될 수 있다면, 그렇게하는 데 큰 부담이되지 않습니다. 필자가 생각하기에 코드에서 불필요한 결합을 피하는 것은 전적으로 가치있는 디자인 목표입니다.

구성 요소가 논리적으로 밀접하게 결합되어 있어야하는 상황이 발생하면 구성 요소를 분해하기 전에 강력한 논쟁을 찾아 볼 것입니다.

나는 이러한 유형의 연습 대부분에 적용되는 원리가 관성 중 하나라고 생각합니다. 나는 내 코드가 어떻게 작동하고 싶을 지에 대한 아이디어를 가지고 있으며 인생을 더 힘들게하지 않고 그렇게 할 수 있다면 그렇게 할 것입니다. 그렇게하면 개발이 어렵지만 유지 보수 및 향후 작업이 쉬워지면 코드 수명 기간 동안 더 많은 작업이 수행 될지 추측하여 내 가이드로 사용할 것입니다. 그렇지 않으면 가치가있는 계획적인 디자인 포인트가되어야합니다.


답변

간단한 대답은 올바르게 수행하면 느슨한 결합이 양호하다는 것입니다.

하나의 기능, 하나의 목적을 따르는 경우, 진행중인 사항을 쉽게 따라갈 수 있어야합니다. 또한 느슨한 커플 코드는 당연히 아무런 노력없이 따릅니다.

간단한 설계 규칙 : 1. 파사드 인터페이스를 구축하지 않는 한 여러 항목에 대한 지식을 단일 지점으로 구축하지 마십시오. 2. 하나의 기능-하나의 목적 (외관에서와 같이 다목적 일 수 있음) 3. 하나의 모듈-하나의 명확한 관련 기능 세트-하나의 명확한 목적 4. 단순히 단위 테스트를 할 수없는 경우 간단한 목적

나중에 리팩토링하기 쉬운 것에 대한 이러한 모든 의견은 많은 코드입니다. 일단 지식이 많은 장소, 특히 분산 시스템에서 구축되면 리팩토링 비용, 롤아웃 동기화 및 거의 모든 다른 비용으로 인해 대부분의 경우 시스템이 그로 인해 폐기되는 결과를 고려하지 않아도됩니다.

요즘 소프트웨어 개발에있어 슬픈 점은 90 %의 사람들이 새로운 시스템을 개발하고 오래된 시스템을 이해할 능력이 없으며, 비트와 조각의 지속적인 리팩토링으로 인해 시스템이 열악한 건강 상태에 도달했을 때 결코 주변에 있지 않습니다.


답변

다른 것이 결코 바뀌지 않는다면 한 것이 다른 것과 얼마나 밀접하게 결합되어 있는지는 중요하지 않습니다. 나는 가능한 한 가장 느슨한 형태의 커플 링을 달성함으로써 변화하기 쉬운 이유를 찾는 것, 안정성을 추구하는 것보다 적은 이유를 찾는 것에 집중하는 것이 일반적으로 더 생산적이라는 것을 알았습니다.
디커플링 패키지를 분리하기 위해 때로는 겸손한 코드 복제를 선호하는 시점에서 매우 유용한 것으로 나타났습니다. 기본적인 예로, 수학 라이브러리를 사용하여 이미지 라이브러리를 구현할 수 있습니다. 나는 복사하기가 쉽지 않은 기본 수학 함수를 복제하지 않았습니다.

이제 내 이미지 라이브러리는 수학 라이브러리에 어떤 종류의 변경 사항이 있더라도 이미지 라이브러리에 영향을 미치지 않는 방식으로 수학 라이브러리와 완전히 독립적입니다. 안정성을 최우선으로 생각합니다. 이미지 라이브러리는 변경해야 할 다른 라이브러리와 분리되어 있기 때문에 변경해야 할 이유가 크게 줄어든만큼 안정적입니다. 보너스로 다른 라이브러리를 가져 와서 빌드하고 사용할 필요가없는 독립형 라이브러리 일 때 쉽게 배포 할 수 있습니다.

안정성은 저에게 매우 도움이됩니다. 나는 미래에 변화해야 할 이유가 점점 적은 잘 테스트 된 코드 모음을 만드는 것을 좋아합니다. 그것은 파이프 꿈이 아닙니다. 나는 80 년대 후반부터 그 이후로 전혀 바뀌지 않은 이후로 사용하고 다시 사용한 C 코드를 가지고 있습니다. 필자는 픽셀 지향 및 지오메트리 관련 코드와 같은 하위 수준의 항목이지만, 상위 수준의 항목은 많이 사용되지 않지만 여전히 많은 것을 유지하는 데 도움이되는 항목입니다. 그것은 거의 항상 외부가 없다면 더 적은 수의 것들에 의존하는 라이브러리를 의미합니다. 소프트웨어가 변화의 이유가 거의 없거나 전혀없는 안정적인 기반에 점점 더 의존 할 경우 안정성이 향상됩니다. 실제로 움직이는 부품의 수가 안정적인 부품보다 훨씬 많더라도 움직이는 부품 수가 적을수록 좋습니다.

느슨한 결합은 동일한 맥락에 있지만 느슨한 결합은 결합이없는 것보다 훨씬 덜 안정적이라는 것을 종종 발견합니다. 내가 생각했던 것보다 마음이 바뀌지 않는 훨씬 뛰어난 인터페이스 디자이너와 클라이언트가있는 팀에서 일하지 않는 한 순수한 인터페이스조차도 코드 전체에서 계단식 손상을 야기하는 방식으로 변경해야하는 이유를 종종 찾습니다. 인터페이스가 아닌 추상을 향해 의존성을 지향함으로써 안정성을 달성 할 수 있다는 아이디어는 인터페이스 디자인이 구현보다 처음부터 쉽게 이해되는 경우에만 유용합니다. 필자는 개발자가 충족해야한다고 생각한 설계 요구 사항을 감안하여 개발자가 매우 훌륭하지만 훌륭하지 않은 구현을 만들었을 때 종종 역전 된 것으로 나타났습니다.

따라서 안정성과 완벽한 디커플링을 선호하여 적어도 자신감있게 말할 수 있습니다. “수년 동안 사용되어 철저한 테스트를 통해 확보 된이 작은 격리 된 라이브러리는 혼란스러운 외부 세계에서 무슨 일이 있어도 변경이 필요하지 않습니다. ” 외부에서 어떤 종류의 디자인 변경이 필요하든 상관없이 약간의 정신이 나옵니다.

커플 링 및 안정성, ECS 예

또한 엔터티 구성 요소 시스템을 좋아하고 시스템과 구성 요소 간의 종속성이 모든 원시 데이터에 직접 액세스하고 다음과 같이 조작하기 때문에 많은 밀접한 결합을 도입합니다.

구성 요소가 원시 데이터를 노출하기 때문에 여기의 모든 종속성은 매우 엄격합니다. 의존성은 추상화를 향하지 않고 원시 데이터 를 향하고 있습니다 . 즉, 각 시스템은 액세스를 요청하는 각 유형의 구성 요소에 대해 가능한 최대의 지식을 가지고 있습니다. 구성 요소는 모든 시스템이 원시 데이터에 액세스하고 조작하는 기능을 수행하지 않습니다. 그러나 매우 평평하기 때문에 이와 같은 시스템에 대해서는 추론하기가 매우 쉽습니다. 텍스처가 까다로워지면 렌더링 및 페인팅 시스템 만 텍스처 구성 요소에 액세스한다는 점을이 시스템에서 즉시 알 수 있으며, 텍스처에서 개념적으로 만 읽기 때문에 렌더링 시스템을 신속하게 배제 할 수 있습니다.

한편 느슨하게 연결된 대안은 다음과 같습니다.

… 데이터가 아닌 추상 기능에 대한 모든 종속성과 해당 다이어그램의 모든 단일 항목이 공용 인터페이스와 자체 기능을 노출합니다. 여기서 모든 종속성은 매우 느슨 할 수 있습니다. 객체는 서로 직접적으로 의존하지 않고 순수한 인터페이스를 통해 서로 상호 작용할 수도 있습니다. 여전히 복잡한 상호 작용을 고려할 때 특히 문제가 발생하면이 시스템에 대해 추론하기가 매우 어렵습니다. 또한 ECS보다 더 많은 상호 작용 (더 많은 커플 링, 더 느슨하지만)이있을 것입니다. 엔티티는 서로의 추상 공용 인터페이스에 대해서만 알고 있더라도 집계하는 구성 요소에 대해 알아야하기 때문입니다.

또한 디자인 변경 사항이 있으면 ECS보다 계단식 손상이 더 많으며, 모든 단일 항목이 멋진 객체 지향 인터페이스와 추상화를 제공하려고 시도하기 때문에 일반적으로 디자인 변경 이유와 유혹이 더 많습니다. 그것은 각각의 모든 작은 일이 디자인에 제약과 한계를 부과하려고 할 것이라는 생각과 함께 즉시 제공되며, 그러한 제약은 종종 디자인 변경을 보증하는 것입니다. 기능은 훨씬 더 제한적이며 원시 데이터보다 훨씬 더 많은 설계 가정을해야합니다.

실제로 위의 “플랫”ECS 시스템 유형은 복잡한 종속성의 복잡한 거미줄을 가진 가장 느슨하게 결합 된 시스템보다 훨씬 쉽게 추론하기가 훨씬 쉽다는 것을 알게되었습니다. ECS 버전은 시스템이 작동하는 데 필요한 적절한 데이터를 제공하는 것 외에는 책임이 없기 때문에 기존 구성 요소를 변경해야하는 경우가 있습니다. IMotion개인 데이터에 대한 불변량을 유지하면서 문제를 해결하고 관련이없는 원시 데이터 만 제공해야하는 모션 구성 요소와 복잡한 기능을 제공하는 인터페이스를 구현 하는 순수한 인터페이스 및 콘크리트 모션 오브젝트 설계의 어려움을 비교하십시오. 기능.

기능은 데이터보다 훨씬 더 어려워지기 때문에 종속성의 흐름을 데이터로 향하게하는 것이 종종 바람직하다고 생각합니다. 결국 몇 개의 벡터 / 행렬 라이브러리가 있습니까? 정확히 같은 데이터 표현을 사용하고 기능상 미묘하게 다른 몇 개가 있습니까? 기능적으로 미묘한 차이를 원하기 때문에 동일한 데이터 표현에도 불구하고 셀 수없이 많은 데이터를 보유하고 있습니다. 이미지 라이브러리는 몇 개입니까? 그중 몇 개가 다른 독특한 방식으로 픽셀을 나타 냅니까? 기능이 훨씬 더 불안정하고 많은 시나리오에서 데이터보다 설계 변경에 더 취약하다는 것을 거의 보여주지 않습니다. 물론 어느 시점에는 기능이 필요하지만 대부분의 종속성이 데이터를 향한 시스템을 설계 할 수 있습니다. 일반적으로 추상화 나 기능에 대한 것이 아닙니다. 이는 커플 링보다 안정성을 우선시합니다.

필자가 작성한 가장 안정적인 함수 (80 년대 후반부터 전혀 변경하지 않고 사용하고 재사용 한 종류)는 모두 배열을 받아 들인 지오메트리 함수와 같이 원시 데이터에 의존하는 함수였습니다. 복합체에 의존 수레와 정수가 아닌 그들 Mesh오브젝트 또는 IMesh인터페이스 또는 벡터 / 행렬 곱셈에 의존하는 단지 float[]또는 double[]에 의존하지 하나 FancyMatrixObjectWhichWillRequireDesignChangesNextYearAndDeprecateWhatWeUse.