CQS(Command Query Separation) 원칙이란?

Daniel·2024년 8월 12일
0

Back-End

목록 보기
41/54

소프트웨어 설계에서 꼭 알아야 할 원칙 중 하나인 CQS는 "명령과 조회를 분리하라"는 개념이다.
이 원칙을 따르면 코드의 명확성, 유지보수성, 테스트 용이성이 향상된다.

이번 포스트에서는 CQS의 개념과 적용 방법, 장단점을 예제와 함께 정리해보자.

CQS란?

CQS는 Command Query Separation의 줄임말로, "하나의 메서드는 상태를 변경하거나, 상태를 반환하거나 둘 중 하나만 해야 한다"는 원칙이다.

상태를 변경하면서 동시에 값을 반환하는 메서드는 CQS 위반이다.

이 원칙은 객체의 명령(변경)질의(조회)의 책임을 명확히 분리함으로써 코드의 명확성을 높인다.

Command (명령)

  • 객체의 상태를 변경한다.
  • 값을 반환하지 않는다 (반환한다면 성공 여부 정도만 허용).
  • 주로 void 메서드 형태로 구성된다.
// Command
public class AddUserCommand {
	private String username;
	private String password;

	public AddUserCommand(String username, String password) {
		this.username = username;
		this.password = password;
	}

	public String getUsername() { return username; }
	public String getPassword() { return password; }
}
// Command Handler
public class UserCommandHandler {
	public void handleAddUserCommand(AddUserCommand command) {
		// 실제로는 DB 저장 로직 등이 들어감
		System.out.println("User added: " + command.getUsername());
	}
}
// 실행
UserCommandHandler handler = new UserCommandHandler();
handler.handleAddUserCommand(new AddUserCommand("john123", "password"));

Query (조회)

  • 객체의 상태를 조회한다.
  • 상태를 변경하지 않는다.
  • 데이터를 반환한다.
// Query
public class GetUserQuery {
	private String username;

	public GetUserQuery(String username) {
		this.username = username;
	}

	public String getUsername() { return username; }
}
// Query Handler
public class UserQueryHandler {
	public String handleGetUserQuery(GetUserQuery query) {
		String userDetails = "User details for username: " + query.getUsername();
		System.out.println(userDetails);
		return userDetails;
	}
}
// 실행
UserQueryHandler handler = new UserQueryHandler();
String result = handler.handleGetUserQuery(new GetUserQuery("john123"));
System.out.println(result);

CQS를 왜 지켜야 할까?

✅ 장점

  • 관심사 분리 → 코드의 역할이 명확해짐
  • 단일 책임 원칙(SRP)에 부합
  • 유닛 테스트 작성 용이 → Command와 Query 각각 테스트 가능
  • 읽기/쓰기 작업을 개별 최적화 가능

⚠️ 단점

  • Command, Query를 별도로 구성해야 하므로 구조가 복잡해질 수 있음
  • 유지보수 오버헤드 발생 가능 (특히 작은 프로젝트에서는 과하다고 느껴질 수 있음)
  • 중복 코드가 생길 여지도 있음

언제 써야 할까?

  • 복잡한 도메인 로직을 가진 서비스, 예: 도메인 주도 설계(DDD)
  • 읽기/쓰기 성능 요구가 다른 경우
  • 명확한 역할 분리가 필요한 대규모 시스템

마무리

CQS는 처음엔 조금 과해 보일 수 있지만, 프로젝트가 커질수록 그 가치가 드러난다.
특히 객체 설계를 명확히 하고, 테스트 가능성을 높이고 싶은 개발자에게는 꼭 고려해야 할 설계 원칙이다.

“읽기와 쓰기를 명확히 나누는 것, 그 단순한 원칙이 코드 전체의 복잡도를 줄여준다.”

profile
응애 나 애기 개발자

0개의 댓글