CQRS والخدمات الصغيرة في تطوير المنتجات

كيف تصمم منتجًا حتى لا تدفن المال في الأرض


في أي مرحلة من مراحل إنشاء منتج أو نظام لربط التصميم المعماري للنظام بحيث لا يكون مؤلمًا للغاية للأموال التي تنفق؟ كيفية تحديد ما إذا كان سيتم دمج CQRS والخدمات الصغيرة.


هذه المقالة مخصصة لممثلي الأعمال الذين يطلبون تطوير حل لتكنولوجيا المعلومات. سنوضح لك كيفية إطلاق منتج وتجنب التكاليف غير المبررة المرتبطة بالهندسة المعمارية. وانظر أيضًا كيف سيساعد استخدام CQRS في تنفيذ الوظائف في عملاء التطبيقات المختلفة ، وما إذا كانت الخدمات المصغرة هي العلاج الشافي.


باختصار حول CQRS


CQRS (فصل مسؤولية استعلام الأوامر) - قالب مستخدم في تطوير الأنظمة ، والذي ينص على أن أي طريقة من النظام يمكن أن تكون إما طلبًا (لا يغير حالة النظام) أو أمرًا (تغيير حالة النظام). كما تظهر الممارسة ، يعد هذا أحد الأنماط الأكثر استخدامًا في تطوير البرمجيات. يمكن استخدامه على مستويات مختلفة وفي مواقف مختلفة. على سبيل المثال ، التقسيم الكلاسيكي للأنظمة إلى OLTP / OLAP ، عندما تتم كتابة البيانات غالبًا إلى نظام OLTP وقراءتها من نظام OLAP ، ليس أكثر من استخدام قالب CQRS في بنية قاعدة البيانات.



“” ( 2000 ) CQRS. , Interbase/FirebirdSQL . . , , Query-, CRM- Command. CQRS JS . , JS … , , .



: A Big Ball of Mud



. , MVP , . , . — , . , . , .


, . , . , . .


: “ . , ”. , , , . “ ” . . . - , .



. , , . , . .


. , , . , . (Elastic ), - . , , - . , .


, , , . , - , - , . , . , , , .. 1 . - . , .


, , , , , . , . — . , , CAP-. , , .




/ . : , . .


/ , . . , , , .



, -, , , , . , -, (.. -), , , - .


, , . (.. ), , CRM- , . , , ..


?


- , , low-fidelity . Business Canvas ( ) , . , : -, . , . , . — ? : 2 . , , .


, . - - . , . , , (, COVID-19 !). CQRS .



- . CQRS .


:



, SOLID, Dependency Inversion Dependency Injection, , . , .


3 , :


  1. (Admin office Desktop App)
  2. (Ship Desktop Mechanic app)
  3. (SyncService)

, , , , . , Offline- , , . ? , , , . , — . - .


,


C#, .


/// <summary>
///       .
///       Composition Root(web api ,     ..)
/// </summary>
    public interface IHandlersFactory
    {
        IQueryHandler<TQuery, TResult> CreateQueryHandler<TQuery, TResult>();

        IAsyncQueryHandler<TQuery, TResult> CreateAsyncQueryHandler<TQuery, TResult>();

        ICommandHandler<TCommand> CreateCommandHandler<TCommand>();

        IAsyncCommandHandler<TCommand> CreateAsyncCommandHandler<TCommand>();
    }
/// <summary>
///       
/// </summary>
 public interface ICommandHandler<TCommand>
    {
        void Execute(TCommand command);
    }
/// <summary>
///       
/// </summary>

public interface IQueryHandler<TQuery, TResult>
    {
        TResult Execute(TQuery query);
    }

/// <summary>
///     Ninject,     
/// </summary>
public class NinjectFactory : IHandlersFactory
    {
        private readonly IResolutionRoot _resolutionRoot;

        public NinjectFactory(IResolutionRoot resolutionRoot)
        {
            _resolutionRoot = resolutionRoot;
        }

        public IAsyncCommandHandler<TCommand> CreateAsyncCommandHandler<TCommand>()
        {
            return _resolutionRoot.Get<IAsyncCommandHandler<TCommand>>();
        }

        public IAsyncQueryHandler<TQuery, TResult> CreateAsyncQueryHandler<TQuery, TResult>()
        {
            return _resolutionRoot.Get<IAsyncQueryHandler<TQuery, TResult>>();
        }

        public ICommandHandler<TCommand> CreateCommandHandler<TCommand>()
        {
            return _resolutionRoot.Get<ICommandHandler<TCommand>>();
        }

        public IQueryHandler<TQuery, TResult> CreateQueryHandler<TQuery, TResult>()
        {
            return _resolutionRoot.Get<IQueryHandler<TQuery, TResult>>();
        }
    }

Ninject


public override void Load()
        {
            // queries
            Bind<IQueryHandler<GetCertificateByIdQuery, Certificate>>().To<GetCertificateByIdQueryHandler>();
            Bind<IQueryHandler<GetCertificatesQuery, List<Certificate>>>().To<GetCertificatesQueryHandler>();
            Bind<IQueryHandler<GetCertificateByShipQuery, List<Certificate>>>().To<GetCertificateByShipQueryHandler>();
…………
}

IHandlerFactory :


:


Ship ship = mHandlersFactory.CreateQueryHandler<GetShipByIdQuery, Ship>().Execute(new GetShipByIdQuery(id));

:


mHandlersFactory.CreateCommandHandler<DeleteReportCommand>()
                    .Execute(new DeleteReportCommand(report));

, :


  1. , , .
  2. , , .
  3. , . /, . .
  4. , !

. . 300 . , 3 :


  1. - ? ?
  2. , ?
  3. ?

Bounded Context . , . .


CQRS


: MVVM, SOLID, CQRS .. . , .


, . : . , .



Agile- “ , , — ”. , — . , — . , , .


, . . -, . -, , . -, . , , .


All Articles