Mybatis를 사용했을 땐 사실 CQRS의 필요성을 느끼지 못 했다. 근데 JPA를 공부하고 JPQL을 공부 해보니 CQS에 대해 알게 되었고 실제로 적용해보니 좀 자연스럽게 커맨드와 쿼리를 나누는 것을 생각하게 되었다. 근데 왜 CQS가 아닌 CQRS를 이용해서 분리 했는지 말해보고자 한다.
CQS는 명령과 조회는 분리 되어야 한다는 개념이다.
클래스의 필드 값을 조회할 때 getter, 수정 할 때 setter를 사용하는데 이 것도 하나의 CQS 패턴이다. 하지만 setter는 값을 수정만 해야지 반환 하는 값이 있으면 안된다.
public class Member {
private String name;
private int age;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
CQRS는 CQS 개념을 포함하고 있고 있으며 CQS는 연산 수준에서 명령과 조회를 분리 했다면 CQRS는 객체 수준에서 명령과 조회를 분리하는 것이다.
CQRS를 이용한다면 명령(CUD)과 조회(R) 기능이 객체 수준에서 분리 되니, 기능이 많아져도 유지보수 하는 점에 있어서 분리되어 있어 유리하고 코드의 명확성이 높아진다.
// CQRS 적용 전
class MemberService{};
// CQRS 적용 후
class MemberCommendService{};
class MemberQueryService{};
서론에서 한번 언급 했듯 Mybatis를 사용했을 땐 명령과 조회를 분리 해야겠다는 필요성을 잘 못느꼈다.
근데 JPA를 사용하니 복잡한 조회는 JPQL을 사용을 해야 했고, JPQL의 프레임워크로 QueryDSL을 사용하게 되니 자연스럽게 Repository 부터 분리하여 사용하게 됐다.
Repository를 분리하여 사용하게 되니 Service 레이어 역시 같이 나눠서 사용하는게 관리하는 게 편할 것 같았기 때문에 CRQS를 Service 레이어 부터 적용하게 됐다.