좋은 아키텍처를 위한 "선긋기"

JACKJACK·2023년 10월 15일
2
post-thumbnail

선긋기란?

소프트웨어 아키텍처는 선을 긋는 기술이며 이를 경계라고 부른다. 처음부터 그어지는 경계도 있는 반면 프로젝트 진행에 따라 그어지는 경계도 있다. 그래서 너무 일찍 선을 긋고 결정을 내려버리는 것을 지양해야 한다. 아키텍처는 유스케이스와는 아무 관련이 없는 프레임워크, 데이터 베이스, 웹 서버, 유틸리티 라이브러리 등의 결정에 의존하지 않도록, 결정을 최후에 순간에 내릴수 있도록 해줘야 한다. 그렇지 않으면 이 후 변동사항에 대해 유연하지 못한 시스템이 될 수 있고, 변동이 생길 때 엄청난 비용을 대가로 지불해야 할 수있다.

클린 아키텍처의 저자는 FitNesse 라는 프로그램을 만들며 18개월간 데이터베이스 없어 스키마, 쿼리, 데이터베이스 서버, 접속시간 문제 같은 부분에 시간을 쓰지 않고 테스트를 더빠르게 돌릴 수 있었다. 이렇게 경계선을 늦춰 막연히 생각했던 MySQL을 데이터 저장에 사용하기보다 단기적으로 더 합리적인 플랫 파일로 저장 할 수 있었고, 궁극적으로 시간을 엄청 절약시키는데 도움이 되었다고 한다.

그렇다면 어떻게 선을 그을까? 그리고 언제 그을까?

관련이 있는것과 없는것 사이에 선을 그으면 된다. 예시로 GUI와 업무 규칙과 데이터베이스는 각각 서로 관련이 없기에 선을 그어줘야 한다. 업무규칙과 데이터베이스는 언뜻보면 서로 떼어놓을 수 없는 관계로 보는 경우가 있는데 이는 잘못된 것이다, 데이터베이스는 업무규칙이 간접적으로 사용하는 도구에 불과하다. 업무규칙이 알아야 하는것은 데이터를 가져오고 저장할 때 사용할 수 있는 함수 집합이 있는 사실만 알면 된다.(데이터베이스는 뒤로 숨긴다.) 아래 그림이 그 예시이다.

그리고 이때 경계선은 다음과 같이 그을 수 있다. 경계선을 긋는 순간 도표에서 Database Access가 존재하는 사실을 아는 클래스는 없게 된다. 업무규칙이 Interface를 만들어 Database 컴포넌트를 다양한 교체될 수 있으며 , Business Rules는 전혀 개의치 않는다. 이렇게 데이터베이스의 결정을 연기할 수 있다.

입력과 출력은?

개발자와 고객은 GUI를 시스템으로 이해하는경우가 종종 있는데 이것은 아니며, 입력과 출력은 중요하지 않다. 중요한것은 업무규칙이며 다음 그림을 보면 이해할 수 있다. GUI가 Business Rules에 의존하며 GUI는 얼마든지 교체될 수 있고 GUI가 무엇으로 바뀌든 Business Rules는 전혀 개의치 않다. 또한 이러한 패턴은 서드파티 플러그인을 사용할 때도 사용되어 시스템 확장과 유지보수가 보다 쉬워지게 된다.




경계 횡단하기

경계가 무엇인지 알아보았으니 이제 시스템 아키텍처에서 쓰이는 다양한 형태의 경계에 대해 몇가지 알아보자. 런타임에서 경계를 횡단하는것은 경계의 한쪽에서 반대편 기능을 호출해 데이터를 전달하는 것인데, 이 때 경계를 세워 의존관계에 의해 변경이 전파되는 것을 막아야 한다.

두려운 단일체

배포관점에서 볼 때 단일체는 경계가 드러나지 않는다. 하지만 그 단일체를 만드는과정에서 각 컴포넌트들을 독립적으로 수행할 수 있게 분리하는것은 가치있는 일이다. 객체지향과 다형성 개념이 있기에 우리는 경계를 횡단할 수 있는것이다. 다음은 가장 단순한 저수준에서 고수준 컴포넌트에 의존하는 경우와 그 반대의 경우이다. 단일체(모놀리틱)의 경우에도 다음과 같이 규칙적인 방식으로 구조를 분리하면 프로젝트 개발/테스트/배포에 큰 도움이 된다.

경계1. 배포형 컴포넌트

아키텍처의 경계가 물리적으로 드러날 수도 있는데 그 중 가장 단순한 형태는 .jar 파일과 같은 동적 라이브러리이다. 이 컴포넌트들은 각자 배포해 곧바로 사용할 수 있기 때문에 배포 수준의 결합 분리 모드이다.

경계2. 스레드(?)

단일체와 배포형 컴포넌트는 모두 스레드를 활용할 수 있으며, 스레드는 실행 경계가 아니며 실행 계획과 순서를 체계화 하는 방법에 가깝다.

경계3. 로컬 프로세스

훨씬 강한 물리적 형태를 띠는 아키텍처 경계로는 로컬 프로세스가 있다. 요약하자면 쿠버네티스와 같은 컨테이너 오케스트레이션을 적용해 프로세스에 드는 비용을 최소화 시키자는 것이다.

경계4. 서비스

물리적인 형태를 띠는 가장 강력한 경계는 바로 서비스이다. 서비스는 함수 호출에 비해 매우 느리며 주의를 기울여 통신을 자제해야 한다. 서비스 또한 저수준이 고수준 서비스에 플러그인 되어야 한다.




결론

  • 소프트웨어 아키텍처에서 경계선을 그리려면 먼저 시스템을 컴포넌트 단위로 분할해야한다. 이 때 일부 컴포넌트는 핵심 업무 규칙에 해당하고 나머지는 플러그인에 해당한다.
  • 결국 이 내용은 의존성 역전 원칙과 안정된 추상화 원칙을 사용하는 것과 원리가 동일하다.
  • 단일체를 제외한 대다수의 시스템은 한 가지 이상의 경계 전략을 사용한다. 서비스 경계를 활용하는 시스템이라면 로컬 프로세스 경계도 일부 포함하고 있을 수 있다.
profile
러닝커브를 빠르게 높이자🎢

1개의 댓글

comment-user-thumbnail
2023년 10월 23일

좋은글 감사합니다.
혹시 참고 자료가 있으면 알려주실수 있으실까요?

답글 달기