tag:blogger.com,1999:blog-88464123942329795792024-03-20T08:37:58.646-07:00DesenvolveloperAntônio Fláviohttp://www.blogger.com/profile/00669972471874904233noreply@blogger.comBlogger1125tag:blogger.com,1999:blog-8846412394232979579.post-92069166166751378072015-01-22T07:37:00.003-08:002021-03-03T18:40:44.080-08:00CQRS<div class="MsoNormal" style="margin-bottom: 0cm;">
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div class="MsoNormal" style="margin-bottom: 0cm;">
<div style="text-align: justify;">
<span face="Trebuchet MS, sans-serif" style="color: #444444;">CQRS significa "Segregação de Responsabilidade entre Comando e Consulta</span><span style="color: #444444;">" (do inglês Command Query Resposibility
Segregation). É um padrão que ouvi pela primeira vez descrito por Greg Young.
Segundo ele é a simples noção de que você pode usar um modelo diferente, para
atualizar informações, do modelo que você usa para ler as informações. Esta
simples ideia leva à algumas profundas consequências para o projeto de sistemas
de informação.</span></div>
</div>
<div class="MsoNormal" style="margin-bottom: 0cm;">
<div style="text-align: justify;">
<span face="Trebuchet MS, sans-serif" style="color: #444444;"><br /></span></div>
</div>
<div class="MsoNormal" style="margin-bottom: 0cm;">
<div style="text-align: justify;">
<span face="Trebuchet MS, sans-serif" style="color: #444444;">A abordagem tradicional que as pessoas usam para
interagir com um sistema de informação é tratar isto como um armazenamento de
dados CRUD. Com isto eu digo que nós temos um modelo mental de alguma estrutura
de registro onde nós podemos criar novos registro, ler registros, atualizar
registros existentes e excluir registros quando terminarmos com eles. Em um
simples caso, nossas interações são todas sobre o armazenamento e recuperação
destes registros.<o:p></o:p></span></div>
</div>
<div class="MsoNormal" style="margin-bottom: 0cm;">
<div style="text-align: justify;">
<span face="Trebuchet MS, sans-serif" style="color: #444444;"><br /></span></div>
</div>
<div class="MsoNormal" style="margin-bottom: 0cm;">
<div style="text-align: justify;">
<span face="Trebuchet MS, sans-serif" style="color: #444444;">Como nossas necessidades se tornam mais sofisticadas,
nós constantemente afastamos desse modelo. Nós podemos querer ver as informações
em um caminho diferente da base de registros, talvez unindo muitos registros em
um, ou formando registros virtuais para combinar informações em diferentes
lugares. Do lado da atualização nós podemos buscar regras de validação que
permita apenas certas combinações de dados para ser armazenado, ou podemos até
mesmo inferir que os dados sejam armazenados de forma diferente do que nós
fornecemos.<o:p></o:p></span></div>
</div>
<div class="MsoNormal" style="margin-bottom: 0cm;">
<div style="text-align: justify;">
<span face="Trebuchet MS, sans-serif" style="color: #444444;"><br /></span></div>
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmsM1q2xupXdnfmA9fbAkc5aSbKaTouwxaYlCIpHKBdK5NEFKp0WPZ52gP49y5PcHuA8NSY_9MnfO80Nbad-szesPqyf8_F-QO-CSCHpK-gdxYTatEuV6to31Ea7tMd8Jqa7aGBOmy9-TC/s1600/Explicacao_CQRS.png" style="margin-left: 1em; margin-right: 1em;"><span face="Trebuchet MS, sans-serif" style="color: #444444;"><img border="0" height="262" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmsM1q2xupXdnfmA9fbAkc5aSbKaTouwxaYlCIpHKBdK5NEFKp0WPZ52gP49y5PcHuA8NSY_9MnfO80Nbad-szesPqyf8_F-QO-CSCHpK-gdxYTatEuV6to31Ea7tMd8Jqa7aGBOmy9-TC/s1600/Explicacao_CQRS.png" width="400" /></span></a></div>
<div class="MsoNormal" style="margin-bottom: 0cm;">
<div style="text-align: justify;">
<span face="Trebuchet MS, sans-serif" style="color: #444444;"><br /></span></div>
</div>
<div class="MsoNormal" style="margin-bottom: 0cm;">
<div style="text-align: justify;">
<span face="Trebuchet MS, sans-serif" style="color: #444444;"> </span></div>
</div>
<div class="MsoNormal" style="margin-bottom: 0cm;">
<div style="text-align: justify;">
<span face="Trebuchet MS, sans-serif" style="color: #444444;">Como isso acontece, nós começamos a ver várias
representações da informação. Quando usuários interagem com a informação eles
usam várias apresentações para esta informação, cada uma das quais é uma
apresentação diferente. Desenvolvedores geralmente constroem seu próprio modelo
conceitual que eles usam para manipular os elementos centrais do modelo. Se você
estiver usando um modelo de domínio, então isso é geralmente sua representação
conceitual do domínio. Você normalmente também faz a armazenamento de
persistência o mais próximo do modelo conceitual que você puder.<o:p></o:p></span></div>
</div>
<div class="MsoNormal" style="margin-bottom: 0cm;">
<div style="text-align: justify;">
<span face="Trebuchet MS, sans-serif" style="color: #444444;"><br /></span></div>
</div>
<div class="MsoNormal" style="margin-bottom: 0cm;">
<div style="text-align: justify;">
<span face="Trebuchet MS, sans-serif" style="color: #444444;">Esta estrutura de muitas camadas de apresentação pode
ficar muito complicada, mas quando as pessoas fazem isto elas ainda simplificam
para uma única representação conceitual que atua como um ponto de integração
conceitual entre todas as apresentações.<o:p></o:p></span></div>
</div>
<div class="MsoNormal" style="margin-bottom: 0cm;">
<div style="text-align: justify;">
<span face="Trebuchet MS, sans-serif" style="color: #444444;"><br /></span></div>
</div>
<div class="MsoNormal" style="margin-bottom: 0cm;">
<div style="text-align: justify;">
<span face="Trebuchet MS, sans-serif" style="color: #444444;">A mudança que o CQRS introduz é dividir esse modelo
conceitual e separá-los em modelo para atualização e exibição, que ele se
refere como Command e Query respectivamente seguindo o vocabulário de
CommandQuerySeparation. A justificativa é que para muitos problemas,
particularmente em domínios mais complicados, tendo o mesmo modelo conceitual
para comandos e consultas leva a um modelo mais complexo que não faz bem.<o:p></o:p></span></div>
</div>
<div class="MsoNormal" style="margin-bottom: 0cm;">
<div style="text-align: justify;">
<span face="Trebuchet MS, sans-serif" style="color: #444444;"><br /></span></div>
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfIGfEA2LkB1eOf8ObI7vP8QBvQeUROVWC3fHjg1Bvoeu7ERUHpD8yteVQJIjye4eISs_cNO8z1zBfbFoFw0-MhHD9rcS3es0Q4XP4aLj6ehJ4XZ4E4Yvdv3rz2hu5tehT7RBm_DO5_DDV/s1600/Explicacao2_CQRS.png" style="margin-left: 1em; margin-right: 1em;"><span face="Trebuchet MS, sans-serif" style="color: #444444;"><img border="0" height="281" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfIGfEA2LkB1eOf8ObI7vP8QBvQeUROVWC3fHjg1Bvoeu7ERUHpD8yteVQJIjye4eISs_cNO8z1zBfbFoFw0-MhHD9rcS3es0Q4XP4aLj6ehJ4XZ4E4Yvdv3rz2hu5tehT7RBm_DO5_DDV/s1600/Explicacao2_CQRS.png" width="400" /></span></a></div>
<div style="text-align: justify;">
<span face="Trebuchet MS, sans-serif" style="color: #444444;"><br />
</span></div>
<div class="MsoNormal" style="margin-bottom: 0cm;">
<div style="text-align: justify;">
<span face="Trebuchet MS, sans-serif" style="color: #444444;"><br /></span></div>
</div>
<div class="MsoNormal" style="margin-bottom: 0cm;">
<div style="text-align: justify;">
<span face="Trebuchet MS, sans-serif" style="color: #444444;"><br /></span></div>
</div>
<div class="MsoNormal" style="margin-bottom: 0cm;">
<div style="text-align: justify;">
<span face="Trebuchet MS, sans-serif" style="color: #444444;">Por ser modelos separados nós normalmente pensamos em
diferentes modelos de objeto, provavelmente executando em diferentes processos
lógicos, talvez em hardware separado. Um exemplo web seria um usuário olhando
para uma página web que foi processada usando um modelo de consulta. Se iniciar
uma mudança, que esta mudança é encaminhada para o modelo de comando separado
para processamento, o resultado da mudança é comunicada ao modelo de consulta
para tornar o estado atualizado. Há espaço para uma variação considerável aqui.
Os modelos em memória poderiam compartilhar o mesmo banco de dados, que no caso
o banco de dados aja como a interação entre os dois modelos. Porém eles também
podem usar base de dados separadas, efetivamente tornando o lado da base de
dados de consulta um ReportingDatabase em tempo real. Neste caso, eles precisam
de algum mecanismo de comunicação entre
os dois modelos ou seus banco de dados.<o:p></o:p></span></div>
</div>
<div class="MsoNormal" style="margin-bottom: 0cm;">
<div style="text-align: justify;">
<span face="Trebuchet MS, sans-serif" style="color: #444444;"><br /></span></div>
</div>
<div class="MsoNormal" style="margin-bottom: 0cm;">
<div style="text-align: justify;">
<span face="Trebuchet MS, sans-serif" style="color: #444444;">Os dois modelos podem não ser modelos de objetos
separados, pode ser que o mesmo objeto tenha diferentes interfaces para seu lado
command e seu lado query, um pouco como vistas em banco de dados relacionais.
Mas geralmente quando eu escuto sobre CQRS, eles são claramente modelos
separados.<o:p></o:p></span></div>
</div>
<div class="MsoNormal" style="margin-bottom: 0cm;">
<div style="text-align: justify;">
<span face="Trebuchet MS, sans-serif" style="color: #444444;"><br /></span></div>
</div>
<div class="MsoNormal" style="margin-bottom: 0cm;">
<div style="text-align: justify;">
<span face="Trebuchet MS, sans-serif" style="color: #444444;">CQRS se encaixa naturalmente com algum outro padrão
arquitetural.<o:p></o:p></span></div>
</div>
<div class="MsoNormal" style="margin-bottom: 0cm;">
<div style="text-align: justify;">
<span face="Trebuchet MS, sans-serif" style="color: #444444;"><br /></span></div>
</div>
<div class="MsoListParagraph" style="margin-bottom: 0cm; mso-add-space: auto; mso-list: l0 level1 lfo1; text-indent: -18pt;">
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
</div>
<ul>
<li><span face="Trebuchet MS, sans-serif" style="color: #444444;">À medida que
afastamos de uma única representação que interagimos via CRUD, nós podemos
facilmente mover para um UI baseada em tarefas.</span></li>
</ul>
<ul>
<li><span face="Trebuchet MS, sans-serif" style="color: #444444;">Interagindo com o
modelo de comando naturalmente caímos em comandos ou eventos, que entrosa
melhor com Event Sourcing.</span></li>
</ul>
<ul>
<li><span face="Trebuchet MS, sans-serif" style="color: #444444;">Tendo modelos
separados levanta questões sobre o quanto é difícil manter modelos
consistentes, o que levanta a possibilidade da utilização de consistência
eventual.</span></li>
</ul>
<ul>
<li><span face="Trebuchet MS, sans-serif" style="color: #444444;">Para muitos
domínios, muita da lógica é necessária quando você está atualizando, então pode
fazer sentido o uso de EagerReadDerivation para simplificar seu modelo do lado
de consulta.</span></li>
</ul>
<ul>
<li><span face="Trebuchet MS, sans-serif" style="color: #444444;">CQRS é adequada
para domínios complexos, do tipo que também se beneficiam de Domain-Driven
Design.</span></li>
</ul>
<h3>
<span face="Trebuchet MS, sans-serif"><span style="color: #444444;">Quando usar</span></span></h3>
<span face="Trebuchet MS, sans-serif"><br /></span></div>
<div class="MsoNormal" style="margin-bottom: 0cm;">
<div style="text-align: justify;">
<span face="Trebuchet MS, sans-serif"><span style="color: #444444;">Como todo padrão, CQRS é utilizado em alguns lugares,
mas não em outros. Muitos sis</span><span style="color: #444444;">temas ajus</span><span style="color: #444444;">tam um modelo mental CRUD, e assim deve
ser feito neste estilo.<o:p></o:p></span></span></div>
</div>
<div class="MsoNormal" style="margin-bottom: 0cm;">
<div style="text-align: justify;">
<span face="Trebuchet MS, sans-serif" style="color: #444444;">CQRS é um salto mental significativo para todos os
envolvidos, então não deve ser abordada ao menos que os benefícios vale a pena
o salto.<o:p></o:p></span></div>
</div>
<div class="MsoNormal" style="margin-bottom: 0cm;">
<div style="text-align: justify;">
<span face="Trebuchet MS, sans-serif" style="color: #444444;"><br /></span></div>
</div>
<div class="MsoNormal" style="margin-bottom: 0cm;">
<div style="text-align: justify;">
<span face="Trebuchet MS, sans-serif" style="color: #444444;">Em particular CQRS seria apenas usado em porções
especificas de um sistema (Bounded Context no jargão DDD), e não no sistema
como um todo. Nesta forma de pensar, cada Bounded Context precisa de suas
próprias decisões de como será modelado.<o:p></o:p></span></div>
</div>
<div class="MsoNormal" style="margin-bottom: 0cm;">
<div style="text-align: justify;">
<span face="Trebuchet MS, sans-serif" style="color: #444444;"><br /></span></div>
</div>
<div class="MsoNormal" style="margin-bottom: 0cm;">
<div style="text-align: justify;">
<span face="Trebuchet MS, sans-serif" style="color: #444444;">Até agora eu vi benefícios em duas direções.
Primeiramente é para lidar com complexidade - um domínio complexo pode ser
fácil de resolver usando CQRS. Eu tenho que limitar isso, normalmente há
sobreposição suficiente entre os lados de comando e consulta, e compartilhar um
modelo é fácil. Cada domínio tem diferentes características.<o:p></o:p></span></div>
</div>
<div class="MsoNormal" style="margin-bottom: 0cm;">
<div style="text-align: justify;">
<span face="Trebuchet MS, sans-serif" style="color: #444444;"><br /></span></div>
</div>
<div class="MsoNormal" style="margin-bottom: 0cm;">
<div style="text-align: justify;">
<span face="Trebuchet MS, sans-serif" style="color: #444444;">O outro principal benefício está em lidar com a
aplicações de alta performance. CQRS permite você separar o carregamento dos
leitores e escritores, permitindo você escalar cada independentemente. Se sua
aplicação vê um grande divergência entre leitura e escrita isto é muito útil.
Mesmo sem que, você possa aplicar diferentes estratégias de otimização dos dois
lados. Um exemplo disso é o uso de diferentes técnicas de acesso a banco de
dados para leitura e atualização.<o:p></o:p></span></div>
</div>
<div class="MsoNormal" style="margin-bottom: 0cm;">
<div style="text-align: justify;">
<span face="Trebuchet MS, sans-serif" style="color: #444444;"><br /></span></div>
</div>
<div class="MsoNormal" style="margin-bottom: 0cm;">
<div style="text-align: justify;">
<span face="Trebuchet MS, sans-serif" style="color: #444444;">Se seu domínio não é adequado para o CQRS, mas você
tem consultas que demandam complexidade adicional ou problemas de performance,
lembre que você ainda pode usar um ReportingDatabase. CQRS utiliza um modelo
separado para todas consultas. Com um reporting database você ainda usa seu
sistema principal para a maioria das consultas, mas deixa as mais exigentes a
cargo do reporting database.<o:p></o:p></span></div>
</div>
<div class="MsoNormal" style="margin-bottom: 0cm;">
<div style="text-align: justify;">
<span face="Trebuchet MS, sans-serif" style="color: #444444;"><br /></span></div>
</div>
<div class="MsoNormal" style="margin-bottom: 0cm;">
<div style="text-align: justify;">
<span face="Trebuchet MS, sans-serif"><span style="color: #444444;">Também é verdade que nós não temos uso suficiente de
CQRS na área ainda para estar confiante que entendemos os prós e contras.
Então, enquanto CQRS é um padrão, eu certamente o que na minha "caixa de
ferramentas", só não o manteria no topo</span><span style="color: #444444;">.<o:p></o:p></span></span></div>
</div>
<div class="MsoNormal" style="margin-bottom: 0cm;">
<div style="text-align: justify;">
<span face="Trebuchet MS, sans-serif" style="color: #444444;"><br /></span>
<h3>
<span face="'Trebuchet MS', sans-serif" style="color: #444444;">Outras leituras</span></h3>
<span face="'Trebuchet MS', sans-serif" style="color: #444444;"><br /></span></div>
</div>
<div class="MsoNormal" style="margin-bottom: 0cm;">
<div style="text-align: justify;">
<span face="Trebuchet MS, sans-serif" style="background: white; color: #444444;"> - Greg Young foi a
primeira pessoa que li sobre o assunto - este é o artigo dele que mais gosto.<o:p></o:p></span></div>
</div>
<div class="MsoNormal" style="margin-bottom: 0cm;">
<div style="text-align: justify;">
<span face="Trebuchet MS, sans-serif" style="background: white; color: #444444;">- Udi Dahan é um outro defensor de CQRS, e ele tem uma
descrição detalhada da técnica.<o:p></o:p></span></div>
</div>
<div class="MsoNormal" style="margin-bottom: 0cm;">
<div style="text-align: justify;">
<span face="Trebuchet MS, sans-serif" style="background: white; color: #444444;">- Há um site com informações de CQRS que Greg mantém. Sua
seção de documentos contém alguns materiais interessantes.<o:p></o:p></span></div>
</div>
<div class="MsoNormal" style="margin-bottom: 0cm;">
<div style="text-align: justify;">
<span face="Trebuchet MS, sans-serif" style="background: white; color: #444444;">- Existe uma lista de email ativa para discutir o assunto.<o:p></o:p></span></div>
</div>
<div class="MsoNormal" style="margin-bottom: 0cm;">
<div style="text-align: justify;">
<span face="Trebuchet MS, sans-serif" style="background: white; color: #444444;">- Greg Young está trabalhando em um livro sobre CQRS.<o:p></o:p></span></div>
</div>
<div class="MsoNormal" style="margin-bottom: 0cm;">
<div style="text-align: justify;">
<span face="Trebuchet MS, sans-serif" style="color: #444444;"><br /></span></div>
<div style="text-align: justify;">
<span face="Trebuchet MS, sans-serif" style="color: #444444;"><br /></span></div>
</div>
<div class="MsoNormal" style="margin-bottom: 0cm;">
<div style="text-align: justify;">
<span style="background: white;"><span style="font-family: Courier New, Courier, monospace;">Traduzido por Antônio Flávio Castro</span><span face="Trebuchet MS, sans-serif" style="color: #444444; font-size: 10.5pt;"><o:p></o:p></span></span></div>
<div style="text-align: justify;">
<span style="background: white; color: #444444;"><span style="font-family: Courier New, Courier, monospace;"><br /></span></span></div>
</div>
<div class="MsoNormal" style="margin-bottom: 0cm;">
<div style="text-align: justify;">
<span face="Trebuchet MS, sans-serif" style="color: #444444; font-size: 12pt;">Artigo Original: <a href="http://martinfowler.com/bliki/CQRS.html">http://martinfowler.com/bliki/CQRS.html</a></span></div>
</div>
<div style="text-align: justify;">
<span style="color: #444444;">
</span></div>
<div class="MsoNormal" style="margin-bottom: 0cm;">
<div style="text-align: justify;">
<span style="font-size: 12pt;"><span face="Trebuchet MS, sans-serif" style="color: #444444;">Data da Tradução: 19/01/2015</span><o:p></o:p></span></div><div style="text-align: justify;"><span style="font-size: 12pt;"><span face="Trebuchet MS, sans-serif" style="color: #444444;">Última atualização: 03/03/2021</span></span></div>
</div>
Antônio Fláviohttp://www.blogger.com/profile/00669972471874904233noreply@blogger.com5