부트캠프 19일차 후기
오늘 CodeKata는 2문제를 해결했다. 두 문제 다 구현에 시간이 좀 걸리는 문제라서 이렇게 되어버렸다.
새롭게 배운 내장함수는 distinct이다. Array에서 이 메소드를 사용하면 중복된 원소를 배제한 Array을 얻을 수 있는 편리한 함수이다. 문제를 해결하면서 점점 알게 되는 내장함수가 늘어나는데, 점점 이 내장함수들을 사용해서 시간단축을 했다고 느껴지고 있다. 특히 오늘 푼 두번째 문제는 Split와 distinct가 없었다면 시간이 엄청 걸렸을 거라 생각하니 아찔하다.
이어서 숙련 과제 Step2를 구현하였다. 처음부터 이전에 만든 Use Case Diagram과 ERD, API 명세서에 기능을 추가하는 방식으로 만들었고, 데이터베이스에 새로운 테이블을 추가하고 기존 테이블에 Column을 추가하고 구현을 시작하였다.
이때 기존 테이블에 Column을 추가 및 변경하는 방식을 알게 되었는데, 이전에는 귀찮아서 drop table <테이블 이름> 식으로 테이블을 삭제하고 테이블을 다시 만들었다. 그런데 늘 이런 방식이면 곤란했기에 구글링을 통해 배웠다.
PostgresSQL 기준으로 Column을 추가하기 위해선
alter table <테이블 이름>
add column <Column 이름> <데이터 타입>;
이 Query를 사용한다. 그리고 여기 외래키를 추가 하기 위해선
alter table <테이블 이름> add constrain <제약조건명>
foreign key(Column 이름) references 외부 테이블(외부 테이블 Column 이름)
이 Query를 사용한다. 이 방식과 유사하게 다른 제약조건(Primary Key 추가 등)도 추가 할 수 있다.
그렇게 코드를 짜기 시작하니 고민이 되는 부분이 있었다. Step2에 들어서면서 다른 테이블과의 연관관계를 설정하게 되면서 양방향으로 설정할지, 아니면 단방향으로 설정하지, 단방향을 설정한다면 "다대일"일지 혹은 "일대다"일지 고민하게 되었다. 일단 강의에서는 양방향으로 설정을 하였고, Cascade를 활용해서 Service를 구현하였다. 그런데 나는 이 방식에 약간의 불만이 있었다. 왜냐하면 1:N의 연관관계에서 1 쪽의 서비스 클래스에서 N을 관리하는 것이 걸리는 부분이였다 이왕이면 역할을 분리하는 게 좋지 않을까?란 생각에서 나는 다대일을 택하게 되었다. 그렇게 N과 관련된 Service를 따로 구현하였다.
구현을 어느정도 마치고 점검을 하는 단계를 거치고보니 N쪽의 Service 파트에서 코드가 반복되는 부분이 있었다. N과 연관관계를 맺은 1쪽의 엔티티가 존재하는지 점검하는 코드인데, 이 부분은 굳이 N 쪽의 Service에서 할 필요가 없었고 1 쪽의 Service에 이미 똑같은 코드가 존재했었다. 그래서 이것을 해결할 방법을 궁리하기 시작했다, 첫 번째는 관련 Util 클래스를 정의해서 가져와서 사용하는 방식이였다. 다만 Repository에 접근하는 클래스가 늘어나는 것은 되도록 회피하고 싶었다. 웬만하면 관련 Service만이 관련 Repository에 접근하는 방식이 유지보수 측면에서 낫다고 생각을 한 것이 그 이유이다.
그렇게 두 번째 방법을 떠올렸다, 기존에는 N쪽의 Service가 1쪽의 Repository를 직접 사용했었는데, 이번엔 1쪽의 Service를 간접적으로 사용하는 것이다. 그렇게 하면 해당 Service만이 그 Repository를 접근할 수 있고, 간접적으로 사용함으로써 점검된 클래스만을 접근하고 코드를 일원화해서 코드의 중복을 피할 수 있다는 장점을 취할 수 있다라고 생각했다. 단점으로는 DTO를 받는 형식이라 엔티티로 직접 접근하는 것보다는 불편하다. 그래도 이 방식이면 괜찮다고 생각해 Repository 대신 Service를 주입해 코드를 짰다. 그렇게 Step2를 구현하게 되었다.
이제 내일은 Step3를 구현을 해볼 것 같은데, 요구사항을 본 순간 QueryDSL이 떠올랐다. Kotlin에서 이걸 찾아서 사용할 지 아니면 그냥 jpql을 사용할 지는 고민을 해봐야겠다.