CQRS, or Command Query Responsibility Segregation, is a design pattern that separates the responsibilities of reading and writing data in a software system. Here’s a breakdown of its key concepts:
Key Concepts
Separation of Concerns:
- Commands: These are actions that change the state of the system (e.g., creating, updating, or deleting data). They do not return data.
- Queries: These are operations that retrieve data without altering the system’s state. They are designed for read operations.
Here's a simple example of implementing the CQRS pattern in C#:
// Command
public class CreateProductCommand
{
public string Name { get; set; }
public decimal Price { get; set; }
}
// Command Handler
public class CreateProductCommandHandler
{
public void Handle(CreateProductCommand command)
{
// Logic to create a new product and update the state
// This might involve validation, persistence, and other business logic
Console.WriteLine($"Product '{command.Name}' created successfully with price {command.Price}");
}
}
// Query
public class GetProductQuery
{
public int ProductId { get; set; }
}
// Query Handler
public class GetProductQueryHandler
{
public Product Handle(GetProductQuery query)
{
// Logic to retrieve product information from the state
// This might involve querying a database, caching, or other mechanisms
return new Product
{
ProductId = query.ProductId,
Name = "Sample Product",
Price = 29.99m
};
}
}
// Model
public class Product
{
public int ProductId { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
}
// Example Usage
class Program
{
static void Main()
{
// Command side usage
var createProductCommand = new CreateProductCommand
{
Name = "Example Product",
Price = 49.99m
};
var createProductHandler = new CreateProductCommandHandler();
createProductHandler.Handle(createProductCommand);
// Query side usage
var getProductQuery = new GetProductQuery
{
ProductId = 1
};
var getProductHandler = new GetProductQueryHandler();
var product = getProductHandler.Handle(getProductQuery);
Console.WriteLine($"Product Name: {product.Name}, Price: {product.Price}");
}
}
In this example, the CreateProductCommand represents a command for creating a new product, and the CreateProductCommandHandler handles this command, updating the system state accordingly. On the query side, the GetProductQuery represents a query to retrieve product information, and the GetProductQueryHandler handles this query, providing the necessary data from the system state. The Product class is a simple model representing a product.
Benefits:
- Scalability: By separating reads and writes, you can optimize each side independently. For instance, you might use different data stores or caching mechanisms for reading.
- Performance: Read and write models can be tailored for their specific tasks, potentially improving performance.
- Flexibility: Allows for different data models for reads and writes, which can simplify complex domains.
Reference: https://www.c-sharpcorner.com
0 comments:
Post a Comment