본문 바로가기

프로젝트일지

[프로젝트 'Inside'] 기본 도메인 설계와 개발 과정, 느낀 점

프로젝트 기획 배경

올해 초 몇 개의 동아리에 지원하면서 지원서를 작성할 일이 몇 번 있었다. 보통 구글 폼을 통해 많이 모집했고, 자체적인 동아리 홈페이지 내에서 지원서를 직접 받는 경우도 있었다. 구글 폼의 경우 손쉽게 지원서 양식을 만들고 누구나 쉽게 사용할 수 있다는 장점이 있지만, 결국 설문조사를 목적으로 만들어진 서비스이기 때문에 지원서 기능에 특화시킬 수 있는 부분들이 몇가지 있어보였다. 그래서 처음에는 아래를 목표로 프로젝트를 기획하게 되었다.

  • 내가 쓴 글과 모집자가 확인 하는 글의 시각적인 불일치를 해결해보자
  • 모집자가 더 편하게 지원서 확인할 수 있도록 만들기

먼저 시각적 불일치는 내가 입력한 글이 시각적인 부분에서 그대로 모집자에게 전달될 것이라고 보장하지 않는 문제를 말한다. 예를 들어 줄바꿈 같은 문제이다. 보통 지원서를 작성할 때, 모집자의 입장에서 눈에 잘 들어오도록 줄과 문단을 나눈다. 하지만 몇몇 지원서 서비스와 구글 폼에서는 이런 양식들을 내가 입력한 그대로 모집자에게 전달되는지 알 수 없기 때문에 불편하게 느껴졌다. 이를 미리보기 등의 기능을 통해 해결 해보자고 생각했다.

 

구글 폼은 설문에 대한 통계를 도표, 그래프, 스프레드 시트 등을 통해 정말 다양하게 제공한다.하지만 300~ 1000자 수준의 지원서 글을, 지원자 별로 빠르게 검토하는데에는 부족부분이 있다고 생각했다. 때문에 이런 부분 또한 개선해 보는 것을 목표로 삼았다.  

 

 

초기 목표

 개인 프로젝트이기 때문에, 처음부터 너무 복잡한 기획을 세우면 완성하기 힘들 것 같았다. 팀 프로젝트 경험은 몇번 있지만 오히려 개인 프로젝트 경험은 적어서, 일단 기초적인 기능을 먼저 구현하고, 하나씩 기능을 개선해 나가고자 했다. 때문에  설정한 기본적인 기능은 다음과 같다.

 

  • 로그인 - OAuth2를 활용해 구글, 페이스북, 네이버 로그인
  • 지원자
    • 지원서 작성 및 제출
    • 지원서 임시저장
    • 내가 쓴 지원서 조회
  • 모집자(또는 단체)
    • 지원서 양식 생성
      • 항목 추가 - 글 형식, 체크박스, radio(select) 형식
      • 링크 생성 - 모집마다 지원 링크가 생성(구글 폼 형식)
    • 지원서 목록 조회

로그인 기능 같은 경우 그냥 Spring filter를 통해 간단하게 구현하려 했으나 최근 어떤 기업 면접과제에서 강제로 Spring Security를 익히게되어 이를 활용해보려한다.

 

 

위의 기본 기능을 구현하기 위해 데이터베이스를 아래와 같이 설계했다.

 

사실 이렇게 테이블 설계를 먼저 해본 것은 처음인 것 같은데 만들면서 어떻게 구현할지를 생각하면서 만들다보니 이 단계에서 고민이 많았다. 예를 들어 question과 여러 form 테이블들은 JPA의 상속관계를 통해 매핑되도록 질문의 유형마다 다른 입력 형식을 같기 위해 다음과 같이 설계하였다. 

이 부분에서 text_form 테이블은 하나의 문항(question)에 대한 정보를 한 테이블로 관리할 수 있었지만, checkbox_form, select_form 과 같은 경우에는 여러개의 정해지지 않은 길이의 항목들이 필요했기 때문에 element 테이블을 생성하고 checkbox_form은 단순히 question_id 하나만 갖는다.

 

JPA의 @Inheritance를 활용해 개발하다보니 이와 같이 테이블을 설계하게 되었는데, 지금까지도 이와 같은 방식이 맞는건지 의문이든다. 계속 고민하면서 좋은 방법을 고민 해봐야겠다.

 

 

DDD와 TDD

그 유명한 DDD와 TDD를 이 프로젝트를 통해 직접 적용해보고 싶었다. 여러번 설명을 듣고 예시 코드를 봐도 직접 경험해보는 것과는 또다른 경험이었다. 먼저 TDD의 경우 하면서도 이게맞나,,, 라는 생각이 계속 들었다. 테스트 코드 내에서도 중복이 많고 여러가지로 지저분해 보여서 솔직히 누가 볼까 부끄러웠다.

너무 알아보기 힘든 테스트들,,

그래도 유튜브에 올라온 어떤 컨퍼런스에서, TDD를 잘하긴 위해선 일단 많이 해보는게 중요하다는 한 개발자의 말을 듣고 힘들어도 계속 진행해봐야 겠다. 하다보면 뭔가가 보이지 않을까 싶다. 그래도 확실히 테스트를 먼저 작성하고 구현하다보니 구현을 먼저했으면 놓쳤을 부분들을 먼저 고려해볼 수 있었고, 좀더 안전하고 일관성 있게 개발되는듯한 안정감 또한 느낄 수 있었다. 더 많이 경험해봐야겠다!!!!

 

그리고 DDD는 아직 더 해봐야 알겠지만 처음에 생각한 것 처럼 그렇게 어려운 개념이 아닐 수도 있겠다는 생각이 들었다. 위의 테이블 설계처럼 어떻게 비즈니스 로직을 구현일 것인가를 생각하면서 도메인을 설계하다보면, 도메인을 설계하는 것만으로도 웹과 관련된 계층을 제외한 대부분의 개발이 끝난다는 것을 깨달았다.

 

만약 controller 처럼 웹과 맞닿아 있는 부분 먼저 개발했다면, 웹 부분에 대한 변경에 따라 도메인을 계속 수정해야하는 불안정한 개발을 했을 것이다. 하지만 도메인을 먼저 개발하다보니 더 안정적으로 웹과 같은 변경이 많은 부분들을 도메인과 분리하고 dto를 통해 데이터를 전달하므로써 도메인은 변경이 적고 안정적인 형태로 개발이 가능하다.(지금까지는,,)

 

또 자연스럽게 머리속에 개념적으로 이어지는대로 user, recruitment, application 엔티티를 나누어 각각의 도메인 디렉터리에 저장하고 나머지 엔티티들은 패키지 안에서 의미적으로 연결된 연관관계에 따라 패키징했는데,  몇달전 공부했던 cascade, orphanRemoval 기능이 잘 생각나지 않아 찾아보던중 Aggregate Root라는 개념이 있었고 나도모르게 이 개념을 개발에 접목시켜서 개발하고 있었어서 신기했다. Aggregate Root는 한 도메인 내의 연관 객체에 묶음에서 가장 부모가 되는 엔티티를 말한다고 한다.(하단링크 참조)

https://eocoding.tistory.com/36

 

DDD, Aggregate Root 란?

이번에 알아볼 것은, DDD란? Domain이란? Domain Model이란? DDD가 필요한 이유 DDD와 Aggregate Root DDD의 특징과 이유 간단히 영속성 전이, 고아 객체와의 연관 DDD(Domain Driven Design)란? 도메인 중심으로..

eocoding.tistory.com

 

Aggregate Root인 Recruitment 에서 cascade 적용

CascadeType을 ALL이 아니라 PERSIST로 한 건, 테스트 과정에서도 아직 persist 이외의 다른 동작이 필요한지 모르겠었어서이다. 나도모르게 CASCADE 기능을 사용하기보다 계속 개발을 진행하면서 나오는 상황에 '아 이럴 때 필요하구나'를 느끼고 싶어서 아직 PERSIST만 적용해 두었다.

 

 

앞으로 계획

이제 웹 계층을 설계하고 웹 템플릿 엔진을 이용해 렌더링 화면을 개발해야한다. 프론트 쪽 개발을 안해본지 너무 오래돼서 까먹은게 많은데 Thymeleaf 와 Mustache 중 무 엇을 선택할지는 아직도 고민이다. 비교적 최근에 공부한 Security를 통해서 code 방식의 OAuth 로그인 및 회원가입 개발을 가장 먼저 진행할 것 같다. 구현은 해보았지만 아직 완전하게 추상화 개념이 이해되지 않아서 다시 곱씹어가며 공부해야겠다.

 

또 까먹었었는데 테이블의 스키마 부분을 신경을 안썼다. 일단 그부분 먼저 추가하고 그 다음에 차근차근 웹계층 쪽을 개발해 나가야겠다!!

 

해당 프로젝트 gihub Repsitory:  https://github.com/unannn/Inside

 

GitHub - unannn/Inside: 지원서 서비스입니다.

지원서 서비스입니다. Contribute to unannn/Inside development by creating an account on GitHub.

github.com