소프트웨어 아키텍처는 선을 긋는 기술이며, 저자는 이러한 선을 경계라고 부른다.
경계의 역할
- 한편에 있는 요소가 반대편에 있는 요소를 알지 못하도록 막는다.
- 경계는 프로젝트 수명 중 초기에 그어지는 경우도 있고, 어떤 경우는 매우 나중에 그어지는 것도 있다.
- 초기에 그어지는 선들은 가능한 한 오랫동안 결정을 연기하여, 핵심적인 업무 로직을 오염시키지 못하게 만들려는 목적이 있다.
경계와 아키텍트의 목표
필요한 시스템을 만들고 유지하는 데 드는 인적 자원을 최소화하는 것.
- 인적 자원의 효율을 떨어뜨리는 요인은 결합이다. 특히 너무 일찍 내려진 결정에 따른 결합이다.
- 시스템의 업무 요구사항(유스케이스)와 관련없는 프레임워크, 데이터베이스, 웹 서버, 유틸리티 라이브러리, 의존성 주입에 대한 결정 등.
- 좋은 시스템 아키텍처는 이러한 선택사항에 의존하지 않는다. 따라서 가능한한 취후의 순간에 결정을 내릴 수 있게 해주며 결정에 따른 영향이 크지 않다.
선택사항의 빠른 결정에 따른 후유증
- 개발 당시에 유행하는 프레임워크나 아키텍처를 이르게 채택.
- 해당 기술 혹은 구조에 강하게 coupling(결합)된 시스템이 개발됨.
- 이후 변하는 유행에 대응하는데 상당한 인적, 시간적, 경제적 비용이 발생.
선을 긋는 법
관련 있는 것과 없는 것 사이에 선을 긋는다.
Ex) 단일 책임 원칙을 떠올려보자.
- GUI는 업무 규칙과 관련이 없기 때문에 선이 있어야한다.
- 데이터베이스는 GUI와 관련이 없기 때문에 선이 있어야한다.
- 데이터베이스는 업무 규칙과 관련이 없으므로 선이 있어야한다.
플러그인 아키텍처
“소프트웨어 개발 기술의 역사는 플러그인을 손쉽게 생성하여, 확장가능하며 유지보수가 쉬운 시스템 아키텍처를 확립할 수 있게 만드는 방법에 대한 이야기다.”
- 선택적이거나 다양한 형태로 구현될 수 있는 나머지 컴포넌트로 부터 핵심적인 업무규직은 분리되어 있고, 또한 독립적이다.
- 이 설계에서는 사용자 인터페이스는 플러그인 형태로 고려되었으므로 다양한 GUI를 플러그인 형태로 연결할 수 있게 된다.
- 데이터베이스도 다양한 종류의 기술로 대체 가능하다. (핵심업무 로직은 MySQL,Oracle, NoSQL DB그 어떤 것과도 관련이 없다.)
- 시스템을 플러그인 아키텍처로 배치한다면 변경이 전파될 수 없는 방화벽을 생성할 수 있다.
(GUI 변경이 업무규칙에 영향을 줄 수 없음.)
경계 횡단하기
1) 단일체
- 아키텍처 경계 중에서 가장 단순, 물리적으로 엄격하게 구분되지 않는 형태.(소스수준의 분리 모드)
- 하나의 실행파일이다.
- 배포관점에서 경계가 드러나지 않음.
- 하나의 실행파일이지만 내부의 다양한 컴포넌트를 만드는 과정을 독립적으로 수행할 수 있게 하는 일은 매우 중요하다.
- 다형성을 활용하여 결합도를 적절히 분리.(객체지향)
- 컴포넌트간(경계) 통신은 매우 빠르고 값싸다.(단순 함순 호출)
2) 배포형 컴포넌트
- 물리적으로 아키텍처 경계를 나타낼 수 있는 방법중 가장 단순한 형태 -> 동적 링크 라이브러리
- .Net의 DLL, 자바의 JAR, 루비의 Gem, UNIX의 공유 라이브러리.
- 해당 방식을 활용하면 따로 컴파일하지 않고 배포가능한 형태로 바로 사용이 가능하다. -> 배포 수준 결합 분리 모드
- 동일한 프로세서와 주소공간에 위치하므로 경계를 가로지르는 비용은 싸다.(단순 함수 호출)
3) 스레드
- 단일체와 배포형 컴포넌트 모두 스레드 활용이 가능하다.
- 스레드는 아키텍처 경계도 아니며 배포 단위도 아니다.
- 실행 계획과 순서를 체계화하는 방법에 가깝다.
4) 로컬프로세스
- 훨씬 강한 물리적형태를 띄는 아키텍처 경계.
- 주로 명령행이나 그와 유사한 시스템 호출을 통해 생성.
- 독립된 주소 공간에서 실행. (프로세스간 공유 메모리는 보안상 사용을 지양)
- 소켓, 메일박스, 메세지 큐와 같이 OS에서 제공하는 통신기능을 이용하여 서로 통신.
- 경계를 지나는 통신에는 OS호출, 데이터 마샬링 및 언마샬링, 프로세스간 context switching 등이 있음.
- 위 통신은 비싼편에 속하므로 통신이 빈번히 발생하지 않도록 신중히 제한해야한다.
5) 서비스
- 물리적인 형태를 띠는 가장 강력한 경계.
- 물리적 위치에 구애를 받지 않음.
- 서로 통신하는 두 서비스는 물리적으로 동일한 프로세서에 위치할 수도 있고 아닐 수도 있음.
(모든 통신이 네트워크를 통해 이뤄진다고 가정한다.) - 서비스 경계를 지나는 통신은 함수 호출에 비해 매우 느리다.
- 지연에 따른 문제를 고수준에서 처리할 수 있어야 한다.
- 저수준 서비스는 고수준 서비스에 플러그인 되어야한다.(고수준 서비스는 저수준 서비스에 대해서 알아서는 안됨!)
결론
- 소프트웨어 아키텍처에서 경계선을 그리려면 먼저 시스템을 컴포넌트 단위로 분할해야 한다.
- 일부 컴포넌트는 핵심 업무 규칙. 나머지 컴포넌트는 플러그인으로, 핵심업무와는 직접적 관련은 없지만 필수 기능을 포함.
- 컴포넌트 사이의 화살표가 핵심 업무를 향하도록 컴포넌트의 소스를 배치해야한다.
- 단일체를 제외한 대다수 시스템은 한 가지 이상의 경계 전략을 사용.
- 즉, 대체로 한 시스템 안에서도 통신이 빈번한 로컬 경계와 지연을 중요하게 고려해야 하는 경계가 혼합되어 있음.
'Design > Architecture' 카테고리의 다른 글
[Clean Architecture] 아키텍처 - 험블 객체 (Humble Object) (0) | 2021.12.28 |
---|---|
[Clean Architecture] 아키텍처 - 업무규칙 (Entity, Use case) (0) | 2021.12.23 |
[Clean Architecture] 아키텍처 - 독립성 (0) | 2021.12.13 |
[Clean Architecture] 아키텍처란? (0) | 2021.12.05 |
[Architecture 공부] CQRS에 대해서 알아보자. (0) | 2021.11.28 |