12장 컴포넌트
컴포넌트는 시스템의 구성 요소로 배포할 수 있는 가장 작은 단위다.
컴파일 언어에선 바이너리 파일의 결합체(jar)이고, 인터프리터 언어에선 소스 파일의 결합체다.
컴포넌트가 최종적으로 어떤 형태로 배포되든, 잘 설계된 컴포넌트라면 독립적으로 배포 가능해야한다.
컴포넌트의 간략한 역사
소프트웨어 개발 초창기엔 메모리에서 프로그램의 위치와 레이아웃을 프로그래머가 직접 제어했다.
이 시절엔 프로그래머가 라이브러리의 코드를 애플리케이션 코드에 직접 포함시켜 단일 프로그램으로 컴파일했다. 라이브러리는 바이너리가 아니라 소스 코드 형태로 유지되었다.
그러다 컴파일 시간을 줄이기 위해 함수 라이브러리의 소스 코드를 애플리케이션 코드로부터 분리했다. 함수 라이브러리를 별도로 컴파일해 메모리에 위치시키고 애플리케이션을 로드했다.
하지만 애플리케이션과 라이브러리가 사용하는 메모리가 늘어날수록 단편화가 발생할 수 밖에 없었다.
재배치성
재배치가 가능한 라이브러리를 통해 해결할 수 있었다. 로더를 사용해 메모리에 재배치할 수 있는 형태의 바이너리를 생성하도록 컴파일러를 수정했다. 로더는 여러 바이너리를 하나씩 로드하면서 재배치했고 이를 통해 프로그래머는 필요한 함수만 로드할 수 있게 되었다.
또한 컴파일러는 재배치 가능한 바이너리 안의 함수 이름을 메타데이터 형태로 생성하도록 수정했다. 프로그램에서 라이브러리 함수를 호출하는 부분을 외부 참조(external reference)로 생성하고, 라이브러리 함수를 정의하는 부분을 외부 정의(external definition)로 생성했다.
따라서 외부 정의를 로드할 위치가 정해지면 로더가 외부 참조를 외부 정의에 연결시킬 수 있게 되었다. 이렇게 링킹 로더(linking loader)가 탄생했다.
링커
링킹 로더의 등장으로 프로그래머는 프로그램을 개별적으로 컴파일하고 로드할 수 있게 되었다. 하지만 프로그램이 더 커지면서 디스크와 같은 느린 저장 장치로 인해 링킹 로더의 속도가 사용할 수 없는 수준이 되었다. 이로 인해 로드와 링크 두 단계로 분리되었다
이후 컴퓨터와 저장 장치의 속도가 점점 빨라져서 다시 로드와 링크를 동시에 할 수 있게 되었고 여러 jar 파일과 공유 라이브러리를 순식간에 링크해 실행할 수 있게 되었다. 이로 인해 컴포넌트 플러그인 아키텍처가 탄생했다.
결론
런타임에 플러그인 형태로 결합할 수 있는 동적 링크 파일이 소프트웨어 컴포넌트에 해당한다. 50년이 걸렸지만 이제는 기본적으로 쉽게 사용할 수 있다.
Last updated