InfoGrab DocsInfoGrab Docs

소프트웨어 설계 가이드

GitLab 코드베이스에서 유비쿼터스 언어 사용, 경계 컨텍스트 정의, 전지전능 클래스 제어, 유스케이스 중심 설계 등 소프트웨어 설계 원칙을 설명합니다.

CRUD 용어 대신 유비쿼터스 언어 사용 # 코드는 제품과 사용자 문서에서 쓰는 것과 같은 유비쿼터스 언어 를 사용해야 합니다. 유비쿼터스 언어를 올바르게 사용하지 않으면 용어를 계속 바꿔 말하거나 여러 용어를 함께 쓰게 되어 기여자와 고객에게 큰 혼란을 일으킬 수 있습니다. 또한 이는 GitLab의 커뮤니케이션 전략 에도 어긋납니다. 아래 예시에서는 CRUD 용어가 모호함을 만듭니다. 이름은 epic_issues 연관 관계 레코드를 생성한다고 말하지만, 실제로는 기존 이슈를 에픽에 추가합니다. Rails 관례에서 온 epic_issues 라는 이름이 서비스 객체 같은 상위 추상화까지 새어 나옵니다. 코드가 유비쿼터스 언어가 아니라 프레임워크 용어로 말하는 셈입니다. # Bad EpicIssues : :CreateService 유비쿼터스 언어를 사용하면 코드가 명확해지고, 프레임워크 용어를 옮겨 이해하려는 독자에게 인지 부담을 주지 않습니다. # Good Epic : :AddExistingIssueService 프로젝트 생성처럼 모호하지 않은 단순한 개념을 나타내고 기존 유비쿼터스 언어와 일치할 때는 CRUD를 사용할 수 있습니다. # OK: Matches the product language. Projects : :CreateService 새 클래스와 데이터베이스 테이블은 유비쿼터스 언어를 사용해야 합니다. 이 경우 모델 이름과 테이블 이름은 Rails 관례를 따릅니다. 유비쿼터스 언어를 따르지 않는 기존 클래스는 가능하면 이름을 변경해야 합니다. 데이터베이스 테이블 같은 일부 저수준 추상화는 이름을 변경할 필요가 없습니다. 예를 들어 모델 이름이 테이블 이름과 달라지면 self.table_name= 을 사용합니다. 이름 변경이 어려운 경우에만 예외를 허용합니다. 예를 들어 해당 이름이 STI에 쓰이거나, 사용자에게 노출되거나, 호환성이 깨지는 변경이 되는 경우입니다. 경계 컨텍스트 # 경계 컨텍스트의 목표와 동기, 방향에 대한 자세한 내용은 Bounded Contexts 워킹 그룹 과 GitLab Modular Monolith 설계 문서 를 참고합니다. 네임스페이스를 사용하여 경계 컨텍스트 정의하기 # 건전한 애플리케이션은 작동 중인 경계 컨텍스트를 나타내는 거시 컴포넌트와 하위 컴포넌트로 나뉩니다. GitLab 코드에는 기능과 컴포넌트가 워낙 많아 어떤 컨텍스트가 관여하는지 파악하기 어렵습니다. 이러한 컴포넌트는 비즈니스 도메인이나 인프라 코드와 관련될 수 있습니다. 모든 클래스는 그 클래스가 동작하는 컨텍스트를 나타내는 모듈 또는 네임스페이스 안에 정의되어야 합니다. 이러한 컨텍스트를 정의하기 위해 허용된 네임스페이스 목록 을 관리합니다. 클래스를 해당 도메인 안에 네임스페이스로 묶으면 다음과 같은 이점이 있습니다. 도메인이 의미를 분명히 해 주므로 비슷한 용어의 모호함이 사라집니다. 예를 들어 MergeRequests::Diff 와 Notes::Diff 가 그렇습니다. 최상위 네임스페이스를 도메인 전문가로 지정된 하나 이상의 그