Project Section - Main Project Week2 Review
메인 프로젝트의 본격적인 한 주가 지나갔다. 팀 빌딩도 끝났고, 요구사항 분석도 마무리했으며, 기본적인 설계도 마쳤다. 이번 주는 기본적으로 구현해야 하는 기능들에 대한 구현에 힘쓰는 한 주가 되었다. 구현과 동시에, 초기에 설정했던 설계에 문제는 없는지 계속해서 분석했다. 필요한 테이블은 전부 정의했는지, 불필요한 테이블을 추가로 정의한 것은 아닌지, 이 로직이 여기에 있는 것이 적절한지 등을 고민하며 구현을 진행했다.
당연히 초기의 설계 계획과 지금의 프로젝트 설계와는 차이가 많아졌다. 테이블로 정의했던 것들을 칼럼으로 빼기도 하고, 엔티티로 설계돼있던 객체를 Embeddable한 객체로 재설정해 조인 테이블정도로만 처리하기도 하고, 기존에는 없던 테이블을 추가하기도 했다. 이번 주 리뷰는 이러한 과정에서 어떤 선택을 왜 했었는지에 집중해보고자 한다.
그에 앞서 내가 맡았던 도메인이 무엇인지부터 살펴보아야 할 것이다. 지난 주차 리뷰에서 언급했듯이 우리는 간단하게 제조가 가능한 칵테일 레시피를 공유하는 서비스를 기획하였다. 내가 담당한 도메인은 칵테일이었다. 백엔드 팀장의 역할을 맡은만큼 가장 중요한 도메인 처리를 맡게되었고, 당연히 그만큼 해야할 일이 많았다.
처음에는 칵테일의 재료, 레시피, 베이스 술, 태그, 카테고리 등을 전부 테이블 처리하고자 하였다. 그러나 프론트엔드 측에서 태그나 재료, 베이스 술을 사용자가 마음대로 추가할 수 없게 하고 싶다고 하셨고, 카테고리도 하나의 카테고리에 담기는 데이터의 양을 고려하여 베이스 술 2개를 하나의 카테고리에 묶고자 하였다.
그래서 나는 기존에 엔티티로 설계되어있던 재료, 베이스 술, 카테고리, 태그를 전부 enum화 하고 칵테일의 칼럼과 조인테이블 정도로 처리했다. 사용자가 아닌 서버 차원에서만 추가나 삭제가 가능하고 크게 변경될 확률이 없기 때문에 설계 차원에서 얘들을 굳이 하나씩 테이블을 차지하게 만들어야 할 가치를 찾지 못했다. 그런데 우리에게 배정된 멘토님이 그러면 값이 바뀔 때마다 배포를 새로해야 하겠다는 말씀을 해주셨다. 해당 부분은 고려하지 못했던 부분이라 배포와 테이블 처리 중 어느 쪽에 더 무게를 실어야하나 고민해보았고, 재료 정도는 테이블 처리해 사용자가 마음대로 추가할 수 있게 하는게 좀 더 나을 것 같다는 결론을 내렸다. 태그, 베이스 술은 변동 가능성이 매우 적기 때문에 정말 필요한 경우에는 재배포를 해도 될 것 같았지만, 재료의 경우에는 훨씬 더 많은 경우의 수를 모두 담기 어렵다고 판단했기 때문이다. 아직은 기본적인 구현을 우선 완성하는 것을 목표로 해 적용하지 않았지만, 다음 주 리팩토링 및 심화 기능 구현 때 프론트엔드 측에 해당 의견을 제시할 예정이다.
다음으로 추천 칵테일을 새롭게 테이블로 정의했다. 원래는 칵테일 테이블에서 조건을 걸어서 조회하는 방식으로 추천 칵테일을 처리하고자 했는데, 추천 알고리즘에 조건이 많아지면서 해당 방법보다는 추천 칵테일을 조회하기 위한 새로운 테이블이 필요할 것 같다는 판단을 하게 되었다. 초기에는 단순히 별점이 높은 순서대로 추천해주는 로직을 생각했으나, 사용자의 나이대와 성별을 고려하여 해당 나이대와 성별의 사용들이 북마크한 횟수가 많은 칵테일을 추천하는 기능을 새롭게 적용하고자 하였다. 이를 위해서는 칵테일에서 사용자 정보를 가져오고 그 사용자 정보에서 또 나이와 성별 정보가 필요했다. 심지어 20대와 30대 등 나이대로 추천해주기 위해서는 또 다른 알고리즘을 요했다. 그렇게 처리하느니 새롭게 추천 칵테일을 테이블을 하나 만들어버리는게 낫겠다는 생각이 들었다. 문제는 조회 전용 테이블을 만들고자 했는데 결국에는 북마크 횟수에 따라 업데이트가 생긴다는 것이다. 어쨋든 북마크 횟수를 기준으로 다시 한 번 정렬해서 조회해야하기 때문에, 이를 처리하기 위해서는 사용자가 특정 칵테일 레시피를 북마크 할 때마다 해당 사용자와 칵테일 조건에 맞는 추천 칵테일을 찾아서 북마크 횟수를 +1 업데이트 해줘야한다. 이렇게 사용하는게 적절한 방법인지를 스스로 결정하는게 좀 어려워서 다음 주에 멘토님에게 여쭤볼 예정이다.
이번 주에 했던 가장 큰 고민들은 위의 두 가지였다. 사실 프로그램이 돌아가게 기능 구현만 하는 것은 굉장히 쉽다. 기능의 프로세스를 파악하고 그대로 작성만 하면 된다. 다만, 좋은 설계를 하는 것은 매우 어렵다. 기능과 책임, 역할에 따라 객체를 적절하게 분리하고, 필요한 정보에 따라 테이블을 잘 정의해야만이 이후의 추가적인 요구 사항의 변경에 유연하게 대처할 수 있을 것이다.
다음 주는 이를 위한 시간으로 만들고자 한다. 먼저 테스트 코드를 작성해 기능 테스트를 원활하게 한다. 그리고 잘 작성된 테스트의 힘을 바탕으로 마음 편하게 리팩토링을 진행한다. 또한 서버가 안정적으로 돌아가는지 확인하기 위한 로깅도 추가한다. 물론 기존의 코드는 리팩토링하면서, 동시에 추가적인 구현도 진행할 것이다.
단순 구현에 좀 더 힘썼던 이번 주와 달리, 다음 주는 좀 더 깊지만 즐거운 고민과 고뇌의 시간이 기다리고 있을 것이다. 벌써부터 다음 주가 기대된다. 일단은 다음 주를 위해 주말동안 뇌를 좀 쉬게 해줘야겠다.