일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- publicapi
- Velog
- 정적중첩클래스
- privateapi
- 스프링컨테이너
- 인수테스트
- github actions
- 서버사이드렌더링
- 클라이언트사이드렌더링
- 애너테이션
- java
- SOLID
- IoC
- 변경감지
- 자바의정석
- 다형성
- 항해99
- refreshtoken
- 더티채킹
- 일급컬렉션
- 스파르타코딩클럽
- DI
- 항해99 9기
- 싱글톤패턴
- bean
- 인프콘
- 비정적중첩클래스
- 9기
- Spring
- 지네릭스
- Today
- Total
멈재
[JAVA/Spring] 10. CQS 패턴 (Command Query Separation) 본문
여러 디자인 패턴을 들어보긴 했지만, CQS 패턴은 나에게는 다소 생소한 패턴 중 하나이다.
디자인 패턴은 프로그램을 개발하는 과정에서 빈번하게 발생하는 디자인 상의 문제를 정리해서, 상황에 따라 간편하게 적용해서 쓸 수 있는 패턴 형태로 만든 것이다. - 헤드퍼스트 디자인 패턴 中 -
시간적 여유가 난다면 가장 먼저 다루고 싶었던 것이 바로 이 CQS 패턴이었다.
김영한 님의 스프링 로드맵에서 가끔 "커맨드와 쿼리를 분리시켜라."는 말을 들었는데, 그것이 바로 이 CQS 패턴을 말한 것이었다.
참고: https://www.inflearn.com/questions/27795/cqrs
CQS 패턴은 소프트웨어 디자인 패턴 중 하나로, 모든 객체의 메소드 작업을 수행하는 Command, 데이터를 반환하는 Query, 이렇게 2개로 구분하는 디자인 패턴이다.
다시 말하면, CQS는 객체의 모든 메서드를 Command와 Query 두 가지로 구분해야 하며, 하나의 메서드는 반드시 Command나 Query 둘 중 하나에만 속해야 한다는 걸 의미한다.
Command란?
Command는 객체의 상태를 변경하는 메서드로 값을 반환하지 않는다.
이 말을 즉슨, 시스템에 어떠한 side effect를 가하는 행위에서는 값을 반환하지 않아야 한다는 것이다.
void decreaseStock() { // OK
stock = stock - 1;
}
Integer decreaseStock() { // NO
return stock = stcok - 1;
}
Query란?
Query는 객체 내부 상태를 바꾸지 않고 객체의 값을 반환하기만 한다.
이 말은 즉슨, 상태를 변경시키지 않아야 하고, 시스템의 상태를 단지 반환만 해야 한다.
Product getProduct(Long productId) { // OK
return products.get(productId);
}
void getProduct(Long productId) { // NO
Product product = products.get(productId);
product.updateModifiedAt();
return product;
}
만약 하나의 함수에서 Command와 Query가 모두 동시에 일어나게 된다면, CQS 패턴을 지키지 못한 것이다.
거기다가 SOLID 원칙과 소프트웨어의 3가지 원칙 중 KISS(Keep It Simple, Stupid)가 지켜지지 않은 코드일 것이다.
SOLID 원칙이 위배되면 예상치 못한 side effect가 발생하고, 이는 예기치 못한 결과로 이어지기 때문에 CQS 패턴을 지킨다면 SOLID 원칙에 위배되지 않게 코드를 작성하는데 도움을 줄 수 있다.
그래서 CQS 패턴을 사용했을 때의 장단점도 알아보자.
장점
"읽기"와 "쓰기"를 분리할 수 있다.
즉, 읽기와 쓰기가 동시에 일어나지 않기 때문에 성능 최적화에 용이하고 읽기 편해진다.
단점
관리해야 하는 객체가 많아질 수록 Query, Command가 많아지기 때문에 중복 코드가 발생할 수 있고, 이에 따라 유지보수하는데 많은 노력이 들어갈 수 있다.
정리하면, Command와 Query를 분리함으로써 각 메서드의 의미를 명확하게 해주고, side effect가 발생할 수 있는 코드(Command)와 그렇지 않은 코드(Query)를 분리한다.
참고
https://medium.com/@su_bak/cqs-command-query-separation-pattern-이란-f701eabf8754
https://dundung.tistory.com/183
https://velog.io/@stella317/Spring-CQSCommand-Query-Separation
'JAVA & Spring & JPA' 카테고리의 다른 글
[Spring/JPA] 14. AttributeConverter로 코드의 가독성을 높여보자 (0) | 2022.12.20 |
---|---|
[JAVA] 13. JAVA의 HashSet은 어떻게 동작할까? (1) | 2022.12.19 |
[JAVA] 08. 일급 컬렉션(First Class Collection) (0) | 2022.10.19 |
[JAVA/Spring] 07. MVC 패턴 (추가 예정) (0) | 2022.10.17 |
[JAVA/Spring] 04. DI & IoC & Bean - 1 (0) | 2022.10.09 |