인프런 커뮤니티 질문&답변

비가싫어요님의 프로필 이미지

작성한 질문수

Readable Code: 읽기 좋은 코드를 작성하는 사고법

강의를 다 들은 후에 오랜 궁금증에 대해 질문드립니다!

24.07.09 17:06 작성

·

455

·

수정됨

3

안녕하세요, 우빈님! 정말 좋은 강의를 제공해주셔서 감사합니다. 제가 고민하던 주제에 관해 다뤄주셔서 정말 흥미를 가지고 강의를 들을 수 있었습니다

강의를 다 들은 시점에 개발 공부를 시작한 이래로 늘 가지고 있던 오랜 궁금한 점이 있어서 이렇게 질문을 남기게 되었습니다! 조금 장문이 될 수도 있을 거 같네요🥲


스프링을 사용해서 개발하게 되면 제일 처음 배우는 구조가 Controller -> Service -> Repository 이런 구조인데요, 보통 비즈니스 로직은 Service 에 작성된다고 배웠습니다. Service 레이어에서 모든 게 처리되고 비즈니스 로직이 도메인 쪽에 위치하지 못 하게 되는 것 같습니다. 애초에 도메인이라는 개념 자체가 없고 바로 JPA 엔티티를 만들고 @Service 어노테이션이 붙은 클래스에서 모든 걸 다 처리하는 거 같아요. 제가 국비 교육에서 배운 팀 프로젝트나 3개월 간 짧게 경험해 본 실무에서도 다 이렇게 코드를 짰던 거 같습니다. 공부하다보니 이런 걸 트랜잭션 스크립트 라고 하는 거 같더라구요.

그런데 아무리 생각해도 이런 방식은 객체지향적이지 않다는 생각을 지울 수가 없었습니다. 제가 객체지향의 사실과 오해, 오브젝트 등에서 읽은 객체의 역할, 책임, 협력 이런 것들을 적용해보지 못 하는 것 같아서 객체지향적으로 코드를 짜는 것은 어떤 것일까 하는 갈망이 늘 있었습니다. 이런 갈망이 있어서 이번 강의를 더 간절히 기다렸던 거 같아요😀

이번 강의는 스프링이나 데이터베이스를 전혀 사용하지 않고 순수 자바로만 객체지향에 대해서 설명을 해주셨는데요, 만약 스프링과 데이터베이스 기술(JPA) 등을 사용한다고 할 때는 어떻게 처리하시는 지 궁금합니다.

이와 관련해서 제가 공부한 건 JPA 엔티티와 별개로 도메인 역할을 하는 클래스를 만들고 해당 클래스에서 비즈니스 로직을 처리하게 하고 도메인 객체를 JPA 엔티티로 변환해서 데이터베이스에 저장하는 방식이었습니다. (도메인 객체와 영속성 객체를 분리한 것이라고 할 수 있을 거 같습니다.) 이렇게 하면 도메인 객체 안에 있는 비즈니스 로직을 단위 테스트 하기도 쉽고(도메인 객체는 순수 자바(코틀린) 코드로만 돼 있으니까요!) 데이터베이스 중심적이지 않고 도메인 중심적으로 생각을 할 수 있는 것 같다는 인상을 받았습니다.

다만 이렇게 할 때는 어떤 개념을 통해 도메인을 추출해야할 지, 그리고 책임을 어떤 도메인에 넣어야 할 지 고민할 게 많더라구요. 근데 약간 소설의 등장인물을 설정하는 거 같아서 재미는 있었습니다 ㅎㅎ 이렇게 접근을 하니 @Service 어노테이션이 붙은 클래스는 단순히 객체들이 모여서 서로 협력할 수 있게 해주는 광장(?) 이라고 해야될까요, 중개해주는 역할만 하게 되는 것 같다는 생각을 해보기도 했습니다.

이러다 보니 DDD 에 대해서도 많이 관심을 갖게 됐습니다. 도메인 위주로 설계 하고 도메인에게 적절한 역할을 할당하는 방식인 거 같아서요. 그리고 아키텍처에도 많이 관심이 생기더라구요. 단순히 Controller -> Service -> Repositoy 구조의 레이어드 아키텍처에선 처음 언급한 문제를 해결하는게 쉽지 않아 보였거든요.

 

주절주절 질문이 길었는데 요약을 해보자면 다음과 같습니다.

 

  1. 스프링, JPA 같은 기술과 접목했을 때 이번 강의에서 배운 추상, 객체지향적 개발 방식을 어떻게 적용할 수 있을까요?

  2. 이후로 공부할 만한 주제로 DDD, 아키텍처 등이 적절할까요?

 

비전공으로 혼자서 백엔드 개발자 취업 준비 중이라 질문할 곳이 마땅치 않아 여기에 이렇게 남기는 점 미리 양해를 구합니다😭

답변 2

2

박우빈님의 프로필 이미지
박우빈
지식공유자

2024. 07. 13. 15:44

안녕하세요, 부서진 나침반 님!

너무 좋은 질문입니다. 몇 가지 포인트로 나누어서 답변을 드려보도록 할게요.

 

스프링을 사용해서 개발하게 되면 제일 처음 배우는 구조가 Controller -> Service -> Repository 이런 구조인데요, 보통 비즈니스 로직은 Service 에 작성된다고 배웠습니다. Service 레이어에서 모든 게 처리되고 비즈니스 로직이 도메인 쪽에 위치하지 못 하게 되는 것 같습니다. 애초에 도메인이라는 개념 자체가 없고 바로 JPA 엔티티를 만들고 @Service 어노테이션이 붙은 클래스에서 모든 걸 다 처리하는 거 같아요. 제가 국비 교육에서 배운 팀 프로젝트나 3개월 간 짧게 경험해 본 실무에서도 다 이렇게 코드를 짰던 거 같습니다. 공부하다보니 이런 걸 트랜잭션 스크립트 라고 하는 거 같더라구요.

그런데 아무리 생각해도 이런 방식은 객체지향적이지 않다는 생각을 지울 수가 없었습니다. 제가 객체지향의 사실과 오해, 오브젝트 등에서 읽은 객체의 역할, 책임, 협력 이런 것들을 적용해보지 못 하는 것 같아서 객체지향적으로 코드를 짜는 것은 어떤 것일까 하는 갈망이 늘 있었습니다. 이런 갈망이 있어서 이번 강의를 더 간절히 기다렸던 거 같아요😀

음 사실 그렇지 않습니다. 결론부터 말하자면, JPA 객체를 도메인 객체 삼아 최대한 많은 도메인 로직을 부여하고, 이들의 협력이 일어나는 장소가 Service 레이어가 되도록 설계할 수 있습니다.
도메인 객체의 협력을 통해서만 풀어낼 수 있는 비즈니스 로직은 당연히 서비스 레이어에 위치할 것이고, 이에 대한 테스트도 필요하겠지만, 기본적으로 각 객체가 가질 수 있는 도메인 로직이 존재하기 때문에 JPA 엔티티를 도메인 객체로 충분하 사용할 수 있습니다.

이번 강의는 스프링이나 데이터베이스를 전혀 사용하지 않고 순수 자바로만 객체지향에 대해서 설명을 해주셨는데요, 만약 스프링과 데이터베이스 기술(JPA) 등을 사용한다고 할 때는 어떻게 처리하시는 지 궁금합니다.

이와 관련해서 제가 공부한 건 JPA 엔티티와 별개로 도메인 역할을 하는 클래스를 만들고 해당 클래스에서 비즈니스 로직을 처리하게 하고 도메인 객체를 JPA 엔티티로 변환해서 데이터베이스에 저장하는 방식이었습니다. (도메인 객체와 영속성 객체를 분리한 것이라고 할 수 있을 거 같습니다.) 이렇게 하면 도메인 객체 안에 있는 비즈니스 로직을 단위 테스트 하기도 쉽고(도메인 객체는 순수 자바(코틀린) 코드로만 돼 있으니까요!) 데이터베이스 중심적이지 않고 도메인 중심적으로 생각을 할 수 있는 것 같다는 인상을 받았습니다.

맞습니다! 사실 정말 엄밀하게, (강의 중에 표현한 추상과 구체의 개념으로) 도메인 객체와 데이터의 영속성을 담당하는 JPA 엔티티를 분리하고, 두 객체 간 변환하는 과정을 통해 JPA라는 구체적인 기술과 보다 추상적인 도메인 로직을 분리할 수 있습니다.

앞선 답변에 이어 정리하자면,

  • JPA 엔티티를 도메인 객체 삼아, 엔티티 내에 도메인 로직을 담아 그 협력을 통해 비즈니스 로직을 풀어내는 설계

  • 좀 더 엄밀하게 JPA 엔티티와 도메인 객체를 분리하여, 구체적인 기술과 추상적인 도메인을 분리하는 설계

두 방법 모두 장단이 있습니다.
이상적으로 보자면 당연히 두 번째 방법이 더 좋아보입니다만, 실무에서는 편리함 때문에 첫 번째 방법을 사용하는 경우가 좀 더 많습니다.
도메인 객체를 JPA 엔티티로 매번 변환하는 일은 사실 그 자체로 비용이기도 하고요, (귀찮죠..) 한번 JPA를 도입한 프로젝트에서 JPA를 걷어내는 일이 사실상 잘 없기 때문입니다. (특정 상황에서는 필요할 수도 있겠지만요.)
물론 반대로, 팀 내 컨벤션 원칙을 엄밀하게 세우고, 모든 팀원이 동의하며 두 번째 방법을 잘 사용하는 팀도 있습니다.

다만 이렇게 할 때는 어떤 개념을 통해 도메인을 추출해야할 지, 그리고 책임을 어떤 도메인에 넣어야 할 지 고민할 게 많더라구요. 근데 약간 소설의 등장인물을 설정하는 거 같아서 재미는 있었습니다 ㅎㅎ 이렇게 접근을 하니 @Service 어노테이션이 붙은 클래스는 단순히 객체들이 모여서 서로 협력할 수 있게 해주는 광장(?) 이라고 해야될까요, 중개해주는 역할만 하게 되는 것 같다는 생각을 해보기도 했습니다.

이러다 보니 DDD 에 대해서도 많이 관심을 갖게 됐습니다. 도메인 위주로 설계 하고 도메인에게 적절한 역할을 할당하는 방식인 거 같아서요. 그리고 아키텍처에도 많이 관심이 생기더라구요. 단순히 Controller -> Service -> Repositoy 구조의 레이어드 아키텍처에선 처음 언급한 문제를 해결하는게 쉽지 않아 보였거든요.

맞습니다. 말씀주신 것처럼 관련해서 DDD와 헥사고날 아키텍처에 대해서 추가적으로 학습해보시면 좋을 것 같아요. 다만, 취업 준비 중이라 말씀주셨는데요, 개인적으로는 당장의 학습도 좋지만 취업 후 1~2년 차 정도에 담당하고 계실 실무 프로젝트와 엮어서 관련 개념을 학습해보시는 것이 가장 효율이 좋을 것이라 생각합니다.
만약 당장 학습하고 싶으시다면, '만들면서 배우는 클린 아키텍처(톰 홈버그 저, 위키북스)'라는 책을 추천드려요.

도움이 되셨기를 바라며, 취업의 여정도 응원하겠습니다!

감사합니다 🙂

비가싫어요님의 프로필 이미지

2024. 07. 13. 17:09

와 정말 친절하게 답변을 주셨군요! 감사드립니다 😄

늘 객제치향적으로 코드를 짜야한다, 도메인이 우선이 돼야 한다 이런 식의 말과 글을 많이 접하다보니 어떤 프로젝트를 하든지 데이터베이스와 영속성 객체부터 만드는게 너무 데이터베이스 중심적인가? 하는 생각이 많이 들었습니다.

이번 강의를 통해서 객체지향적으로 코드를 짜는 것이 어떤 것인지 이해를 더 잘 하게 된 것 같습니다. 추상화의 힘(?)도 알게 된 거 같구요 ㅎㅎ

강의 여러 번 반복해서 보면서 계속해서 공부해보도록 하겠습니다! 좋은 강의와 답변 감사드립니다!

0

인프런 AI 인턴님의 프로필 이미지

2024. 07. 11. 17:11

안녕하세요, 인프런 AI 인턴입니다.

먼저, 스프링과 JPA를 활용한 객체지향적 개발 방식에 대해 궁금해하시는 우빈님의 열정이 돋보입니다. 질문하신 내용에 대해 답변드리겠습니다.

  1. 스프링과 JPA를 사용할 때 객체지향적 개발 방식을 적용하는 것은 도메인 중심 설계를 통해 가능합니다. 앞서 언급하신 것처럼, 도메인 클래스를 중심으로 비즈니스 로직을 구현하고, 서비스 계층에서는 이러한 도메인 객체들의 협력을 조정하는 역할을 합니다. 이를 위해, 도메인 클래스는 순수한 비즈니스 로직만을 포함하고, 데이터베이스와의 상호작용은 Repository 계층을 통해 분리하는 방식으로 객체지향의 원칙을 적용할 수 있습니다. 또한, JPA의 경우, 엔티티 클래스와 도메인 클래스를 분리하여 설계하는 것이 아니라, 엔티티 자체가 도메인 로직을 가지고 객체지향적인 설계를 반영할 수도 있습니다. 이 점에서 엔티티 설계 시 객체지향의 원리를 적극적으로 반영하는 것이 중요합니다.

  2. DDD(Domain-Driven Design)는 복잡한 시스템을 도메인 위주로 모델링하고 설계하는 방법론으로, 스프링과 JPA 등의 기술과 함께 객체지향적 접근을 실현하기에 매우 적합한 개념입니다. 따라서, 복잡한 어플리케이션의 구조와 비즈니스 로직을 설계하는 데 있어 DDD를 공부하는 것은 매우 유익할 것입니다.

만약 아키텍처에 대한 공부를 진행하고자 한다면, 마이크로서비스 아키텍처, 클린 아키텍처, 육각형 아키텍처 등 다양한 아키텍처 스타일에 대해서도 알아보시는 것이 좋습니다. 이러한 아키텍처 패턴을 공부함으로써, 시스템의 유연성, 확장성, 유지보수성을 높이는 방법에 대해 더 깊이 이해하게 될 것입니다.

혼자서 공부하며 백엔드 개발자로서 성장하고자 하는 우빈님의 노력이 빛을 발할 것이라 확신합니다. 개발자로서의 여정이 쉽지만은 않겠지만, 지금과 같이 지속적으로 학습하고 탐구하는 자세가 있다면 반드시 좋은 결과를 이룰 것입니다. 질문 주셔서 감사합니다.