[클린아키텍처] 4. 컴포넌트 원칙
4. 컴포넌트 원칙
컴포넌트란
컴포는트는 배포 단위이며 시스템의 구성요소로 배포할 수 있는 가장 작은 단위다.
예시
- Java의 jar, war
- 루비의 gem
- .Net에서 DLL
잘 설계된 컴포넌트라면 반드시 독립적으로 배포(개발) 가능한 능력을 갖춰야 한다.
컴포넌트의 역사
1. 소프트웨어 개발 초창기에 메모리에서 프로그램 위치와 레이아웃을 프로그래머가 직접 제어했다.
- 이 떄 당시 라이브러리는 바이너리가 아닌 소스코드 형태로 존재했다.
- 하지만 이 방식은 컴파일 시 매우 느린 단점이 있다.
2. 컴파일 시간을 단축시키기 위해 함수 라이브러리 소스코드를 애플리케이션 코드로부터 분리했다.
- 하지만 라이브러리가 점점 커졌고 할당된 메모리 주소를 넘거가게 되는데
3. 재배치가 가능한 바이너리(relocatable bineary)
- 지능적인 로더를 사용해 메모리에 재배치할 수 있는 형태의 바이너리를 생성하도록 컴파일을 수정하자는 개념
- 로더는 재배치 코드가 자리할 위치 정보를 전달받음 -> 재배치 코드에는 로드한 데이터의 변경 부분을 주소에 로드할 수 있는지 알려주는 플래그 삽입
- 이제 프로그래머는 함수 라이브러리를 로드할 위치와 애플리케이션을 로드할 위치를 로더에게 지시할 수 있게 되었음
- 실제로 로더는 바이너리를 입력받은 후 단순히 하나씩 차례로 메모리로 로드하며 재배치하는 작업을 처리
- 이를 통해 프로그래머는 오직 필요한 함수만 로드 할 수 있게 됨
- 또한 컴파일러는 재배치 가능한 바이너리 안에 함수 이름을 메타데이터 형태로 생성하도록 수정
- 만약 프로그램이 라이브러리 함수를 호출한다면 라이브러리 함수 이름을 외부 참조(
external reference)로 생성 - 반면 라이브러리 함수를 정의하는 프로그램이라면 컴파일러는 해당 이름을 외부 정의(
external definition)로 생성 - 이렇게 하여 외부 정의 에 링크시킬 수 있게 됨
- 이렇게 링킹 로더(
linking loader)가 탄생
- 만약 프로그램이 라이브러리 함수를 호출한다면 라이브러리 함수 이름을 외부 참조(
4. 링커
- 링킹 로더의 등장으로 프로그래머는 프로그램을 개별적으로 컴파일하고 로드할 수 있는 단위로 분할할 수 있게 되었다.
- 하지만, 프로그램은 훨씬 커지게 되며 링킹 로더가 너무 느려졌다.
링킹 로더가 프로그램 하나를 로드하는 데만 한 시간 이상 걸리게 되었다. (자기테이프 사용)
- 마침내 로드와 링크가 두 단계로 분리
- 프로그래머가 느린 부분 즉, 링크 과정을 맡음
- 링커 라는 별도의 애플리케이션으로 해당 작업을 처리하도록 만듦
- 링커는 링크가 완료된 재배치 코드를 만들어 주어 로더의 로딩 과정이 아주 빨라짐
- 한번 만들어둔 실행 파일은 언제라도 빠르게 로드 할 수 있게 되었다.
5. 무어의 법칙
- 1980년대 소스 모듈은 .c파일에서 .o파일로 컴파일 후 링커로 전달되어 빠르게 로드될 수 있는 형태의 실행 파일로 만들어짐
- 각 모듈을 컴파일 하는 시간은 상대적으로 빠르지만 전체 모듈을 컴파일하는 일은 꽤 시간이 걸림
- 1980년대 후반에 들어서자 디스크는 작아졌으며 RAM의 용량은 커졌다. 컴퓨터 메모리는 저렴해짐
- 1990년대 후반이 되자, 프로그램을 성장시키는 속도보다 링크 시간이 줄어드는게 더 빨라지기 시작함.
- 이렇게 Active X와 공유 라이브러리 시대가 열리고 .jar파일 등장
결론: 이 책에서의 컴포넌트
런타임에 플러그인 형태로 결합할 수 있는 동적 링크 파일
컴포넌트 응집성
이 클래스를 어느 컴포넌트에 포함시켜야 할까?
해당 장에서는 컴포넌트 응집성과 관련된 세 가지 원칙을 논의한다.
- REP(
Reuse/Release Equivalence Principle): 재사용/릴리스 등가 원칙 - CCP(
Common Closure Principle): 공통 폐쇄 원칙 - CRP(
Common Reuse Principle): 공통 재사용 원칙
1. REP: 재사용/릴리즈 등가 원칙
재사용 단위는 릴리즈 단위와 같다.
2. CCP: 공통 폐쇄 원칙
동일한 이유로 동일한 시점에 변경되는 클래스를 같은 컴포넌트로 묶어라. 서로 다른 시점에 다른 이유로 변경되는 클래스는 다른 컴포넌트로 분리하라
3. CRP: 공통 재사용 원칙
컴포넌트 사용자들을 필요하지 않는 것에 의존하게 강요하지 말라