비즈니스 로직, 도메인 로직이 도대체 뭐지?

eddy_song·2022년 5월 15일
4
post-thumbnail

비즈니스 로직, 도메인 로직이 대체 뭐야?

'비즈니스 로직'을 분리하라.

비즈니스/도메인 로직은 다른 계층에 의존해서는 안 된다.

좋은 설계에 대해 얘기할 때 이런 말을 정말 많이 듣는다.

대충은 무슨 말인지 알겠다. UI 업데이트하는 코드는 비즈니스 로직은 아니니까. 비즈니스 로직은 좀 더 추상적인 데이터를 다루는 쪽인 거지...?

근데 DB에서 특정 조건의 데이터를 가져오는 코드는?
서버에서 가져온 데이터를 파싱하는 코드는?
화폐 단위를 다른 화폐로 바꾸는 코드는?
사용자가 검색한 데이터가 실제로 있는지 확인하는 코드는?

음... 비즈니스 로직인가? 아닌가...?
이 단어를 자주 쓰면서도 어렴풋하게 알고 있단 사실을 깨달았다.

그러다 매우 명료하게 설명해주는 글을 찾아서, 오늘은 비즈니스/도메인 로직이 뭔지에 대해 간단히 정리해보려고 한다.

도메인, 비즈니스의 의미

도메인 로직, 비즈니스 로직이라는 말은 거의 동의어처럼 쓰인다.
여기서 눈에 들어오는 것은 '도메인'과 '비즈니스'라는 단어다.

🤔 도메인? 도메인 주소?

😵‍💫 비즈니스? 내 앱은 사업이 아니라 그냥 사이드 프로젝트인데..?

여기서 도메인이나 비즈니스라는 단어는 우리가 자주 쓰는 맥락과는 조금 다르다. 소프트웨어 공학에서 도메인, 비즈니스라는 말은, '소프트웨어가 풀고자하는 현실 세상의 문제'를 가리킨다.

다시 말해 소프트웨어가 존재하는 이유, 목적이다.

은행 앱이라면, 금융 및 은행 업무가 도메인이다. 은행 앱이 해결하고자 하는 문제가 금융 업무를 스마트폰에서 처리할 수 있게 해주는 것이니까. 틱톡 같은 SNS라면 동영상 촬영, 감상, 댓글 및 공유일 것이다.

조금 더 이해를 돕자면, 반대로 공학/기술적인 문제에 속하는 것들은 대개 '도메인'과는 구별된다. 수많은 은행 사용자 데이터를 어떻게 효율적으로 저장할 것인가. 어떻게 고화질 동영상을 빠르게 로딩할 것인가? 같은 것들.

따라서 '도메인 로직'이나 '비즈니스 로직' 이라고 말할 때는, 그 '현실 세상의 문제'를 해결하는 코드를 의미한다. 도메인에 대한 해결책이나 솔루션이라고 할 수 있다.

소프트웨어는 다 현실 문제를 해결하는 거 아닌가?

그렇게 생각할 수도 있겠지만, 코드가 하는 일을 잘 생각해보자.

우리는 특정한 문제 영역에 대한 솔루션을 제공하는 코드 외에도 많은 코드를 써야한다.
그 코드를 가능하게 만들고, 입력과 출력을 처리하기 위한 로직들이다.

대표적으로 데이터베이스에 연결하고, 백엔드 서버와 통신하고, 사용자와 인터랙션하는 코드들이 필요하다.
이런 것들은 도메인 로직과 구분지어 어플리케이션 서비스 로직이라고 부른다.

이 코드는 현실 문제에 대한 의사결정을 하고 있는가?

도메인 로직과 어플리케이션 서비스 로직을 구분하는 하나의 척도는, 바로 '비즈니스 의사결정'이다.

이 코드가 현실 문제, 즉 비즈니스에 대한 의사결정을 하고 있는가?

이거 하나만 기억하면 된다.

도메인 로직은 현실 문제에 대한 의사결정을 하는 코드다. 나머지 코드는 그 결정을 위한 입력값을 만들어주거나, 그 결정의 결과물을 해석하고 보여주고 전파하는 코드다.

모바일 송금의 예시

예를 들어서, 흔한 모바일 송금 앱이 있다고 해보자.

송금 기능을 담당하는 코드가 있다.
이 코드를 자세히 뜯어보면 다음과 같은 일을 하는 코드로 이뤄져있다.

  1. 계좌 잔액이 충분한지 확인한다.
  2. 유효하다면 송금 버튼을 활성화하고, 유효하지 않다면 에러 메시지를 띄운다.
  3. 사용자의 멤버십 등급에 맞춰서 송금 수수료를 계산한다.
  4. 송금 수수료를 결제하도록 외부 결제 서비스에 요청한다.
  5. 사용자의 잔액을 감소시킨다.
  6. 사용자의 잔액을 DB에 저장한다.

이 코드들을 구분할 때, 해당 소프트웨어가 '송금'이라는 현실 문제에 대한 의사결정을 하는가를 생각해보자.

어떤 것이 도메인 로직이고, 어떤 것이 서비스 로직일까?

도메인 로직에 해당하는 것은 다음과 같다.
이 코드들은 '송금'에 대한 의사결정을 담당하고 있다.

  1. 계좌 잔액이 충분한지 확인 -> 송금이 가능한지에 대한 의사결정
  2. 송금 수수료를 계산 -> 송금에 드는 비용을 정책에 따라서 결정
  3. 사용자의 잔액을 감소시킨다 -> 송금이라는 서비스를 수행

어플리케이션 서비스 로직에 해당하는 것은 다음과 같다.
이 코드들은 도메인 로직이 의사결정을 할 수 있도록 입력을 제공하며, 결과를 외부 서비스/DB/UI에 업데이트하는 역할을 맡는다.

  1. 유효하지 않으면 에러 메시지를 띄운다 -> UI
  2. 송금 수수료를 결제하도록 외부 결제 서비스에 요청한다. -> 외부 서비스와의 네트워킹
  3. 잔액을 DB에 저장한다. -> Persistence

만약 어떤 코드가 명확하게 도메인 로직인지 아닌지 애매하다면, 해당 코드가 하는 일을 쪼개야 한다는 신호다. 도메인 로직이 분명한 부분과 서비스 로직이 섞여 있을 수도 있다.

현재 가지고 있는 원화가 미국 달러로 얼마인지 보여주는 함수가 있다고 해보자.

이 함수 하나만 가지고 생각하면 도메인 로직인지 아닌지 애매하다.
하지만 함수를 분리하고 코드를 쪼개보면 좀 더 명확해진다.

  • 미국 달러 환율을 얼마로 할 것인가. 계산 공식은 얼마로 할 것인지 결정하는 코드. -> 도메인 로직
  • 단위와 화폐 포맷을 바꿔서 UI에 업데이트를 하는 코드. -> 어플리케이션 서비스 로직

명확한 관심사의 분리

이런 기준을 세워서 우리가 도메인 로직과 아닌 것을 나누는 이유는 명확한 관심사의 분리를 위해서다.

도메인 로직과 어플리케이션 서비스 로직은 어떤 앱이든 역할이 구분되고, 변경의 이유도 다르기 때문이다.

도메인 로직과 아닌 것을 잘 나누고 결합도를 낮추면, 개발자가 로직을 이해하기 쉬워진다.

DB나 UI 같은 기술적인 구현 사항에 신경 쓰지 않고, 도메인 로직을 이해할 수 있다.

비즈니스 정책이 바뀔 때 소프트웨어를 변경하고 기능을 추가하는 것이 편해진다.

이런 이유로 클린 아키텍처에서는 도메인 로직을 앱의 코어로 두고, 다른 계층에 의존하지 않도록 설계한다. 다른 계층들은 도메인 로직에게 입력을 전달하고, 변화를 외부로 전달하는 역할을 하도록 명확하게 분리한다.

profile
개발 지식을 쉽고 재미있게 설명해보자.

3개의 댓글

comment-user-thumbnail
2022년 5월 19일

좋은 글 잘 읽었습니다 ㅎㅎ
저도 궁금했던 부분인데 잘 정리해주셨네용

1개의 답글
comment-user-thumbnail
2022년 5월 25일

업무하면서 아리송했던 부분들인데, 잘 설명해주셔서 감사합니다! 많은 도움이 됐습니다

답글 달기