소개
클린아키텍처: 소프트웨어 구조와 설계의 원칙 책을 읽고 정리하며 소감을 적는 포스트입니다.
컴포넌트 원칙
컴포넌트는 배포 단위다. 컴포넌트는 시스템의 구성 요소로 배포할 수 있는 가장 작은 단위다.
자바에서는 jar 파일이 컴포넌트이고, 닷넷에서는 DLL이다.
컴포넌트가 가장 마지막에 어떤 형태로 배포되든, 잘 설계된 컴포넌트라면 반드시 독립적으로 배포 가능한, 따라서 독립적으로 개발 가능한 능력을 갖춰야 한다.
컴포넌트의 간략한 역사
소프트웨어 개발 초창기에는 메모리에서의 프로그램 위치와 레이아웃을 프로그래머가 직접 제어했다. 프로그램의 시작부에는 프로그램이 로드 될 주소를 선언하는 오리진(origin) 구문이 나와야 했다.
1
2
3
4
5
6
7
8
9
*200
TLS
START, CLA
TAD BUFR
JMS GETSTR
CLA
TAD BUFR
JMS PUTSTR
JMP START
프로그램 시작부에 있는 *200은 메모리 주소 2008에 로드할 코드를 생성하라고 컴파일러에 알려준다.
이 시대에는 장치는 느리고 메모리는 너무 비싸 메모리가 소스 코드 전체를 메모리에 상주시킬 수가 없었다.
결국 컴파일러는 느린 장치를 이용해서 소스 코드를 여러차례 읽어야만 했다.
컴파일 시간을 단축시키기 위해 프로그래머는 함수 라이브러리와 소스 코드를 애플리케이션 코드로부터 분리했다.
하지만 애플리케이션 마져 점점 커져서 두 개의 주소 세그먼트로 분리하여 함수 라이브러리 공간을 사이에 두고 오가며 동작하게 배치해야 했다.
애플리케이션을 두 개의 주소 세그먼트로 분리
그러나 이러한 배치에서 함수 라이브러리 마저 커지게 된다면 할당된 메모리 주소를 넘어서게 되고 결국 추가 공간을 할당해야 한다.
재배치성
위의 문제를 해결하기 위해서는 재배치가 가능한 바이너리(relocatable binary)였다.
재배치 로더가 여러 개의 바이너리의 위치 정보를 전달받아 새롭게 재배치 하였다. 이를 통해 프로그래머는 피룡한 함수만 로드 할 수 있게 되었다.
또한 컴파일러는 재배치 가능한 바이너리 안의 함수 이름을 메타데이터 형태로 생성하도록 수정하였다. 만약 프로그램이 라이브러리 함수를 호출한다면 컴파일러는 라이브러리 함수 이름을 외부 참조(external reference)로 생성했다. 반면 라이브러리 함수를 정의하는 프로그램이라면 외부 정의(external definition)을 생성했다.
이렇게 링킹 로더(linking loader)가 탄생했다.
링커
링킹 로더의 등장으로 프로그래머는 프로그램을 개별적으로 컴파일하고 로드할 수 있는 단위로 분할 할 수 있게 되었다.
하지만 링킹 로더는 너무 느려서 로드와 링크가 두 단계로 분리 되었다.
프로그래머가 느린 부분, 링크 과정을 맡았는데, 링커(linker)라는 벼롣의 애플리케이션으로 이 작업을 처리하도록 만들었다.
하지만 1980년대가 되어 C나, 다른 고수준 언어를 사용하게 되며 또 다시 전체 모듈을 컴파일 하는 시간이 오래 걸리게 되었고 링커에서는 더 많은 시간이 소요 되었다.
로드 시간은 여진히 빨랐지만 컴파일-링크 시간이 병목 구간이었다.
컴파일하고 링크하는 데 사용 가능한 시간을 모두 소모할 때까지 프로그램은 커진다.
하지만 무어의 법칙이 생겨나면서 메모리는 저렴해지고 RAM에 모두 캐싱 할 수 있을 정도로 커졌다.
이렇게 액티브 X와 공유 라이버러리 시대가 열렸고, .jar 파일도 등장하기 시작했다. 컴퓨터와 장치가 빨라져서 또다시 로드와 링크를 동시에 할 수 있게 되었다. 다수의 .jar 파일 또는 다수의 공유라이브러리를 순식간에 서로 링크한 후, 링크가 끝난 프로그램을 실행할 수 있게 되었다.
이렇게 컴포넌트 플러그인 아키텍처(component plugin architecture)가 탄생했다.
결론
런타임에 플러그인 형태로 결합할 수 있는 동적 링크 파일이 이 책에서 말하는 소프트웨어 컴포넌트에 해당한다.