컴포넌트 결합
- ADP: 의존성 비순환 원칙 (Acyclick Dependencies Principle)
- SDP: 안정된 의존성 원칙(Stable Dependencies Principle)
- SAP: 안정된 추상화 원칙(Stable Abstractions Principle)
ADP
- 의존성 비순환 원칙 (Acyclick Dependencies Principle)
컴포넌트 의존성 그래프에 순환(cycle)이 있어서는 안 된다.
- '숙취 증후군 (the morning after syndrome)'
- 하루 종일 일해서 무언가를 작동하게 만들어 놓고 퇴근했는데, 이튿날 출근해 보면 전혀 돌아가지 않는 상황.
- 보통 당신보다 더 늦게까지 일하면서 당신이 의존하고 있던 무언가를 수정했기 때문이다.
- 숙취 증후군은 많은 개발자가 동일한 소스 파일을 수정하는 환경에서 발생한다.
순환 의존성 제거하기
- 이 문제의 해결책은 개발 환경을 릴리스 가능한 컴포넌트 단위로 분리하는 것이다.
- 컴포넌트는 개별 개발자 또는 단일 개발팀이 책임질 수 있는 작업 단위로 만든다.
- 개발자가 해당 컴포넌트가 동작하도록 만든 후, 해당 컴포넌트를 릴리스하여 다른 개발자가 사용할 수 있도록 만든다. 담당 개발자는 이 컴포넌트에 릴리스 번호를 부여한다.
- 컴포넌트가 새로 릴리스되어 사용할 수 있게 되면, 다른 팀에서는 새 릴리스를 당장 적용할지를 결정해야 한다. 적용하지 않기로 했다면 그냥 과거 버전의 릴리스를 계속 사용한다.
- 각 팀은 특정 컴포넌트가 새롭게 릴리스되면 자신의 컴포넌트를 해당 컴포넌트에 맞게 수정할 시기를 스스로 결정할 수 있다.
- 이 같은 작업 절차는 단순하며 합리적이어서 널리 사용되는 방식이다. 하지만 이 절차가 성공적으로 동작하려면 컴포넌트 사이의 의존성 구조를 반드시 관리해야 한다.
- 의존성 구조에 순환이 있어서는 안 된다. 의존성 구조에 순환이 생기면 '숙취 증후군'을 피할 수 없다.
[그림 7-1. 전형적인 컴포넌트 다이어그램]
- 그림 7-1의 컴포넌트 다이어그램에서는 컴포넌트를 조립하여 애플리케이션을 만드는 다소 전형적인 구조를 볼 수 있다.
- 중요한 점은 컴포넌트 간의 의존성 구조만 보면 된다.(애플리케이션의 목적은 안봐도 된다.)
- 어느 컴포넌트에서 시작하더라도, 의존성 관계를 따라가면 최초의 컴포넌트로 돌아갈 수 없다.
- 즉, 이 구조는 비순환 방향 그래프(Directed Acyclic Graph, DAG)이다.
- Presenters가 새롭게 릴리스되면 어떻게 될까?
- Presenters를 의존하고 있는 Main, View가 영향을 받는다. 해당 개발자가 당장 새로운 릴리스를 적용할지를 결정하면 된다.
- Main은 새롭게 릴리스하더라도 다른 컴포넌트에 영향을 끼치지 않으므로 자유롭다.
- 시스템 전체를 릴리스해야 할 때가 오면 릴리스 절차는 상향식으로 진행하면 된다. 먼저 Entities 컴포넌트를 컴파일하고, 테스트하고, 릴리스한다. 그리고 나서 Database와 Interactors에 대해서도 동일한 과정을 거친다. 화살표를 거꾸로 따라가면 된다.
순환이 컴포넌트 의존성 그래프에 미치는 영향
- 새로운 요구사항이 발생해서 Entities에 포함된 클래스 하나가 Authorizer에 포함된 클래스 하나를 사용하도록 변경할 수 밖에 없다고 가정해 보자.
\[그림 7-2. 순환 의존성\]
- 만약 Authorizer를 변경해서 릴리스한다고 가정하자.
- Authorizer를 의존하는 Entities가 변경되어야 하고, Entities를 의존하는 Interactors가 변경되어야 하고, Interactors를 의존하는 자기 자신인 Authorizer가 변경되어야 하므로 이 3개는 개별적으로 릴리스할 수가 없게 됩니다.
- 다시 '숙취 증후군'으로 돌아가게 됩니다.
순환 끊기
- 컴포넌트 사이의 순환을 끊고 의존성을 다시 DAG로 원상복구하는 일은 언제라도 가능하다.
- 의존성 역전 원칙(DIP)을 적용한다.[그림 7-3. Entities와 Authorizer 사이의 의존성 역전시키기]
- 그림 7-3처럼 User가 필요로 하는 메서드를 제공하는 인터페이스를 생성한다. 그리고 이 인터페이스는 Entities에 위치시키고, Authorizer에서는 이 인터페이스를 상속받는다. 이렇게 의존성을 역전 시킬 수 있고, 순환을 끊을 수 있다.
- Entities와 Authorizer가 모두 의존하는 새로운 컴포넌트를 만든다.[그림 7-4. Entities와 Authorizer 모두가 의존하는 새로운 컴포넌트]
- 두 컴포넌트가 모두 의존하는 클래스들을 새로운 컴포넌트로 이동시켜 순환을 끊을 수 있다.
흐트러짐(Jitters)
- 두 번째 해결책에서 시사하는 바는 요구사항이 변경되면 컴포넌트 구조도 변경될 수 있다는 사실이다.
- 애플리케이션이 성장함에 따라 컴포넌트 의존성 구조는 서서히 흐트러지며 또 성장한다.
- 의존성 구조에 순환이 발생하는지를 항상 관찰해야 한다. 순환이 발생하면 어떤 식으로든 끊어야 한다.
하향식(top-down) 설계
- 컴포넌트 구조는 하향식으로 설계될 수 없다.
- 컴포넌트는 시스템에서 가장 먼저 설계할 수 있는 대상이 아니며, 오히려 시스템이 성장하고 변경될 때 함께 진화한다.
- '컴포넌트 의존성 다이어그램'은 애플리케이션의 기능을 기술하는 일과는 거의 관련이 없다. 오히려 컴포넌트 의존성 다이어그램은 애플리케이션의 빌드 가능성(buildability)과 유지보수성(maintainability)을 보여주는 지도(map)와 같다.
- 빌드하거나 유지보수할 소프트웨어가 없다면 빌드와 유지보수에 관한 지도 또한 필요 없기 때문이다.
- 아직 아무런 클래스도 설계하지 않은 상태에서 컴포넌트 의존성 구조를 설계하려고 시도한다면 실패 할 수도 있다.
- 컴포넌트 의존성 구조는 시스템의 논리적 설계에 발맞춰 성장하며 또 진화해야 한다.
클린 아키첵처 전체 보기
클린 아키텍처란? https://blog.kjslab.com/199
클린 아키텍처 - 설계원칙 - SRP https://blog.kjslab.com/200
클린 아키텍처 - 설계원칙 - OCP https://blog.kjslab.com/201
클린 아키텍처 - 설계원칙 - LSP https://blog.kjslab.com/202
클린 아키텍처 - 설계원칙 - ISP https://blog.kjslab.com/203
클린 아키텍처 - 설계원칙 - DIP & SOLID 요약 https://blog.kjslab.com/204
클린 아키텍처 - 컴포넌트 https://blog.kjslab.com/205
클린 아키텍처 - 컴포넌트 결합 - ADP https://blog.kjslab.com/206
클린 아키텍처 - 컴포넌트 결합 - SDP https://blog.kjslab.com/207
클린 아키텍처 - 컴포넌트 결합 - SAP & 결론 https://blog.kjslab.com/208
'아키텍처 > 클린 아키텍처' 카테고리의 다른 글
클린 아키텍처란? (2) | 2023.02.11 |
---|---|
클린 아키텍처 - 설계원칙 - LSP (2) | 2023.02.11 |
클린 아키텍처 - 설계원칙 - DIP (14) | 2023.02.11 |
클린 아키텍처 - 설계원칙 - ISP (2) | 2023.02.11 |
클린 아키텍처 - 설계원칙 - OCP (13) | 2023.02.11 |
댓글