모든 개발은 결국 도메인부터 아키텍처!
최근, 컴포트 존에 들어와서 익숙한데로 업무를 진행하려고 하는 경향을 갖게 된 것 같다.
현재 회사에서는 올바른 성장 롤모델을 보여줄 사수나 시니어는 없는 상황이라, 지금처럼 업무만 진행한다면, 좋은 개발자가 되기는 어려울 것 같다는 생각이 들었다.
현재, 개발에서는 도메인 주도 개발이 유행하고 실제로 많은 회사들이 이 DDD를 우대사항으로 내거는 회사들이 많은데, 습관적으로 개발을 해왔던 나로서는 왜 DDD가 유행이고 중요한지 전혀 알길이 없었다.
그래서, 이번에 블로그 글을 정리하여 습관적으로 작성한 코드안에 녹아있는 도메인과 아키텍처의 내용을 정리하고, 앞으로의 학습 방향을 확고히 하고자 한다.
누구나 잘 알면서 잘 모르는 도메인
혹시 '코끼리와 시각장애인'이라는 이야기를 알고 있는가?
이야기를 대략 요약해 보면, 여섯 명의 시각장애인이 코끼리의 몸의 '일부'를 더듬으며, 각기 다른 사물을 유추하는 내용인데, 이러한 내용의 흐름은 다양한 사람이 '도메인'을 바라보고 정의하는 흐름이랑 매우 비슷하다.
웹 개발을 하는데 자주 언급되는 용어지만, 굳이 개발자가 아니더라도 인터넷을 사용해 본 사람이라면 '도메인'이라는 말을 많이 들었을 것이다.
그런데, 도메인이라는 이 용어가 참 익숙하지만, 정의할 수 있는 내용이 참 다양하다. 지금까지 필자가 지인들에게 도메인에 대해 물어봤을 때 대략적인 의미를 분야별로 분류해 보면 다음과 같았다.
- 비 IT 비개발직군 : 홈페이지 사이트 이름 (ex. naver, google 등)
- IT 비개발직군 : 비즈니스 분야
- IT 개발직군: 이력, model, 모듈, 문제 등등…
명확한 정보 전달을 위해 최대한 간추려보았는데, 그럼에도 불구하고 의미하는 바가 뭔가 조금씩 다르다.
도메인의 사전적 의미인 ‘영역’이라는 점을 보면, 위에서 정의는 전부 틀린말은 아니다. 다만 도메인이 가지고 있는 의미들 중의 ‘일부’일 뿐이다. 따라서 도메인을 그저 절대적인 관점에서 하나로 정의하려고 해도 결국 코끼리의 일부를 더듬는 장님 중 한 명이 될 수밖에 없다.
따라서, 도메인의 정의할 때는 그 도메인이라는 용어가 사용되는 장소와 상황을 보고 정의해야 할 영역이 무엇인지를 보는 게 핵심이라 할 수 있겠다.
도메인은 결국 ‘영역’의 관점에서 보아야 한다.
개발자가 정의하는 도메인을 파악하기 위해 다양한 방법(나 홀로 고민, 네트워킹 밋업, 커뮤니티 질문 업로드, 동료에게 물어보기 등등...)을 동원하여 알아보았는데, 생각보다 다양했다. 대략적으로 나열해 보면 다음과 같이 정리해볼 수 있었다.
- 비즈니스의 중심
- 나의 이력 (ex. 저는 xx 도메인에서 x년간 근무 했습니다.)
- 문제를 해결해야 하는 부분 (개인적으로 가장 많이 와닿았던 부분이었다.)
- 만남의 장소 (도메인을 기점으로 다양한 개발자와 만남을 가지기 위해서라고 한다..!)
- 플레이그라운드 (어떤 도메인이든 개발은 재밌으니까..?)
개인적으로는 3번이 가장 와닿았는데, 이유는 조영호님이 집필한 오브젝트라는 서적에서 다음과 같이 도메인을 정의했기 때문이라고 생각한다.
소프트웨어는 사용자가 원하는 어떤 문제를 해결하기 위해 만들어진다. 영화 예매 시스템의 목적은 영화를 좀 더 쉽고 빠르게 예매하려는 사용자의 문제를 해결하는 것이다. 이처럼 문제를 해결하기 위해 사용자가 프로그램을 사용하는 분야를 도메인이라고 부른다.
- 조영호, ‘오브젝트’ -
이 내용을 참고해보면, 결국 도메인은 영역의 관점에서 바라보아야 하며, 개발자로서 도메인에 대해 정의해본다면 도메인이란 프로그래밍을 하면서 맞닥뜨리고 해결해야 하는 문제의 영역이라 할 수 있겠다.
깨끗한 코드는 곧 깨끗한 아키텍처
위키피디아에 의하면 아키텍처란(https://en.wikipedia.org/wiki/Software_architecture) 소프트웨어의 복잡한 시스템을 지적으로 파악할 수 있는 추상화라고 한다.
좀 더 쉽게 풀어보자면, 아키텍처는 애플리케이션의 설계도면이라 볼 수 있다. 그런데 만약 명확한 아키텍처가 없다면 무슨 일이 일어날까?
깨진 유리이론
깨진 유리이론이란, 깨진 유리창 하나를 방치해 두면 그 지점을 중심으로 범죄가 확산되기 시작한다는 이론으로, 사소한 무질서를 방치하면, 범죄율이 얼마나 크게 상승하는지에 대한 교훈을 주는 이론이다.
마찬가지로, 애플리케이션 코드 역시 사소한 지저분한 냄새를 방치한다면 유지보수 효율이 매우 안좋아지고 점차 외계인 코드로 변질되어 결과적으로는 어마어마한 기술부채를 쌓게 될 수 있다.
나쁜 냄새의 기준
지저분한 코드를 방치하면 안된다는 내용은 참 말은 쉽지만 실제로 실천하는것은 너무나도 어렵다. 따라서 나쁜 냄새에 대한 기준을 어느정도 확립할 필요성이 있는데 대표적으로 다음과 같은 부분들이 있겠다.
- 경직된 코드
- 두 가지 관점으로 볼 수 있겠는데,
첫째로, SOLID 관점에서 본다면, 하나의 함수 및 클래스에 여러가지 역할을 부여하여 코드의 결합도를 높이는 경우를 예로 들 수 있다.
마지막으로, 아키텍처 관점에서 보면, 하위 계층에 지나치게 의존하여, 특정 계층에 해당하는 코드를 조금이라도 고치면, 다른 영역의 코드까지 고쳐야하는 상황을 예로 들 수 있을 듯 하다.
- 두 가지 관점으로 볼 수 있겠는데,
- 약한 내구성
- 변경이 일어나면, 소프트웨어 자체가 망가지는 경우를 이야기하는데, 1의 경우 때문에 일어날 수 있는 상황일 수도 있고, 각 도메인별 유즈케이스가 명확하지않아 보안 취약점 및 예외처리를 제대로 수행하지 못한 코드를 예로 들 수 있다.
- 의미 없는 반복
- 물론 반복된 코드가 무조건 잘못된 것은 아니다. +1 연산자가 들어있는 함수만 해도, +1을 하고자 하는 대상이 다른것과 같이 코드는 동일하지만 논리적으로 동일하지 않은 비즈니스 로직의 경우, 반복된 코드여도 따로 분류하는 것이 맞다.
그러나, 그냥 코드를 복사 붙여넣기로 방치해놓는다면, 나중에 코드를 변경할 때 불필요한 공정을 발생시키는 요소가 될 수 있겠다.
- 물론 반복된 코드가 무조건 잘못된 것은 아니다. +1 연산자가 들어있는 함수만 해도, +1을 하고자 하는 대상이 다른것과 같이 코드는 동일하지만 논리적으로 동일하지 않은 비즈니스 로직의 경우, 반복된 코드여도 따로 분류하는 것이 맞다.
- 불투명성
- 제 3자의 개발자를 혼란에 빠트리는 코드는 결국 애플리케이션 코드를 지저분하게 만드는 요소가 되는데 이 요소는 결국 모호한 아키텍처를 구성하게 하는 케이스가 될 수 있다.
- 제 3자의 개발자를 혼란에 빠트리는 코드는 결국 애플리케이션 코드를 지저분하게 만드는 요소가 되는데 이 요소는 결국 모호한 아키텍처를 구성하게 하는 케이스가 될 수 있다.
결국 도메인을 잘 이해해야 깨끗한 아키텍처를 구성할 수 있다.
앞의 내용들을 보면, 결국 깨끗한 아키텍처를 구성하기 위해서는 깨끗한 코드가 선행되어야 한다는 점을 알 수 있다. 깨끗한 코드를 구성하기 위해선, SOLID가 준수하게 적용된 객체지향을 구성하기 위한 지식과 경험이 필요하고.. 객체지향을 잘 구성하기 위해선, 제일 먼저 SRP(단일책임원칙)을 준수하는 것이 중요하고, SRP를 준수하기 위해선 도메인을 잘 이해해야 한다.
따라서, 깨끗한 아키텍처를 구성하기 위해선 도메인을 제대로 정의하고 이해하는 과정이 선행되어야 한다는 것을 알 수 있다.
도메인과 아키텍처의 관계
앞의 내용을 통해 필자는 도메인 자체를 정의하는 방향을 정해볼 수 있었고, 좋은 아키텍처를 구축하기 위해선 좋은 코드를 작성할 수 있어야 하고 좋은 코드를 작성하기 위해선 도메인을 이해해야만 한다.
이미 현장에는 레퍼런스로 삼을 수 있는 여러 아키텍처들이 있는데, 그러한 아키텍처들은 도메인을 어떻게 바라보고 있을까? 이 부분에 대한 답은 의외로 명확했다.
모든 아키텍처는 도메인으로부터 시작한다
먼저 우리가 살고 있는 지구의 구조와 클린 아키텍처의 구조를 비교해보자.
그리고 아래의 포트/어댑터 아키텍처 패턴을 보자
바로 위의 이미지의 한 가운데에 적혀진 ‘Domain Model’ 참고해보면, 도메인은 결국 지구의 내핵 즉 핵심 코어를 구성하는 요소가 되며, 도메인이 없으면 아키텍처는 있을 수가 없다. 이 흐름을 보면, 도메인을 잘 이해해야만 아키텍처를 구성할 수 있는 개발자가 될 수 있다는 걸 유추해볼 수 있다.
아키텍처의 종류를 많이 알면 어떤 이점이 있을까?
조금만 검색해보면, 우리는 이미 너무나 다양한 아키텍처들을 접해볼 수 있다. 그런데, 이러한 아키텍처들을 학습을 하는게 의미가 있을까?
결론 부터 이야기하면, 우선 ‘그렇다’라고 주장하고 싶다. 왜냐면, 아키텍처들을 구현하기 위해 필요한 기술들의 종류는 거의 정해져 있는데, 이러한 기술들의 종류를 얕고 다양하게 알아두면, 좀더 의미 있게 애플리케이션을 바라보는 시각을 가질 수 있기 때문이다.
근거를 좀 더 구체적으로 설명하기에 앞서, 먼저 아키텍처의 종류를 살펴보겠는데, 크게 모놀리식 아키텍처, 분산형 아키텍처 로 분류할 수 있다.
모놀리식 아키텍처
단일 모듈로 이루어진 매우 단순한 애플리케이션 아키텍처로 대표적으로 다음과 같은 아키텍처가 있다.
- Layered Architecture
- Clean Architecture
- Hexagonal Architecture
분산형 아키텍처
하나의 메인 도메인에서 나누어지는 서브 도메인들을 역할에 따라 모듈을 나누고 분산된 시스템으로 메인 도메인을 운영하는 구조의 아키텍처라 할 수 있는데, 쉽게 생각해서 여러 개의 고립된 상태로 서로 통신을 하는 모놀리식 아키텍처들의 모임으로 받아들여도 무방하다.
대표적으로 다음과 같은 아키텍처들이 있다.
- Service Oriented Architecture
- Event-base Architecture
- MicroService Architecture
이처럼, 애플리케이션의 아키텍처에 대한 레퍼런스는 굉장히 다양한데, 이러한 아키텍처를 알면 얻게되는 이점으로 무엇이 있을까? 크게 2가지로 볼 수 있겠다.
아키텍처를 알면 얻는 이점1. 의미있는 애플리케이션 설계
위의 도표를 살펴보면, 아키텍처의 종류별로 얻을 수 있는 장점과 단점이 매우 다양하다.
애플리케이션 개발을 하면 필연적으로 도메인 설계를 하고, 그 성격에 맞는 아키텍처 구조를 설계해야 한다.
이때, 아키텍처의 특징을 잘 파악해두면, 아예 제로 베이스로 진행하는 것보다는 위와 같이 이미 나와있는 레퍼런스를 미리 파악해두면 설계를 진행하는 데, 명확한 기회비용을 파악할 수 있다.
또한 팀의 동료들을 제대로 설득하는데 필요한 납득할 수 있는 방향을 제시하는데도 큰 역할을 할 수 있다.
아키텍처를 알면 얻는 이점2. 학습에 대한 명확한 기준 제시
윗 문단에서 예로 들었던 이미지를 다시 한번 살펴보자.
위의 이미지를 보면 특정 서비스를 충족 시키기 위해서 필요한 기술들은 거의 고정되어 있는데, 아키텍처별로 이러한 기준을 잘 숙지하고 있으면, 필요에 따라 학습해야하는 기술을 최대한 압축할 수 있다.
개발자는 정말 알아야할게 많고 결국에는 다 할 수 있어야 한다. 그런데 그렇다고 현존하는 모든 기술들을 머리속에 때려넣을려고 한다면, 정신 건강에 악영향을 끼칠 수 있다. 또한 사람의 기억력은 휘발성이 강하기에 나중에 정작 써야할 때가 되면 잊을때가 많다.
하지만 다행히도, 개발 기술은 유행을 따르는 경우가 있어 도메인 서비스를 구현하는데 필요한 아키텍처는 시기별로 거의 정해져 있고 그 아키텍처를 구성하기 위해 필요한 기술 역시 거의 정해져 있다. 따라서, 유행의 흐름을 파악하고 그 유행에 맞는 아키텍처만 파악해둔다면, 개발자에게 필요한 기술들에 대한 선택과 집중을 할 수 있다.
이 내용은 적정 소프트웨어 아키텍처 라는 서적에서도 나온 내용중에 ‘시스템을 제안한다’ 라는 문구를 통해서도 유추해볼 수 있는데, 해당 내용은 다음과 같다.
아키텍처 선택은 시스템의 골격 역할, 품질 속성에 영향을 미치며 시스템을 제안한다.
- 적정 소프트웨어 아키텍처 -
앞으로의 성장 계획
꽤 잘한다 싶은 동료 개발자들이 추천해준 서적, 혹은 몇몇 유명한 개발 블로그들에서 제시하는 추천 서적들의 목록을 보면, ‘클린코드’라는 서적을 추천하지 않은 경우는 없었던 것 같다.
이 서적을 추천하는 이유에 대해서 깊게 고민한 적이 없었는데, 결국에는 깨끗한 코드를 통해, 깨끗한 아키텍처를 구축을 하기 위한 첫 단계이기 때문인듯 하다.
게다가 대부분 서버 개발자 채용공고를 보면 도메인 주도 개발(DDD)를 우대사항으로 포함하는 사례가 많은데, 커리어 발전을 위해서는 깨끗한 코드를 바탕으로 한 도메인에 대한 이해도를 높이고 개발 기술을 바라보는 시각을 넓히는 것이 가장 중요한 포인트인 것 같다.
요약
결국 좋은 아키텍처 구조를 구축할 수 있는 개발자가 좋은 개발자다
지금까지 서술한 내용을 종합하면, 결국 좋은 개발자는 좋은 애플리케이션을 개발할 줄 아는 사람이라 할 수 있다.
좋은 애플리케이션은 결국 구조가 잘 잡힌 애플리케이션을 가지고 있다고 할 수 있는데, 지금까지 서술한 내용을 바탕으로 구조가 잘 잡힌 애플리케이션은 다음과 같다.
- 요구사항에 빠르게 적용한다.
- 오류에 대해서 대응이 빠르다.
- 변경에 빠르다.
- 확장성이 좋다.
- 좋은 아키텍처 구조를 가지고 있다.
출처:
https://en.wikipedia.org/wiki/Software_architecture
https://herbertograca.com/2017/07/05/software-architecture-premises/
https://herbertograca.com/tag/explicit-architecture/
https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html
https://www.oreilly.com/content/software-architecture-patterns/
https://nathanpeck.com/microservice-principles-decentralized-governance/