CQRS et microservices dans le développement de produits

Comment concevoir un produit pour ne pas enfouir de l'argent dans le sol


À quelle étape de la création d'un produit ou d'un système pour relier la conception architecturale du système afin que cela ne soit pas atrocement douloureux pour l'argent dépensé? Comment décider de combiner CQRS et microservices.


Cet article est destiné aux représentants d'entreprises souhaitant développer une solution informatique. Nous vous montrerons comment lancer un produit et éviter les coûts injustifiés liés à l'architecture. Et voyez également comment l'utilisation de CQRS aidera à l'implémentation de fonctionnalités dans différents clients d'application, et si les microservices sont la panacée.


En bref sur le CQRS


CQRS (Command-Query Responsibility Segregation) - un modèle utilisé dans le développement de systèmes, qui stipule que toute méthode du système peut être soit une demande (ne pas changer l'état du système) ou une commande (changer l'état du système). Comme le montre la pratique, c'est l'un des modèles les plus couramment utilisés dans le développement de logiciels. Il peut être utilisé à différents niveaux et dans différentes situations. Par exemple, la division classique des systèmes en OLTP / OLAP, lorsque les données sont souvent écrites sur le système OLTP et lues à partir du système OLAP, n'est rien de plus que l'utilisation du modèle CQRS dans l'architecture de base de données.



“” ( 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