1.아키텍처가 지원해야 하는 것
(1) 유스케이스
- 비즈니스 업무규칙 중 애플리케이션을 통해 처리해야 업무사항을 뜻한다.
- 시스템의 최고 정책은 비즈니스의 수익을 내거나 비용을 줄일 수 있는 업무규칙이다. 이러한 내용은 컴퓨터로 구현을 하는 것과 상관없이 수동으로도 진행해도 전혀 문제가 없는 것들이어야 한다.
- 은행의 이자율 정책이 있다면
- 유스케이스는 은행 대출 자동화 시스템 정책.
- 시스템 아키텍처는 반드시 유스케이스를 통해 시스템의 의도를 파악할 수 있도록 지원해야 한다.
- 개발자가 유스케이스를 보고 시스템이 어떤 용도의 애플리케이션인지 파악할 수 있어야 한다.
(2) 운영
- 시스템 아키텍처는 운영정책과 관련된 각 유스케이스에 걸맞는 처리량과 응답시간을 보장해야 한다.
- 또한 운영정책 변경될 수 있는 가능성을 열어두어야 한다.
- 예를 들어 신규 미술관을 짓는다고 생각해보자.
- 신규 미술관을 이용하는 관객수가 하루 천명이고, 전시 할 수 있는 작품이 100점이라면 미술관 도면(시스템 아키텍처)는 반드시 이러한 운영 작업을 허용할 수 있는 형태로 도면을 구조화해야 한다.
- 그런데 미술관을 운영하다 보면 운영 방식을 수정해야 될 경우가 생길 수 있다. 동시에 하나의 전시가 아닌 두개의 전시를 해야 한다거나, 미술관을 파티 장소로 임시 변경해서 운영해야 될 수도 있다. 시스템 아키텍처는 그러한 가능성까지도 고려해야 한다.
(3) 개발
- 아키텍처는 개발환경을 지원하는 데 있어 핵심적인 역할을 수행한다.
- 이를 위해 아키텍처는 격리되고 독립적으로 개발 가능한 컴포넌트 단위로 시스템을 분할하여 각 팀이 독립적으로 행동하기 편한 환경을 제공할 수 있어야 한다.
(4) 배포
- 아키텍처는 컴포넌트 분리와 의존성 구조 관리를 통하여 배포 용이성을 결정하는 데 중요한 역할을 하며, 즉각적인 배포를 할 수 있도록 해야 한다.
2.선택사항 열어놓기
- 좋은 아키텍처는 선택사항을 열어 둠으로서, 향후 시스템에 변경이 필요할 때 어떤 방향으로든 쉽게 변경할 수 있도록 한다.
- 프레임워크, 데이터베이스, 웹서버 등과 같은 세부 기술에 독립적이어서는 안된다는 뜻으로 이해함.
3.계층 결합 분리
- 아키텍트가 시스템의 모든 유스케이스를 알 수 없다. 그러나 시스템의 기본적인 의도는 알 수 있다.
- 이를 위해 단일 책임 원칙과 공통 폐쇄 원칙을 적용하여 그 의도의 맥락에 따라서 다른 이유로 분리되는 것들은 분리하고 동일한 이유로 변경되는 것들은 묶는다. 아래와 같은 수평 계층으로 결합 및 분리할 수 있다.
- UI 계층
- 업무 로직 계층
- 애플리케이션에 특화된 업무 규칙( 유스케이스 인가?)
- 애플리케이션과는 독립적인 업무 규칙( 엔티티인가? )
- 데이터베이스 계층
4.유스케이스 결합 분리
이미지 출처 : https://velog.io/@jiffydev/Clean-Architecture-5부-아키텍처
- 주문 입력 시스템의 유스케이스
- 유스케이스 1 : 주문 추가
- 유스케이스 2 : 주문 삭제
- 이 둘은 분명 다른 케이스 이기 때문에 각각 다른 속도와 이유로 변경될 수 있다. → 분리 시키자.
- 유스케이스는 시스템의 수평적인 계층을 가로지르로도록 자른 수직으로 좁다란 조각으로 볼 수 있다.
- 주문 추가 유스케이스를 구현하기 위해선 UI, 업무 로직, 데이터베이스 기능의 일부를 사용해야 하기 때문이다.
- 이렇게 우리는 시스템을 수평적 계층으로 분할하면서 동시에 해당 계층을 가로지르는, 얇은 수직적인 유스케이스로 시스템을 분할할 수 있다.
- 시스템에서 서로 다른 이유로 변경되는 요소들의 결합을 분리(UI - 업무 로직 - 데이터베이스)하면 기존 요소에 지장을 주지 않고도 새로운 유스케이스를 계속해서 추가할 수 있게 된다. 또한 유스케이스를 뒷받침하는 UI와 데이터베이스를 서로 묶어서 각 유스케이스가 UI와 데이터베이스의 서로 다른 관점을 사용하게 되면 새로운 유스케이스를 추가하더라도 기존 유스케이스에 영향을 주는 일이 거의 없을 것이다.
5.결합 분리 모드
- 결합 분리는 운영에 도움이 된다.
- 높은 처리량을 보장해야 하는 유스케이스와 낮은 처리량으로도 충분한 유스케이스가 분리됨.
- UI와 데이터베이스가 업무규칙과 분리되어 있다면 UI와 데이터베이스는 업무 규칙과는 다른 서버에서 실행 될 수도 있음.
- 그러나 운영의 이점을 살리기 위해선 적절한 결합 분리 모드를 선택해야 한다.
- 소스 수준 분리 모드
- 소스 코드 모듈 사이의 의존성을 제어 할 수 있음.
- 모든 컴포넌트가 같은 주소 공간에서 실행되고, 서로 통신할 대는 간단한 함수를 호출. 컴퓨터 메모리에는 하나의 실행 파일만 로드됨. → 모노리틱 구조라고도 부름.
- 배포 수준 분리 모드 - 안드로이드 스튜디오 멀티 모듈
- jar파일, DLL, 공유 라이브러리 같은 배포 가능한 단위들 사이의 의존성을 제어할 수 있음.
- 모듈의 소스 코드가 변하더라도 다른 모듈을 재빌드하거나 재배포하지 않도록 만들 수 있음.
- 여전히 많은 컴포넌트가 같은 주소 공간에 상주하며, 단순한 함수 호출을 통해 통신 가능.
- 혹은 어떤 컴포넌트는 동일한 프로세서 내 다른 프로세스 간 통신, 소켓, 또는 공유 메모리를 통해 통신 할 수 있음.
- 결합이 분리된 컴포넌트가 jar 파일, Gem 파일, DLL과 같이 독립적으로 배포할 수 있는 단위로 분할되어 있다는 점이다.
- 서비스 수준 분리 모드
- 의존하는 수준을 데이터 구조 단위까지 낮출 수 있고, 순전히 네트워크 패킷을 통해서만 통신하도록 만들 수 있다.
- 모든 실행 가능한 단위는 소스와 바이너리 변경에 대해 서로 완전히 독립적이게 된다.
- 예 : 서비스 또는 마이크로서비스
- 프로젝트 초기 단계는 어떤 모드가 최선인지 알기 어렵다. 프로젝트가 성숙해갈수록 최적인 모드가 달라질 수도 있다.
6.중복
유스케이스 수직 분리 및 계층 분리시 비슷해 보이는 경우들을 통합하고 싶다는 유혹을 받게 된다. 그럴 때 진짜 중복과 가짜 중복의 차이를 생각하고 그 유혹으로부터 벗어나야 한다.
- 진짜 중복 : 인스턴스가 변경되면 동일한 변경을 그 인스턴스의 모든 복사본에 반드시 적용해야 하는 경우
- 가짜 중복 : 중복으로 보이는 두 코드 영역 → 각자의 경로로 발전한다면 진짜 중복이 아님. 몇년이 지나면 완전히 다른 코드가 되어 있을 것이기 때문.