ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 14장 - 컴포넌트 결합
    클린 코드(Clean Code)/클린 아키텍처요약 2022. 12. 16. 00:01
    728x90

    컴포넌트 사이의 관계를 설명하는 세 가지 원칙을 다루고자 합니다.

     

    의존성 비순환 원칙

    컴포넌트 의존성 그래프에 순환이 있어서는 안 된다.

     

    어떤 코드가 동작하는 것을 확인한 뒤, 다음날 출근해보면 작동하지 않는 경험이 있으신가요?

     

    많은 개발자가 동일한 소스 파일을 수정하는 환경에서 발생하는 문제로 당신보다 더 늦게까지 일하면서 당신이 의존하고 있던 무언가를 수정해서 벌어진 일입니다.

     

    이를 해결하기 위한 두 가지 방법이 발전되어 왔습니다.

     

    주 단위 빌드

    4일은 개발자들이 개별 작업 , 1일은 통합하는데 시간을 소요합니다.

     

    하지만 프로젝트의 덩치가 커질수록 통합하는 작업을 하루가 아니라 더 소모됩니다.

     

    점점 개발팀의 통합 효율성은 낮아지고 빌드 일정은 늘어나며 프로젝트가 감수할 위험은 커집니다.

     

    순환 의존성 제거하기

    릴리스 가능한 컴포넌트 단위로 분리하여 개발자는 해당 컴포넌트가 동작하도록 만든 뒤, 해당 컴포넌트를 릴리스하여 다른 개발자가 사용할 수 있도록 만듭니다.

     

    릴리스 번호를 부여하고 공유합니다.

    이후 자신만의 공간에서 해당 컴포넌트를 지속적으로 수정하여 새로운 릴리즈를 공유합니다.

     

    이제 다른 팀에서는 새 릴리즈를 적용할지 말지 선택해서 결정할 수 있습니다.

     

    이 절차가 성공적으로 동작하려면 컴포넌트 사이의 의존성에 순환이 존재하면 안 됩니다.

     

    순환 끊기

    1. DIP를 통한 의존성 역전

     

    2. 두 컴포넌트가 모두 의존하는 새로운 컴포넌트를 만들기

     

    하지만 애플리케이션의 요구사항이 계속 변경되면서 컴포넌트 구조는 변할 수 있습니다.

    따라서 의존성 구조에 순환이 존재하는지 항상 잘 관찰하고 순환을 끊어내야 합니다.

     

    하향식 설계

    컴포넌트는 시스템에서 가장 먼저 설계하기 어렵고 오히려 시스템이 변화하고 성장할 때 함께 진화합니다.

     

    아무런 클래스도 설계하지 않은 상태에서 컴포넌트 의존성 구조를 설계하려고 시도한다면 상당히 큰 실패를 맛볼 수 있습니다.

    공통 폐쇄에 대해 그다지 많이 파악도 못하고 있고, 재사용 가능한 요소도 알지 못합니다.

    컴포넌트를 생성할 때 높은 확률로 순환 의존성이 발생하게 됩니다.

     

    따라서 컴포넌트 의존성 구조를 시스템의 논리적 설계에 맞춰 성장하며 또 진화해야 합니다.

     

    SDP: 안정된 의존성 원칙

    컴포넌트 일부는 변동성이 지니도록 설계되고 언젠가는 변경될 수 있습니다.

    변경이 쉽지 않은 컴포넌트가 변동이 예상되는 컴포넌트에 의존하게 만들면 안 됩니다.

    한번 의존하게 되면 변동성이 큰 컴포넌트도 변경이 어려워지게 됩니다.

     

    안정성

    동전을 옆면으로 세우면 안정적인가?

    하지만 동전을 건드리지 않는다면 꽤 오래 서 있을 수 있습니다.

     

    안정성은 변경을 만들기 위해 필요한 작업량과 관련됩니다.

     

    소프트웨어 컴포넌트를 변경하기 어렵게 만드는 확실한 방법은 수많은 다른 컴포넌트가 해당 컴포넌트를 의존하게 만들면 됩니다.

    X에 의존하는 컴포넌트수가 많아질수록 X는 안정적입니다.

    반면에 Y에 의존하는 컴포넌트 수가 존재하지 않으면 Y는 의존적입니다.

     

    안정성 지표

    Fan-in : 컴포넌트 내부의 클래스에 의존하는 컴포넌트 외부의 클래스 개수

    Fan-out : 바깥으로 나가는 의존성

    I(불안정성) : Fan-out % (Fan-in + Fan-out)

    지표는 [0,1] 범위를 가지며 I=0이면 최고로 안정된 컴포넌트, I=1이면 최고로 불안정한 컴포넌트입니다.

     

    즉, 바깥으로 나가는 의존성만 있으면 불안정한 컴포넌트이며 의존하는 컴포넌트의 개수만 있다면 안정된 컴포넌트입니다.

     

    SDP에서는 컴포넌트의 I지표는 그 컴포넌트가 의존하는 다른 컴포넌트들의 I보다 커야 한다고 말합니다.

     

    하지만 모든 컴포넌트가 최고로 안정적인 시스템이라면 변경이 불가능합니다.

     

    만약 안정적인 컴포넌트가 불안정적인 컴포넌트를 의존하게 된다면 SDP를 위반합니다.

    이런 경우 인터페이스를 활용한 DIP를 통해 해결할 수 있습니다.

     

    SAP : 안정된 추상화 원칙

    컴포넌트는 안정된 정도만큼만 추상화되어야 한다.

    시스템에는 자주 변경하면 안 되는 소프트웨어도 존재합니다.

    고수준 아키텍처나 정책 결정 관련된 소프트웨어가 그 예시입니다.

     

    고수준 정책을 캡슐화하는 컴포넌트는 안정된 컴포넌트에 위치해야 하며 변동성이 큰 소프트웨어 불안정한 컴포넌트에 위치해야 합니다.

     

    컴포넌트가 최고로 안정된 상태이면서 동시에 변경에 충분히 대응할 수 있을 정도로 유연하게 만들기 위해서는 OCP를 도입하면 됩니다.

    이런 상황을 만들기 위해서는 추상 클래스를 활용하여 해결할 수 있습니다.

     

    안정적인 컴포넌트는 인터페이스와 추상 클래스로 구성되어 쉽게 확장성을 얻을 수 있어야 합니다.

    불안정적인 컴포넌트는 구체 클래스로 구성되어 쉽게 변경할 수 있어야 합니다.

     

     

    주계열

    (x, y)로 이루어진 좌표계에서 x는 안정성, y는 추상화를 의미합니다.

    (0,1)은 최고로 안정적이며 추상화된 컴포넌트를 의미합니다.

    (1,0)은 최고로 불안정하며 구체화된 컴포넌트를 의미합니다.

     

    고통의 구역

    이때(0,0) 부근에 위치한 컴포넌트들은 고통의 구역이라 부릅니다.

    매우 안정적이며 구체적입니다.

    추상적이지 않아 확장할 수 없고, 안정적으로 변경하기도 상당히 어렵습니다.

     

    데이터베이스 스키마는 변동성이 높고 극단적으로 구체적이며 많은 컴포넌트가 여기에 의존합니다.

    이런 이유로 애플리케이션과 데이터베이스 사이에 위치한 인터페이스는 관리하기가 굉장히 어렵고, 스키마가 변경되면 대체로 고통을 수반합니다.

     

    다른 예시로 string 컴포넌트가 존재합니다.

    하지만 String 컴포넌트는 변동성이 없으며 고통의 구역에 위치했더라도 해롭지 않습니다.

     

    쓸모없는 구역

    (1,1) 부근에 위치한 컴포넌트들은 쓸모없는 구역이라 부릅니다.

    컴포넌트들은 최고로 추상적이지만 누구도 그 컴포넌트를 의존하지 않습니다.

     

    따라서 보통 이런 배제구역을 벗어나서 (1,0)과 (0,1)을 잇는 선분인 주계열에 위치한 컴포넌트가 바람직하다고 봅니다.

     

    결론

    이런 지표는 신이 아닙니다.

    임의로 결정된 표준을 기초로 한 측정값에 지나지 않습니다.

    이를 지표로부터 무언가 유용한 것을 찾을 수 있기를 바랍니다.

    '클린 코드(Clean Code) > 클린 아키텍처요약' 카테고리의 다른 글

    16장 - 독립성  (0) 2022.12.21
    15장 - 아키텍처란?  (0) 2022.12.20
    13장 - 컴포넌트 응집도  (0) 2022.12.14
    12장 - 컴포넌트  (0) 2022.12.13
    11장 - DIP: 의존성 역전 원칙  (0) 2022.11.27

    댓글

Designed by Tistory.