정의
계층 아키텍처는 소프트웨어를 계층으로 나누고 계층 사이의 사용 관계에 엄격한 순서를 두는 구조다. 각 계층은 가상 기계(virtual machine) — 다른 소프트웨어가 구현 방식을 몰라도 쓸 수 있는 응집된 서비스 묶음 — 를 이룬다.[1]
발상의 뿌리는 오래됐다. 1968년 Dijkstra는 프로그램을 계층으로 묶고 한 계층의 프로그램이 인접한 계층하고만 통신하게 하는 운영체제 구성을 제시하며, 그런 조직이 주는 개념적 일관성과 그로 인한 개발·유지보수의 이점을 지적했다.[2] 계층 뷰는 소프트웨어 아키텍처에서 가장 흔히 쓰이는 뷰가 됐지만, 흔한 만큼 정의가 헐겁고 오해도 많다.[1]
사용 허용 관계
계층을 계층이게 하는 것은 그림의 배치가 아니라 계층 사이에 놓인 사용 허용(allowed-to-use) 관계다. (A, B)가 이 관계에 있으면 “B는 A 아래에 있다”고 말하며, 이는 A의 구현이 B가 제공하는 가상 기계의 공개 설비를 써도 된다는 뜻이다.[1] 여기서 쓴다는 것은 Parnas의 사용 관계다 — A의 정확성이 B의 올바른 구현에 의존하면 A는 B를 사용한다.
이 관계는 호출 관계와 다르다. 어떤 프로그램은 상대를 호출하지 않고도 사용할 수 있고, 반대로 호출하면서도 사용하지 않을 수 있다. 오류가 났을 때 클라이언트가 넘겨준 이름의 프로그램을 부르도록 명세된 프로그램은 그 오류 처리기가 무엇을 하든 상관하지 않으므로, 처리기가 위 계층에 있어도 문제가 되지 않는다.
계층 방식마다 세부는 다르다. 바로 아래 계층만 쓰게 하는 것도 있고 더 아래 계층까지 허용하는 것도 있다. 그러나 위 계층의 설비를 제한 없이 쓰게 하는 방식은 계층이라 할 수 없다. 사용은 원칙적으로 아래로 흐르고, 불가피한 상향 사용은 예외(bridging)로 따로 문서화해야 하며, 그런 예외가 많다는 것은 구조가 잘못됐다는 신호다.
층 그림과 계층 구조
위아래로 자유롭게 서로를 쓰는 부분들을 위아래로 배치해 놓고 계층이라 부르는 그림이 흔하다. 무제한 상향 사용은 계층이 주는 이점을 무너뜨리므로 그런 구조는 계층이 아니다.[1]
수정 가능성과 이식성
계층이 겨냥하는 품질은 수정 가능성과 이식성이다. 인터페이스를 건드리지 않는 하위 계층의 변경은 어떤 상위 계층도 바꾸지 않고, 아래에 요구하는 설비가 그대로인 상위 계층의 변경은 아래 계층에 닿지 않는다 — 인터페이스를 건드리지 않는 변경은 한 계층 안에 갇힌다. 그래서 계층은 재사용과 이식의 단위가 되며, POSIX를 지키는 운영체제라면 응용 수준 소프트웨어를 바꾸지 않고 갈아 끼울 수 있다는 것이 그 전형적인 예다.[1]
계층의 위아래는 관심사의 기울기이기도 하다. 아래 계층일수록 쓸 수 있는 것이 하드웨어에 가까운 것뿐이므로 컴퓨터·통신 채널·분산 기구·프로세스 디스패처에 관한 지식이 설계에 들어오고, 그 지식은 위에서 도는 응용이 무엇이든 달라지지 않는다. 위 계층은 아래 계층이 그 문제를 떠맡아 준 덕분에 하드웨어와 무관해질 수 있어, 플랫폼이 바뀌어도 함께 바뀔 이유가 없다.
하드웨어 추상화
장치별 차이를 감추는 계층을 따로 두는 것이 이 원리의 흔한 적용이다. Android의 하드웨어 추상화 계층(HAL)은 하드웨어 공급사가 구현할 표준 인터페이스를 정의하는 추상화 계층이며, 공급사는 상위 계층의 코드를 건드리거나 바꾸지 않고도 장치 고유의 저수준 기능을 구현할 수 있다.[3] 인터페이스를 기술하는 언어는 AIDL(Android Interface Definition Language)이고, Android 13에서 앞선 HIDL은 폐기됐다. 대상 릴리스가 요구하는 HAL 구현은 vendor 파티션에 둔다.
차량 제어기 소프트웨어가 이 원리를 어떤 계층 구성으로 구체화했는지는 AUTOSAR Classic 플랫폼에서 다룬다. 재사용을 겨냥해 응용 구조를 조립하는 컴포넌트 기반 아키텍처는 계층 구조와 배타적이지 않다.