- 아키텍트의 목표는 필요한 시스템을 만들고 유지하는 데 드는 인적 자원을 최소화하는 것이라는 사실.
- 인적 자원의 효율을 떨어 뜨리는 요인은? 너무 일찍 내려진 결정에 따른
결합
(coupling)임 - 시스템의 업무 요구사항, 즉 유스케이스와는 아무런 관련이 없는 결정 (프레임워크, 데이터베이스, 웹 서버, 유틸리티 라이브러리, 의존성 주입에 대한 결정 등)은 가능한한 최후의 순간까지 연기해야 함
- 경계는 변경의 축이 있는 지점에 그어진다. 경계의 한쪽에 위치한 컴포넌트는 경계 반대편의 컴포넌트와는 다른 속도로, 그리고 다른 이유로 변경된다(CCP — 공통 폐쇄 원칙)
소프트웨어 아키텍처에서 경계선을 그리려면 먼저 시스템을 컴포넌트 단위로 분할해야 한다.
일부 컴포넌트는 핵심 업무 규칙에 해당하고 나머지 컴포넌트는 플러그인으로, 핵심 업무와는 직접적인 관련이 없지만 필수 기능을 포함한다. 그런 다음 컴포넌트 사이의 화살표가 특정 방향, 즉 핵심 업무를 향하도록 이들 컴포넌트의 소스를 배치한다.
이는 의존성 역전원칙과 안정된 추상화 원칙을 응용한 것이다.
경계
- 소프트웨어 아키텍처는 선을 긋는 기술이며, 이러한 선을 경계라고 부름. 경계는 소프트웨어 요소를 서로 분리하고, 경계 한편에 있는 요소가 반대편에 있는 요소를 알지 못하도록 막는다.
- 아키텍트의 목표는 필요한 시스템을 만들고 유지하는 데 드는 인적 자원을 최소화하는 것이라는 사실을 상기하자. 인적 자원의 효율을 떨어뜨리는 요인은 바로
결합
(coupling) 이다
- 업무 규칙, 업무 요구사항, 유스케이스와 관련이 없는 세부사항 사이에는 경계선이 그어져야 한다.
- 세부사항 : 프레임워크, 데이터베이스, 웹 서버, 유틸리티 라이브러리, 의존성 주입에 대한 결정 등
- 예: 업무규칙 ↔ 데이터베이스. 업무규칙 → UI
아키텍처 실패 사례
저자는 3-티어는 아키텍처가 아니라고 한다. 3-티어는 사실 망 구성방식(topology)이고 좋은 아키텍처라면 틀림없이 미루기 위해 고군 분투 해야만 하는 종류의 결정이다. 라고 말하고 있다 내 생각으로는 Presentation layer, application layer, Data Layer로 구성의 순서를 정해버리기 때문에 망 구성방식이라고 한 것이 아닐까 싶다. 저자가 이 책에서 꾸준하게 말하는 아키텍처에서 중요한 부분은 핵심 정책을 위해 세부사항의 결정을 연기하라는 것이고 이를 위해서는 컴포넌트 사이의 의존성 규칙을 지키는 것이 중요하다. 컴포넌트 사이의 의존성 규칙에 따라 해당 순서는 바뀔 수도 있는 것 이기에 아키텍처는 아니라고 말하지 않았을까 싶다.
- P사의 예시 : 자바 진영 사람은 머릿속에서 서버 팜이 춤추는 이상을 꿈꾸었기에, 3-티어로 구성된 리치 아키텍처를 채택했고, 서버 팜을 통해 분산하고자 했음(GUI를 위한 서버, 미들웨어 서버, 데이터베이스 서버로). 이렇게 모든 도메인 객체가 세 가지 인스턴스를 가져야 한다고 너무 이른 결정을 내린 것으로 인해 간단한 새로운 기능 추가에도 데이터 이동에 따른 메시지 프로토콜 네개 설계, 프로토콜 송,수신부에 따른 핸들러 8개 필요 등, 개발 비용이 매우 늘어나게 됨
- W사의 예시: 업무와 관련된 서로 다른 모든 ‘객체’들로 구성된 거대한 도메인 모델을 생성하고 이들 도메인 객체를 관리하기 위한 서비스들의 묶음을 설계하여 개발자를 지옥의 길로 밀어 넣었음. 간단한 기능 하나 추가를 하려면 각 서비스 사이의 결합으로 인해 엄청난 양의 변경이 필요하다. 그리고 변경에 영향받는 모든 것을 다시 배포해야 한다.
위의 두 가지 사례 모두 SOA와 서버 분산이라는 세부 사항을 너무 일찍부터 채택하여 생긴 문제다.
아키텍처 성공 사례
- 저자가 아들과 직접 만든 FitNese 라는 위키 페이지를 만드는 프로젝트의 이야기임
- 해당 프로젝트에서 초기에 FitNesse의 요구에 특화된 그들만의 웹 서버를 직접 작성하자고 결론 내림. 그로 인해 어떤 웹 프레임워크를 사용할지에 대한 결정을 훨씬 나중으로 연기할 수 있었음
- 초기에 내린 또다른 결정은 데이터베이스에 대해 고민하지 말자는 것. 어떤 데이터베이스를 사용하더라도 상관없는 형태로 설계 함으로써 의도적으로 데이터베이스에 대한 결정을 연기함
- 이렇게 결정을 연기함으로써 데이터베이스에 대한 부분은 스텁, 혹은 플랫파일로 구현체를 만들고 다른 부분의 기능들에 초점을 맞춰 차례대로 작성할 수 있었음!
- 개발 초기에 업무 규칙과 데이터베이스 사이에 경계선을 그음으로, 업무 규칙은 데이터 접근 메서드 외에는 데이터베이스에 대해 아무것도 알지 못하게 되었고 1 년이 훨씬 넘는 기간 동안 데이터베이스를 선택하고 구현하는 일을 연기할 수 있었음
- 18개월이라는 기간 동안 운영할 데이터베이스가 없다는 사실은 스키마와 관련된 문제들, 쿼리 문제들, 데이터베이스 서버 문제들, 패스워드 문제들, 접속시간과 관련된 문제들, 그리도 데이터베이스를 작동시킬 때 추하게 고개를 드는 여타 모든 고약한 문제가 없었다는 사실을 뜻한다. 또한 테스트를 느리게 만드는 데이터베이스가 없으니 테스트도 더 빨리 돌릴 수 있다.
어떻게 선을 그을까? 그리고 언제 그을까

- 위와 같은 상황에서 BusinessRules는 어떠한 Database 구현체를 사용해도 전혀 상관이 없다. ⇒ 데이터베이스에 대한 결정을 연기할 수 있음

- 화살표의 방향을 주목해보면 Database는 BusinessRules에 대해 알고있지만 BusinessRules는 Database에 관해 알지 못한다.
- 이는 DatabaseInterface 클래스는 BusinessRules 컴포넌트에 속하며, DatabaseAccess 클래스는 Database 컴포넌트에 속한다는 사실을 의미함
- 이러한 사실이 이상하게 보인다면 하나만 기억하자. Database 컴포넌트는 BusinessRules가 만들어 낸 호출을 데이터베이스의 쿼리 언어로 변환하는 코드를 담고 있다. BusinessRules에 대해 알고 있는 코드는 바로 이 변환 코드다.
- 두 컴포넌트 사이에 이러한 경계선을 그리고 화살표의 방향이 BusinessRules를 향하도록 만들었으므로, BusinessRules에서는 어떤 종류의 데이터베이스도 사용할 수 있음을 알 수 있다. Database 컴포넌트는 다양한 구현체로 교체될 수 있으며, BusinessRules는 조금도 개의치 않는다.
입력과 출력은?
- 개발자와 고객은 종종 시스템이 무엇인지에 대해 혼란스러워 한다. GUI를 보고선 GUI가 시스템이라고 생각하곤 한다. 그러나 이들은 매우 중요한 원칙을 깨닫지 못했다.
입력과 출력은 중요하지 않다는 사실이다.
- 이 원칙은 처음에는 이해하기 힘들다. 우리는 시스템의 행위를 입출력이 지닌 행위적 측면에서 생각하는 경향이 있다. 예를 들어 비디오 게임에서 사용자 경험은 인터페이스에 의해 좌우되지만 이러한 인터페이스 뒤에는 인터페이스를 조작하는 모델(데이터 구조와 함수로 구성된 정교한 집합)이 존재한다는 사실을 잊어버린다.
- 더 중요한 사실은 모델은 인터페이스를 전혀 필요로 하지 않는다는 점. 게임이 화면에 전혀 출력되지 않더라도 모델은 게임에서 발생하는 모든 이벤트를 모델링하며 주어진 역할을 충실하게 수행한다.
인터페이스는 모델에게 있어 중요하지 않다. 중요한 것은 업무 규칙이다.

플러그인 아키텍처
- 데이터베이스와 GUI에 대해 내린 두 가지 결정을 하나로 합쳐서 보면 컴포넌트 추가와 관련한 일종의 패턴이 만들어진다. 이 패턴은 시스템에서 서드파티 플러그인을 사용할 수 있게 한 바로 그 패턴과 동일하다.
- 소프트웨어 개발기술의 역사는 플러그인을 손쉽게 생성하며, 확장가능하며 유지보수가 쉬운 시스템 아키텍처를 확립할 수 있게 만드는 방법에 대한 이야기다. 선택적 이거나 또는 수많은 다양한 형태로 구현될 수 있는 나머지 컴포넌트 로부터 핵심적인 업무 규칙은 분리되어 있고, 또한 독립적이다.

- 위 설계에서 사용자 인터페이스(GUI)가 플러그인 형태로 고려 되었기에 수많은 종류의 사용자 인터페이스를 플러그인 형태로 연결할 수 있게 된다. (웹 기반일수도, 클라이언트. 서버 기반, SOA 나 콘솔기반, 임의의 어떤 사용자 인터페이스 기술도 가능)
- 데이터베이스도 마찬가지로 임의의 어떤 종류의 데이터베이스 기술로도 대체할 수 있다.