TopDev

Command Query Separation là gì ? CQS được sử dụng khi nào

minhu 📖 4 phút đọc

Command Query Separation (CQS) là một nguyên tắc trong lập trình hướng đối tượng, được đề xuất bởi Bertrand Meyer, nhấn mạnh việc tách biệt các phương thức thay đổi trạng thái của một đối tượng (commands) với các phương thức truy vấn dữ liệu mà không thay đổi trạng thái (queries).

Định nghĩa#

  • Command: Là các phương thức thực hiện một hành động và có thể thay đổi trạng thái của hệ thống. Các command không trả về giá trị, hoặc nếu có thì chỉ trả về thông tin về việc hành động đã được thực hiện thành công hay chưa.

  • Query: Là các phương thức truy vấn dữ liệu từ hệ thống mà không làm thay đổi trạng thái. Các query luôn trả về dữ liệu.

Khi nào sử dụng Command Query Separation?#

CQS được sử dụng khi bạn muốn:

  • Tăng tính rõ ràng và dễ hiểu của mã nguồn: Bằng cách tách biệt rõ ràng giữa các phương thức thay đổi trạng thái và các phương thức truy vấn, mã nguồn sẽ trở nên rõ ràng và dễ hiểu hơn.

  • Giảm thiểu lỗi do hiểu nhầm: Tránh được những lỗi do hiểu nhầm về việc một phương thức có thể thay đổi trạng thái của hệ thống hay không.

  • Dễ dàng bảo trì và mở rộng: Tách biệt rõ ràng giữa command và query giúp hệ thống dễ dàng bảo trì và mở rộng hơn.

Ví dụ minh họa#

Dưới đây là một ví dụ đơn giản về việc áp dụng CQS trong một lớp Account:

` public class Account { private double balance;

public Account(double initialBalance) {
    this.balance = initialBalance;
}

// Command: Thay đổi trạng thái của đối tượng
public void deposit(double amount) {
    if (amount > 0) {
        balance += amount;
    }
}

// Command: Thay đổi trạng thái của đối tượng
public void withdraw(double amount) {
    if (amount > 0 && amount <= balance) {
        balance -= amount;
    }
}

// Query: Truy vấn dữ liệu mà không thay đổi trạng thái
public double getBalance() {
    return balance;
}

} `

Command Query Responsibility Segregation (CQRS)#

CQS thường được sử dụng cùng với một kiến trúc mở rộng gọi là Command Query Responsibility Segregation (CQRS), trong đó việc tách biệt các command và query không chỉ áp dụng ở mức phương thức mà còn ở mức thành phần hệ thống. Trong CQRS:

  • Command: Được xử lý bởi một hệ thống hoặc mô-đun riêng biệt, chịu trách nhiệm về việc thay đổi trạng thái.

  • Query: Được xử lý bởi một hệ thống hoặc mô-đun riêng biệt, chịu trách nhiệm về việc trả về dữ liệu.

Khi nào sử dụng CQRS?#

CQRS được sử dụng khi bạn muốn:

  • Tối ưu hóa hiệu suất: Bằng cách tách biệt việc đọc và ghi, bạn có thể tối ưu hóa từng phần riêng biệt cho hiệu suất tốt nhất.

  • Cải thiện khả năng mở rộng: Việc tách biệt giúp dễ dàng mở rộng từng phần của hệ thống mà không ảnh hưởng đến phần còn lại.

  • Tăng cường bảo mật và quản lý quyền truy cập: Dễ dàng áp dụng các chính sách bảo mật và quản lý quyền truy cập khác nhau cho việc đọc và ghi.

  • Hỗ trợ các tình huống phức tạp: CQRS đặc biệt hữu ích trong các hệ thống có logic nghiệp vụ phức tạp hoặc yêu cầu cao về tính nhất quán và hiệu suất.

Ví dụ minh họa CQRS#

Giả sử bạn có một ứng dụng quản lý đơn hàng, bạn có thể tách biệt việc tạo đơn hàng (command) và truy vấn thông tin đơn hàng (query) như sau:

Command Side

` public class CreateOrderCommand { private String orderId; private List items;

public CreateOrderCommand(String orderId, List<String> items) {
    this.orderId = orderId;
    this.items = items;
}

// Getters

}

public class OrderService { public void handle(CreateOrderCommand command) { // Logic để tạo đơn hàng } } `

Query Side

public class OrderQueryService { public Order getOrder(String orderId) { // Logic để truy vấn thông tin đơn hàng return new Order(orderId, /* other details */); } }

Kết luận#

Command Query Separation là một nguyên tắc giúp tách biệt rõ ràng giữa các hành động thay đổi trạng thái và các truy vấn dữ liệu, giúp mã nguồn rõ ràng, dễ hiểu và dễ bảo trì hơn. Khi áp dụng cùng với CQRS, bạn có thể xây dựng các hệ thống phức tạp, tối ưu hóa hiệu suất, và cải thiện khả năng mở rộng của hệ thống.

Bài liên quan trong #Tin tức

✓ Đã sao chép link