이 프로젝트는 전형적인 MVC 패턴을 따라 Controller, Service, Repository 의 3 계층으로 나누어 구현하고 있었다. Repository, Service 를 먼저 구현하고 이를 Controller와 연결하여 API를 구현하기로 했다.
이를 위해 회원을 표현하는 Member 클래스를 아래와 같이 작성하고 이를 Repository와 Service 에서 사용하여 기능을 구현하였다.
그렇게 모든 Service와 Repository를 구현한 상태에서 Member 클래스 하나만으로 모든 회원 관련 정보를담아내는 것은 문제가 있음을 깨달았다. 예를 들어 자신의 정보를 조회하는 경우 등록된 이메일을 포함해야 하지만, 채팅 상대방을 조회할때에는 포함되면 안되는 점이 있다. 따라서 두 API 의 응답은 별도의 클래스로 분리되어 있어야 마땅하다.
InteliJ Member 클래스의 사용위치를 보면 무려 135군데에서 사용중이라고 한다.. 즉, 이미 이 클래스와 다른 클래스들은 강하게 결합되어있고, 이 클래스를 수정하기가 매우 매우 매우 까다롭게 되어있다.
Member 클래스를 적절한 책임에 따라 분리하기에는 Member 클래스를 사용한 Service, Repository 들은 정상 작동하고 있음을 이미 확인한 상태라 이제와서 바꿀 수도 없는 노릇이었다. 그렇게 이러지도 저러지도 못하던 와중에 그나마 괜찮은 아이디어가 생각났다.
그것은 바로 Member 클래스를 한번 더 감싸는 것이었다. 코드를 보자.
package com.oclock.oclock.dto.response;
import com.oclock.oclock.dto.Member;
import lombok.Getter;
@Getter
public class OtherInfoDto {
private String nickName;
private int major;
private int sex;
public OtherInfoDto(Member member){
nickName = member.getNickName();
major = member.getMajor();
sex = member.getMemberSex();
}
}
이 클래스는 채팅 상대방의 정보를 담는 클래스이다. 생성자에 Member 클래스를 파라미터로 받아 필요한 값만 추출해 다시 자신의 필드에 저장하는 구조를 가지고 있다. 이를 이용해 Member 클래스는 물론, 그와 결합된 이미 완성된 클래스들은 수정하지 않고 오직 Controller 단에서 new OtherInfoDto(member);
한줄로 문제를 해결할 수 있었다.
<aside> ❗ 결국, 이번 문제의 근본적인 원인은 하나의 클래스에 너무 많은 역할이 부여되어 있어서 발생한 것이다.
</aside>
이번 문제를 해결한 방법도 Member 클래스로부터 OtherInfoDto 라는 클래스를 분리한 것이다. 관련 자료를 찾다보니, Entity 라는 개념이 따로 있었다.
<aside> 💡 데이터베이스 설계할때 E-R 다이어그램을 그린다. 이때, E 가 Entity 이다. 즉, 데이터베이스에서 저장할 대상이 되는 것을 Entity라 하는데, 이를 자바의 클래스로 옮긴 것을 Entity 클래스 라고 부른다.
</aside>