애플리케이션 로직? 도메인(비즈니스) 로직?애플리케이션 로직만 있고 도메인 로직은 없는 시스템 vs 애플리케이션 로직만 있고 도메인 로직은 없는 시스템애플리케이션 로직과 도메인 로직을 구분해 얻을 수 있는 장점
애플리케이션 로직과 도메인 로직이 각각 무엇인지에 대해 이해하고, 둘을 구분해 코드를 개선한 사례를 글로 풀어보겠습니다.
애플리케이션 로직? 도메인(비즈니스) 로직?
각각을 아래와 같이 짧게 정의해볼 수 있습니다. 여기서 도메인 로직의 정의는 조금 추상적으로 느껴집니다.
- 애플리케이션 로직: 도메인 로직이 의사결정을 할 수 있도록 입력을 제공하거나, 그 결과를 외부 서비스, DB, UI 등에 업데이트하는 역할을 맡음
- 도메인(비즈니스) 로직: 현실 세상의 문제에 대한 의사결정을 함
애플리케이션 로직만 있고 도메인 로직은 없는 시스템 vs 애플리케이션 로직만 있고 도메인 로직은 없는 시스템
이를 좀 더 쉽게 이해하기 위해 아래 예시에 대해 소거법을 이용해 차이를 구분해보겠습니다.
[예시] 예약 가능 시간 목록 조회 API V1
- 해당 기간동안 예약된 시간들을
DB에서가져온다 → 애플리케이션
- 전체 시간들을
DB에서가져온다 → 애플리케이션
- 전체 시간에서 예약이 된 시간과 안 된 시간을 구분한다 → 도메인
- 예약이 된 시간과 안 된 시간을 구분해
출력한다→ 애플리케이션
애플리케이션 로직만 있고 도메 로직인이 없는 시스템은 겉으론 동작을 하는 것처럼 보이지만 그 값이 사용자가 원한 해결책이 아닐 것입니다. 예시의 API V1에선 예약이 된 시간과 안된 시간이 제대로 구분되지 않고 출력될 것입니다.반면,
도메인만 있고 애플리케이션 로직은 없는 시스템은 문제에 대한 의사결정은 가능하지만 이에 대한 입출력 로직이 부재해 실질적으론 문제를 해결하지 못하는 시스템이 될 것입니다. 예시의 API V1에선 예약이 된 시간과 안 된 시간을 구분하는 방법은 알지만 구분할 대상과 그 결과를 보여줄 방법이 부재하는 시스템이 될 것입니다.다만 어려운 게 V2처럼 짤 수도 있는 것이기에, 동일한 문제에 대해서도 둘의 구분을 사람마다 상황마다 다르게 둘 수 있는 거 같습니다.
[예시] 예약 가능 시간 목록 조회 API V2
- 전체 시간을 예약 여부를 구분해
DB에서가져온다 → 애플리케이션
- 예약이 된 시간과 안 된 시간을 구분해
출력한다→ 애플리케이션
애플리케이션 로직과 도메인 로직을 구분해 얻을 수 있는 장점
제가 생각하는 가장 큰 장점은 도메인 로직을 분리함으로써 문제 해결 과정을 더 잘 묘사할 수 있단 점이 있습니다. 예를 들어 첫 번째 코드를 두 번째 코드로 리팩토링함으로써 읽는 사람을 덜 혼란스럽게 할 수 있습니다.
- 리팩토링 전
- 리팩토링 후
리팩토링 한 버전에선 애플리케이션 로직과 도메인 로직을 잘 구분해둠으로써 적절한 위치(레이어)에 배분해줬고, 문제 해결 과정을 좀 더 자연스럽게 묘사할 수 있었습니다. 리팩토링 전 코드에선 도메인 로직과 애플리케이션 로직이 혼용해 전부 서비스 레이어에 위치했지만, 리팩토링 후엔 도메인 로직과 애플리케이션 로직을 구분해 도메인 로직은 도메인 레이어로 옮겨주었습니다.
문제 해결 과정
- 해당 기간동안 예약된 시간들을
DB에서가져온다 → 애플리케이션
- 전체 시간들을
DB에서가져온다 → 애플리케이션
- 전체 시간에서 예약이 된 시간과 안 된 시간을 구분한다 → 도메인
- 예약이 된 시간과 안 된 시간을 구분해
출력한다→ 애플리케이션
별거 아니게 보일 수 있지만, 생각보다 많은 사람들이 도메인 로직과 애플리케이션 로직 구분 없이 수많은 로직들을 전부 서비스 레이어에 몰아넣는다 생각합니다. 앞으로 도메인 로직을 분리하는 데에 도움이 되길 기대하며 포스트로 작성해보았습니다.
