좋은 시스템일수록 저수준 컴포넌트가 고수준 컴포넌트에 의존하도록 설계되어 있다.
수준
수준은 입력과 출력까지의 거리이다. 시스템의 입력과 출력과의 거리가 멀어질수록 정책의 수준은 높아진다. 입력과 출력을 다루는 정책은 시스템의 최하위 수준에 위치해야 한다.
따라서 고수준의 정책(비즈니스 로직)이 입출력 시스템에 영향을 받게 되어 있다면 잘못 설계된 경우일 가능성이 크다. 아래의 코드가 그렇다.
function encrypt() {
while (true) {
writeChar(translate(readChar()));
}
}
고수준의 encrypt
함수가 저수준(입력과 출력을 담당하는)의 writeChar
와 readChar
에 의존성을 가지고 있다. 이러한 경우 입출력 시스템의 정책에 변화가 생긴다면 encrypt
함수도 변화되어야 할 가능성이 있다. 따라서 Encrypt 클래스와 동일 컴포넌트 상에 읽고 쓰는 인터페이스가 존재하고, 이를 외부에서 구현해서 사용하도록 하여 경계 선을 명확히 그어야 한다.
정책을 컴포넌트로 묶는 기준은 정책이 변경되는 방식에 달려있다. 단일 책임 원칙과 공통 폐쇄 원칙에 따라 동일한 이유로 동일한 시점에 변경되는 정책은 함께 묶인다.