4. 컴포넌트 원칙

컴포넌트란

컴포는트는 배포 단위이며 시스템의 구성요소로 배포할 수 있는 가장 작은 단위다.

예시

  1. Java의 jar, war
  2. 루비의 gem
  3. .Net에서 DLL

잘 설계된 컴포넌트라면 반드시 독립적으로 배포(개발) 가능한 능력을 갖춰야 한다.

컴포넌트의 역사

1. 소프트웨어 개발 초창기에 메모리에서 프로그램 위치와 레이아웃을 프로그래머가 직접 제어했다.

  • 이 떄 당시 라이브러리는 바이너리가 아닌 소스코드 형태로 존재했다.
  • 하지만 이 방식은 컴파일 시 매우 느린 단점이 있다.

2. 컴파일 시간을 단축시키기 위해 함수 라이브러리 소스코드를 애플리케이션 코드로부터 분리했다.

  • 하지만 라이브러리가 점점 커졌고 할당된 메모리 주소를 넘거가게 되는데

3. 재배치가 가능한 바이너리(relocatable bineary)

  • 지능적인 로더를 사용해 메모리에 재배치할 수 있는 형태의 바이너리를 생성하도록 컴파일을 수정하자는 개념
  • 로더는 재배치 코드가 자리할 위치 정보를 전달받음 -> 재배치 코드에는 로드한 데이터의 변경 부분을 주소에 로드할 수 있는지 알려주는 플래그 삽입
  • 이제 프로그래머는 함수 라이브러리를 로드할 위치와 애플리케이션을 로드할 위치를 로더에게 지시할 수 있게 되었음
  • 실제로 로더는 바이너리를 입력받은 후 단순히 하나씩 차례로 메모리로 로드하며 재배치하는 작업을 처리
    • 이를 통해 프로그래머는 오직 필요한 함수만 로드 할 수 있게 됨
  • 또한 컴파일러는 재배치 가능한 바이너리 안에 함수 이름을 메타데이터 형태로 생성하도록 수정
    • 만약 프로그램이 라이브러리 함수를 호출한다면 라이브러리 함수 이름을 외부 참조(external reference)로 생성
    • 반면 라이브러리 함수를 정의하는 프로그램이라면 컴파일러는 해당 이름을 외부 정의(external definition)로 생성
    • 이렇게 하여 외부 정의 에 링크시킬 수 있게 됨
    • 이렇게 링킹 로더(linking loader)가 탄생

4. 링커

  • 링킹 로더의 등장으로 프로그래머는 프로그램을 개별적으로 컴파일하고 로드할 수 있는 단위로 분할할 수 있게 되었다.
  • 하지만, 프로그램은 훨씬 커지게 되며 링킹 로더가 너무 느려졌다.

    링킹 로더가 프로그램 하나를 로드하는 데만 한 시간 이상 걸리게 되었다. (자기테이프 사용)

  • 마침내 로드와 링크가 두 단계로 분리
    • 프로그래머가 느린 부분 즉, 링크 과정을 맡음
    • 링커 라는 별도의 애플리케이션으로 해당 작업을 처리하도록 만듦
    • 링커는 링크가 완료된 재배치 코드를 만들어 주어 로더의 로딩 과정이 아주 빨라짐
    • 한번 만들어둔 실행 파일은 언제라도 빠르게 로드 할 수 있게 되었다.

5. 무어의 법칙

  1. 1980년대 소스 모듈은 .c파일에서 .o파일로 컴파일 후 링커로 전달되어 빠르게 로드될 수 있는 형태의 실행 파일로 만들어짐
  2. 각 모듈을 컴파일 하는 시간은 상대적으로 빠르지만 전체 모듈을 컴파일하는 일은 꽤 시간이 걸림
  3. 1980년대 후반에 들어서자 디스크는 작아졌으며 RAM의 용량은 커졌다. 컴퓨터 메모리는 저렴해짐
  4. 1990년대 후반이 되자, 프로그램을 성장시키는 속도보다 링크 시간이 줄어드는게 더 빨라지기 시작함.
  5. 이렇게 Active X와 공유 라이브러리 시대가 열리고 .jar파일 등장

결론: 이 책에서의 컴포넌트

런타임에 플러그인 형태로 결합할 수 있는 동적 링크 파일

컴포넌트 응집성

이 클래스를 어느 컴포넌트에 포함시켜야 할까?

해당 장에서는 컴포넌트 응집성과 관련된 세 가지 원칙을 논의한다.

  • REP(Reuse/Release Equivalence Principle): 재사용/릴리스 등가 원칙
  • CCP(Common Closure Principle): 공통 폐쇄 원칙
  • CRP(Common Reuse Principle): 공통 재사용 원칙

1. REP: 재사용/릴리즈 등가 원칙

재사용 단위는 릴리즈 단위와 같다.

2. CCP: 공통 폐쇄 원칙

동일한 이유로 동일한 시점에 변경되는 클래스를 같은 컴포넌트로 묶어라. 서로 다른 시점에 다른 이유로 변경되는 클래스는 다른 컴포넌트로 분리하라

3. CRP: 공통 재사용 원칙

컴포넌트 사용자들을 필요하지 않는 것에 의존하게 강요하지 말라

컴포넌트 결합