컴포넌트에 어떤 클래스들을 포함시켜야 하는가? 이것은 중요한 설계 결정이다. 너무 많이 묶으면 불필요한 의존성이 생기고, 너무 적게 묶으면 관리가 어려워진다. 세 가지 원칙이 이 결정을 도와준다.
REP: 재사용/릴리스 등가 원칙
“재사용의 단위는 릴리스의 단위와 같다.” (Reuse/Release Equivalence Principle)
의미
컴포넌트로 재사용하려면, 그 컴포넌트를 릴리스해야 한다. 릴리스란:
- 버전 번호 부여
- 릴리스 문서 제공
- 변경 사항 공지
flowchart LR
subgraph Component [컴포넌트]
C1[Class A]
C2[Class B]
C3[Class C]
end
Component --> R[릴리스]
R --> V["버전 1.2.0"]
R --> D[릴리스 노트]
R --> CH[변경 이력]
실천 지침
REP는 다음을 요구한다:
- 함께 릴리스될 클래스들을 묶어라
- 공통 테마나 목적이 있어야 한다
- 사용자가 전체를 재사용하거나 전혀 재사용하지 않거나
위반 사례
| |
이들은 관련이 없다. 하나를 사용하려면 나머지도 따라온다.
좋은 예
| |
JSON 처리라는 공통 테마로 묶여 있다.
CCP: 공통 폐쇄 원칙
“동일한 이유로, 동일한 시점에 변경되는 클래스들을 같은 컴포넌트로 묶어라.” (Common Closure Principle)
SRP의 컴포넌트 버전
CCP는 SRP를 컴포넌트 수준으로 확장한 것이다:
- SRP: 클래스는 하나의 변경 이유만 가져야 함
- CCP: 컴포넌트는 하나의 변경 이유만 가져야 함
flowchart TB
subgraph SRP [SRP - 클래스 수준]
C[Class]
A1[Actor 1]
A1 --> C
end
subgraph CCP [CCP - 컴포넌트 수준]
COMP[Component]
R1[변경 이유 1]
R1 --> COMP
end
목표
변경이 필요할 때:
- 하나의 컴포넌트만 수정
- 다른 컴포넌트는 재빌드/재배포 불필요
실천 지침
| |
청구 규칙이 바뀌면 → 이 컴포넌트만 수정
OCP와의 관계
CCP는 OCP를 보완한다:
- OCP: 변경에 닫혀 있어야 함
- 100% 폐쇄는 불가능: 어떤 변경은 불가피
- CCP: 불가피한 변경을 한 곳에 집중
“같은 이유로 변경되는 것들을 한 곳에 모아라. 그러면 변경의 영향이 퍼지지 않는다.”
CRP: 공통 재사용 원칙
“함께 재사용되지 않는 클래스들을 같은 컴포넌트에 넣지 마라.” (Common Reuse Principle)
ISP의 컴포넌트 버전
CRP는 ISP를 컴포넌트 수준으로 확장한 것이다:
- ISP: 사용하지 않는 메서드에 의존하지 마라
- CRP: 사용하지 않는 클래스에 의존하지 마라
불필요한 의존성의 위험
flowchart TB
subgraph User [사용자 컴포넌트]
UC[UserCode]
end
subgraph Utils [유틸 컴포넌트]
A[ClassA - 사용함]
B[ClassB - 사용 안 함]
C[ClassC - 사용 안 함]
end
UC --> A
B -.->|변경| REBUILD[재빌드 필요!]
REBUILD -.-> UC
ClassB가 변경되면:
- Utils 컴포넌트 전체 재빌드
- UserCode도 재빌드 (사용하지도 않는데!)
실천 지침
| |
Container를 사용하는 사람은 Geometry가 필요 없다.
| |
세 원칙의 장력
세 원칙은 서로 긴장 관계에 있다:
flowchart TB
subgraph Triangle [장력 다이어그램]
REP["REP재사용성그룹화 촉진"]
CCP["CCP유지보수성그룹화 촉진"]
CRP["CRP분리그룹화 억제"]
REP --- CCP
CCP --- CRP
CRP --- REP
end
REP와 CCP: 그룹화 촉진
- REP: “재사용되는 것들을 묶어라”
- CCP: “함께 변경되는 것들을 묶어라”
- 둘 다 컴포넌트를 크게 만드는 경향
CRP: 그룹화 억제
- CRP: “함께 사용되지 않는 것은 분리하라”
- 컴포넌트를 작게 만드는 경향
균형점 찾기
프로젝트 단계에 따라 균형점이 다르다:
flowchart LR
subgraph Early [초기 개발]
E["CCP 강조개발 용이성"]
end
subgraph Middle [성숙 단계]
M["균형점"]
end
subgraph Mature [성숙/재사용]
L["REP, CRP 강조재사용성"]
end
Early --> Middle --> Mature
| 단계 | 강조 원칙 | 이유 |
|---|---|---|
| 초기 개발 | CCP | 빠른 변경, 유지보수 중요 |
| 성숙 단계 | 균형 | 안정성과 유연성 동시 |
| 재사용 중심 | REP, CRP | 재사용 용이성 중요 |
실제 적용 예시
스프링 프레임워크
Spring은 여러 모듈로 분리되어 있다:
| |
- REP: 각 모듈이 독립적으로 릴리스
- CCP: 관련 기능이 한 모듈에
- CRP: 웹이 필요 없으면 spring-web 의존 불필요
나쁜 예: 모놀리식 유틸
| |
문제:
- DateUtils 변경 → 전체 재빌드
- StringUtils만 필요해도 전체 의존
핵심 요약
| 원칙 | 질문 | 효과 |
|---|---|---|
| REP | 함께 릴리스되는가? | 그룹화 촉진 |
| CCP | 함께 변경되는가? | 그룹화 촉진 |
| CRP | 함께 사용되는가? | 그룹화 억제 |
flowchart TB
Q1{함께 재사용?}
Q2{함께 변경?}
Q3{함께 릴리스?}
Q1 -->|Yes| SAME[같은 컴포넌트]
Q2 -->|Yes| SAME
Q3 -->|Yes| SAME
Q1 -->|No| DIFF[다른 컴포넌트]
“세 원칙은 서로 경쟁한다. REP와 CCP는 포함을, CRP는 배제를 강조한다. 좋은 아키텍트는 이 장력에서 현재 개발팀의 요구에 맞는 균형점을 찾는다.” — Robert C. Martin
다음 장에서는
다음 장에서는 컴포넌트 결합을 다룬다. 컴포넌트들 사이의 의존성을 어떻게 관리할 것인가? ADP, SDP, SAP 세 가지 원칙을 살펴본다.
![Featured image of post [Clean Architecture] 22. 컴포넌트 응집도: REP, CCP, CRP](/post/cleanarchitecture/22-component-cohesion-rep-ccp-crp/wordcloud_hu_1ad2ba202974b641.png)
![[Clean Architecture] 20. 컴포넌트 원칙 서론](/post/cleanarchitecture/20-component-principles-introduction/wordcloud_hu_595e83323d4f659.png)
![[Clean Architecture] 21. 컴포넌트: 배포 단위](/post/cleanarchitecture/21-components-deployment-units-history/wordcloud_hu_54d26db1736fbc0e.png)
![[Clean Architecture] 22. 컴포넌트 응집도: REP, CCP, CRP](/post/cleanarchitecture/22-component-cohesion-rep-ccp-crp/wordcloud_hu_a50c85da11e20dd2.png)
![[Clean Architecture] 23. 컴포넌트 결합: ADP, SDP, SAP](/post/cleanarchitecture/23-component-coupling-adp-sdp-sap/wordcloud_hu_50cb1cab4edab9f7.png)
![[Clean Architecture] 24. 아키텍처 서론](/post/cleanarchitecture/24-architecture-introduction-system-design/wordcloud_hu_b8cf4ed4d955987a.png)
![[Clean Architecture] 14. SOLID 원칙 서론](/post/cleanarchitecture/14-solid-principles-introduction/wordcloud_hu_b40e2016719b5d89.png)
![[Clean Architecture] 18. ISP: 인터페이스 분리 원칙](/post/cleanarchitecture/18-isp-interface-segregation-principle/wordcloud_hu_e792044eccd81103.png)
![[Clean Architecture] 15. SRP: 단일 책임 원칙](/post/cleanarchitecture/15-srp-single-responsibility-principle/wordcloud_hu_8a6fa0e5a13a91ff.png)
![[Clean Architecture] 16. OCP: 개방-폐쇄 원칙](/post/cleanarchitecture/16-ocp-open-closed-principle/wordcloud_hu_a84054017b47f51d.png)