پرشین تم مقالات 🧩 CQRS چیست؟

🧩 CQRS چیست؟

image profile پرشین تم - 24 شهریور 1404 - 18:19 دانلود مقاله

هرCQRS یک الگوی طراحی نرم‌افزار است که عملیات خواندن (پرس‌وجوها) را از عملیات نوشتن (دستورات) جدا می‌کند. به جای استفاده از یک مدل برای مدیریت دو، آنها را به دو مدل مجزا تقسیم می‌کنید:

🧩 CQRS چیست؟

- دستورات: وضعیت سیستم را تغییر می‌دهند (مثلاً ایجاد، به‌روزرسانی، حذف).

- پرس‌وجوها: داده‌ها را بدون تغییر آن بازیابی می‌کنند.

این جداسازی به هر طرف اجازه می‌دهد تا به طور مستقل برای عملکرد، مقیاس‌پذیری و امنیت بهینه شود.

 

🏗️ چرا از CQRS استفاده کنیم؟

سیستم‌های CRUD سنتی از یک مدل برای همه چیز استفاده می‌کنند که می‌تواند منجر به موارد زیر شود:

  • گلوگاه‌های عملکرد هنگام رقابت عملیات خواندن و نوشتن.
  • مدل‌های داده پیچیده که سعی در برآورده کردن نیازهای متناقض دارند.
  • خطرات امنیتی ناشی از همپوشانی الگوهای دسترسی.

CQRS این مشکل را با فراهم کردن موارد زیر حل می‌کند:

  • مقیاس‌بندی خواندن و نوشتن به صورت مستقل.
  • استفاده از پایگاه‌های داده یا ساختارهای داده مختلف برای هر کدام.
  • ساده‌سازی منطق کسب‌وکار با هماهنگ‌سازی دستورات با اقدامات دنیای واقعی

 

🔧 اجزای اصلی

  • Command: نشان‌دهنده‌ی قصد تغییر وضعیت است (مثلاً CreateOrder)
  • Command Handler: دستور را پردازش کرده و تغییرات را اعمال می‌کند.
  • Query: داده‌ها را بازیابی می‌کند (مثلاً GetOrderDetails)
  • Query Handler: دستور را اجرا کرده و نتایج را برمی‌گرداند.
  • Event: پس از پردازش یک دستور منتشر می‌شود (در Event Sourcing استفاده می‌شود).

 

🚀 چه زمانی از CQRS استفاده کنیم

CQRS در سناریوهایی مانند موارد زیر می‌درخشد:

  • منطق تجاری پیچیده که در آن خواندن و نوشتن تفاوت قابل توجهی دارند.
  • سیستم‌های با کارایی بالا با ترافیک خواندن سنگین.
  • معماری‌های رویداد محور یا سیستم‌هایی که از Event Sourcing استفاده می‌کنند.

اما مراقب باشید - این پیچیدگی را افزایش می‌دهد. برای برنامه‌های ساده CRUD، ممکن است بیش از حد باشد.

 

مثال عملی 

در ادامه یک مثال عملی از پیاده سازی CQRS را ارائه می دهیم.

🧱 نمای کلی ساختار پروژه

/Domain
  Product.cs
/Application
  /Commands
    CreateProductCommand.cs
    CreateProductHandler.cs
  /Queries
    GetProductByIdQuery.cs
    GetProductByIdHandler.cs
/Core
  ICommand.cs
  IQuery.cs
  ICommandHandler.cs
  IQueryHandler.cs
  Dispatcher.cs
/Infrastructure
  ProductDbContext.cs
  ProductRepository.cs

 

1️⃣ تعریف اینترفیس های اصلی

// Core/ICommand.cs
public interface ICommand { }

// Core/IQuery<TResult>.cs
public interface IQuery<TResult> { }

// Core/ICommandHandler.cs
public interface ICommandHandler<TCommand>
    where TCommand : ICommand {
    Task HandleAsync(TCommand command);
}

// Core/IQueryHandler.cs
public interface IQueryHandler<TQuery, TResult>
    where TQuery : IQuery<TResult> {
    Task<TResult> HandleAsync(TQuery query);
}

 

2️⃣ ایجاد یک Dispatcher

// Core/Dispatcher.cs
public class Dispatcher {
    private readonly IServiceProvider _provider;
    public Dispatcher(IServiceProvider provider) {
        _provider = provider;
    }

    public Task SendAsync<TCommand>(TCommand command) where TCommand : ICommand {
        var handler = _provider.GetRequiredService<ICommandHandler<TCommand>>();
        return handler.HandleAsync(command);
    }

    public Task<TResult> QueryAsync<TQuery, TResult>(TQuery query) where TQuery : IQuery<TResult> {
        var handler = _provider.GetRequiredService<IQueryHandler<TQuery, TResult>>();
        return handler.HandleAsync(query);
    }
}

 

3️⃣ Domain Model

// Domain/Product.cs
public class Product {
    public Guid Id { get; set; }
    public string Name { get; set; } = string.Empty;
    public decimal Price { get; set; }
}

 

4️⃣ Command & Handler

// Application/Commands/CreateProductCommand.cs
public class CreateProductCommand : ICommand {
    public string Name { get; set; } = string.Empty;
    public decimal Price { get; set; }
}

// Application/Commands/CreateProductHandler.cs
public class CreateProductHandler : ICommandHandler<CreateProductCommand> {
    private readonly ProductDbContext _context;
    public CreateProductHandler(ProductDbContext context) {
        _context = context;
    }

    public async Task HandleAsync(CreateProductCommand command) {
        var product = new Product {
            Id = Guid.NewGuid(),
            Name = command.Name,
            Price = command.Price
        };

        _context.Products.Add(product);
        await _context.SaveChangesAsync();
    }
}

 

5️⃣ Query & Handler

// Application/Queries/GetProductByIdQuery.cs
public class GetProductByIdQuery : IQuery<Product?> {
    public Guid Id { get; set; }
}

// Application/Queries/GetProductByIdHandler.cs
public class GetProductByIdHandler : IQueryHandler<GetProductByIdQuery, Product?> {
    private readonly ProductDbContext _context;

    public GetProductByIdHandler(ProductDbContext context) {
        _context = context;
    }

    public async Task<Product?> HandleAsync(GetProductByIdQuery query) {
        return await _context.Products.FindAsync(query.Id);
    }
}

 

6️⃣ Register Services

// Program.cs
builder.Services.AddDbContext<ProductDbContext>(opt =>
    opt.UseInMemoryDatabase("ProductDb"));

builder.Services.AddScoped<Dispatcher>();
builder.Services.AddScoped<ICommandHandler<CreateProductCommand>, CreateProductHandler>();
builder.Services.AddScoped<IQueryHandler<GetProductByIdQuery, Product?>, GetProductByIdHandler>();

 

7️⃣ Controller Example

// Controllers/ProductController.cs
[ApiController]
[Route("api/[controller]")]
public class ProductController : ControllerBase {
    private readonly Dispatcher _dispatcher;
    public ProductController(Dispatcher dispatcher) {
        _dispatcher = dispatcher;
    }

    [HttpPost]
    public async Task<IActionResult> Create(CreateProductCommand command) {
        await _dispatcher.SendAsync(command);
        return Ok();
    }

    [HttpGet("{id}")]
    public async Task<IActionResult> GetById(Guid id) {
        var product = await _dispatcher.QueryAsync<GetProductByIdQuery, Product?>(new GetProductByIdQuery { Id = id });
        return product is null ? NotFound() : Ok(product);
    }
}
با خرید اشتراک می توانید تا چندین برابر مبلغ خرید اشتراک خود قالب های HTML ، سورس کدهای آماده و یا مقالات دانلود کنید
شما می توانید تنها فقط با مبلغ 3,000,000 میلیون تومان وب سایت سفارسی برای خود داشته باشید
محبوب ترین مقالات
تفاوت بین CSS و SCSS چیست؟ تفاوت بین CSS و SCSS چیست؟
category برنامه نویسی 07 اسفند 1402
تفاوت بین RDBMS و DBMS تفاوت بین RDBMS و DBMS
category برنامه نویسی 02 فروردین 1403
کاوش در معماری GPT-3 کاوش در معماری GPT-3
category هوش مصنوعی 12 اسفند 1402
کلمات کلیدی در SQL کلمات کلیدی در SQL
category برنامه نویسی 01 خرداد 1403
تفاوت بین CSS، SASS و SCSS چیست؟ تفاوت بین CSS، SASS و SCSS چیست؟
category برنامه نویسی 13 اسفند 1402
انواع Join در SQL انواع Join در SQL
category برنامه نویسی 02 فروردین 1403
ChatGPT چیست؟ ChatGPT چیست؟
category هوش مصنوعی 12 اسفند 1402
آخرین مقالات
🎨 نظریه یا تئوری طراحی چیست؟ 🎨 نظریه یا تئوری طراحی چیست؟ نظریه طراحی چارچوب فکری است که نحوه درک، خلق و ارزیابی طراحی را هدایت می‌کند. این نظریه، فلسفه، زیبایی‌شناسی، عملکرد و...
category کامپیوتر 05 مرداد 1404
سفر من به داستان‌سرایی بصری - طراحی رابط کاربری و طراحی لوگو سفر من به داستان‌سرایی بصری - طراحی رابط کاربری و طراحی لوگو چگونه سفر خود را به سمت طراحی لوگو، گرافیک و رابط کاربری/تجربه کاربری آغاز کنید. برای موفقیت در طراحی لوگو، طراحی گراف...
category کامپیوتر 02 مرداد 1404
🧠 درک هوش مصنوعی- از مبانی تا مرزها 🧠 درک هوش مصنوعی- از مبانی تا مرزها هوش مصنوعی تقریباً هر صنعتی را تغییر شکل می‌دهد، در این مقاله با یک مرور کلی آکادمیک سطح بالا شروع کنیم و آن را به بخش...
category هوش مصنوعی 27 تیر 1404