[Clean Architecture] 17장. 경계: 선 긋기
|
Introduction
- 소프트웨어 아키텍처는 선을 긋는 기술이며, 이러한 선을 경계라고 부름
- 경계는 소프트웨어 요소를 서로 분리하고, 경계 한편에 있는 요소가 반대편에 있는 요소를 알지 못하도록 막음
- 선 중 일부는 프로젝트 수명 중 아주 초기에, 심지어 코드가 전혀 작성되기 전에 그어지며, 어떤 선은 매우 나중에 그어짐
- 초기에 그어지는 선들은 가능한 한 오랫동안 결정을 연기시키기 위해, 그래서 이들 결정이 핵심적인 업무 로직을 오염시키지 못하게 만들려는 목적으로 쓰임
- 아키텍트의 목표는 필요한 시스템을 만들고 유지하는 데 드는 인적 자원을 최소화하는 것
- 그렇다면 인적 자원의 효율을 떨어뜨리는 요인은?
- 바로 결합 coupling
- 특히 너무 일찍 내려진 결정에 따른 결합
- 어떤 종류의 결정이 이른 결정일까?
- 바로 시스템의 업무 요구사항, 즉 유스케이스와 아무런 관련이 없는 결정
- 프레임워크, 데이터베이스, 웹 서버, 유틸리티 라이브러리, 의존성 주입에 대한 결정 등
- 좋은 시스템 아키텍처란 이러한 결정이 부수적이며, 결정을 연기할 수 있는 아키텍처
- 좋은 시스템 아키텍처는 이런 결정에 의존하지 않음
- 좋은 시스템 아키텍처는 이러한 결정을 가능한 한 최후의 순간에 내릴 수 있게 해주며, 결정에 따른 영향이 크지 않게 만듦
두 가지 슬픈 이야기
- P 회사
- 아키텍트가 너무 이르게 결정을 내림으로써 개발 비용을 엄청나게 가중시킨 사례
- W 사
- SOA를 약속하는 일련의 도구들을 너무 일찍 채택하여 적용했다는 사실
- 즉, 거대한 일련의 도메인 객체 서비스를 너무 이른 시기에 채택함
FitNesse
- 필자의 성공 사례
- 개발 초기에 업무 규칙과 데이터베이스 사이에 경계선을 그음
- 경계선을 긋는 행위는 결정을 늦추고 연기하는 데 도움이 되었고, 궁극적으로 시간을 엄청나게 절약해주었으며, 골치를 썩지 않게 해줌
- 이것이 좋은 아키텍처라면 반드시 해야 하는 일
어떻게 선을 그을까? 그리고 언제 그을까?
- 관련이 있는 것과 관련이 없는 것 사이에 선을 그음
- 데이터베이스는 업무 규칙이 간접적으로 사용할 수 있는 도구
- 업무 규칙은 스키마, 쿼리 언어, 또는 데이터베이스와 관련된 나머지 세부사항에 대해 어떤 것도 알아서는 안 됨
- 업무 규칙이 알아야 할 것은 데이터를 가져오고 저장할 때 사용할 수 있는 함수 집합이 있다는 사실이 전부
- 이러한 함수 집합을 통해서 우리는 데이터베이스를 인터페이스 뒤로 숨길 수 있음
- 이 도표에서 클래스와 인터페이스는 상징적
- 실제 애플리케이션에서는 업무 규칙과 관련된 수많은 클래스들, 데이터베이스 인터페이스와 관련된 수많은 클래스들, 그리고 데이터베이스 접근을 구현한 수많은 구현체가 존재함
- 그렇더라도 이 모두는 이 패턴을 거의 동일하게 따름
- 경계선은 어디에 있는가?
- 상속 관계를 횡단하면서 Database Interface 바로 아래에 그어짐
- Database Access 에서 출발하는 두 화살표에 주목
- Database Access 클래스로부터 바깥으로 향함
- 즉, 이 도표에서 Database Access 가 존재한다는 사실을 알고 있는 클래스는 없다는 뜻
- 이제 조금 물러나서 보자
- 많은 업무 규칙이 포함된 컴포넌트, 데이터베이스와 데이터베이스 접근 클래스를 포함하는 컴포넌트를 살펴보려고 함
- 화살표 방향에 주목
- Database 는 Business Rules 에 대해 알고 있음
- Business Rules 은 Database 에 관해 알지 못함
- 이는 Database Interface 클래스는 Business Rules 컴포넌트에 속하며, Database Access 클래스는 Database 컴포넌트에 속한다는 사실을 의미
- 이 선의 방향이 중요함
- Business Rules 에 있어 Database 는 문제가 되지 않지만, Database 는 Business Rules 없이는 존재할 수 없다는 사실을 이 방향을 통해서 알 수 있음
- 이러한 사실이 이상하게 보인다면 하나만 기억하자
- Database 컴포넌트는 Business Rules 가 만들어 낸 호출을 데이터베이스의 쿼리 언어로 변환하는 코드를 담고 있음
- Business Rules 에 대해 알고 있는 코드는 바로 이 변환 코드
- 데이터베이스 컴포넌트는 다양한 구현체로 교체될 수 있으며, Business Rules 은 조금도 개의치 않음
- 이와 같은 사실은 데이터베이스에 대한 결정은 연기할 수 있으며, 데이터베이스를 걸정하기에 앞서 업무 규칙을 먼저 작성하고 테스트하는 데 집중할 수 있음을 의미
입력과 출력은?
- 매우 중요한 원칙, 입력과 출력은 중요하지 않다는 사실
- 인터페이스는 모델에 있어 중요하지 않음, 중요한 것은 업무 규칙
플러그인 아키텍처
- 데이터베이스와 GUI 에 대해 내린 두 가지 결정을 하나로 합쳐서 보면 컴포넌트 추가와 관련한 일종의 패턴이 만들어짐
- 이 패턴은 시스템에서 서드 파티 플러그인을 사용할 수 있게 한 바로 그 패턴과 동일
- 사실 소프트웨어 개발 기술의 역사는 플러그인을 손쉽게 생성하여, 확장 가능하며 유지보수가 쉬운 시스템 아키텍처를 확립할 수 있게 만드는 방법에 대한 이야기
- 선택적이거나 또는 수많은 다양한 형태로 구현될 수 있는 나머지 컴포넌트로부터 핵심적인 업무 규칙은 분리되어 있고, 또한 독립적임
- 플러그인 형태로 고려되었기에 다양한 기술을 적용할 수 있음
플러그인에 대한 논의
- 시스템을 플러그인 아키텍처로 배치함으로써 변경이 전파될 수 없는 방화벽을 생성할 수 있음
- 경계는 변경의 축이 있는 지점에 그어짐
- 경계의 한 쪽에 위치한 컴포넌트는 경계 반대편의 컴포넌트와는 다른 속도로, 그리고 다른 이유로 변경됨
- 이 역시도 순전히 단일 책임 원칙에 해당함
- 단일 책임 원칙은 어디에 경계를 그어야 할지를 알려줌
결론
- 소프트웨어 아키텍처에서 경계선을 그리려면 먼저 시스템을 컴포넌트 단위로 분할해야 함
- 일부 컴포넌트는 핵심 업무 규칙에 해당함
- 나머지 컴포넌트는 플러그인으로, 핵심 업무와는 직접적인 관련이 없지만, 필수 기능을 포함함
- 그런 다음 컴포넌트 사이의 화살표가 특정 방향, 즉 핵심 업무를 향하도록 이들 컴포넌트의 소스를 배치함
- 이는 의존성 역전 원칙과 안정된 추상화 원칙을 응용한 것임을 눈치챌 수 있어야 함
- 의존성 화살표는 저수준 세부사항에서 고수준의 추상화를 향하도록 배치됨