Como projetar um produto para não enterrar dinheiro no chão
Em que estágio da criação de um produto ou sistema para conectar o projeto arquitetônico do sistema, para que posteriormente não seja dolorosamente doloroso o dinheiro gasto? Como decidir se combina CQRS e microsserviços.
Este artigo é para representantes de negócios que solicitam o desenvolvimento de uma solução de TI. Mostraremos como lançar um produto e evitar custos injustificados associados à arquitetura. E veja também como o uso do CQRS ajudará na implementação da funcionalidade em diferentes clientes de aplicativos e se os microsserviços são a própria panacéia.
Brevemente sobre o CQRS
CQRS (Segregação de responsabilidade da consulta de comando) - um modelo usado no desenvolvimento de sistemas, que afirma que qualquer método do sistema pode ser uma solicitação (não alterando o estado do sistema) ou um comando (alterando o estado do sistema). Como mostra a prática, este é um dos padrões mais usados no desenvolvimento de software. Pode ser usado em diferentes níveis e em diferentes situações. Por exemplo, a divisão clássica de sistemas em OLTP / OLAP, quando os dados geralmente são gravados no sistema OLTP e lidos no sistema OLAP, nada mais é do que o uso do modelo CQRS na arquitetura do banco de dados.

“” ( 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 , :
- (Admin office Desktop App)
- (Ship Desktop Mechanic app)
- (SyncService)
, , , , . , Offline- , , . ? , , , . , — . - .
,
C#, .
public interface IHandlersFactory
{
IQueryHandler<TQuery, TResult> CreateQueryHandler<TQuery, TResult>();
IAsyncQueryHandler<TQuery, TResult> CreateAsyncQueryHandler<TQuery, TResult>();
ICommandHandler<TCommand> CreateCommandHandler<TCommand>();
IAsyncCommandHandler<TCommand> CreateAsyncCommandHandler<TCommand>();
}
public interface ICommandHandler<TCommand>
{
void Execute(TCommand command);
}
public interface IQueryHandler<TQuery, TResult>
{
TResult Execute(TQuery query);
}
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()
{
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));
, :
- , , .
- , , .
- , . /, . .
- , !
. . 300 . , 3 :
- - ? ?
- , ?
- ?
Bounded Context . , . .
CQRS
: MVVM, SOLID, CQRS .. . , .
, . : . , .
Agile- “ , , — ”. , — . , — . , , .
, . . -, . -, , . -, . , , .