• Nenhum resultado encontrado

3 CQRS - Command and Query Responsibility Segregation

3.2 Caracterização de CQRS

3.2.1 Conceitos base

Após esta separação de papéis, é importante ter uma ideia geral de como ficará logicamente separado, quais os componentes base do CQRS e qual o fluxo básico do dia-a-dia de um utilizador com uma aplicação baseada em CQRS (Imagem 9).

Imagem 9 – Componentes lógicos do CQRS (Abdullin, s.d.)

Pela Imagem 9 para além dos comandos e queries é possível verificar que após a interação de um utilizador com o sistema, ele poderá querer consultar algo no sistema (lista de encomendas) e executa uma determinada query, que poderá comunicar com várias bases de dados. Se o utilizador quiser modificar algo no sistema (Change Address ou Create Order) é enviado um comando com o detalhe das alterações para um handler, que tem a responsabilidade de identificar o pedido e saber para onde o reencaminhar para ser executado. Posteriormente poderá dar origem a um evento para o resto do sistema, persistindo depois essas mesmas alterações e podendo ser consultadas “quase” de seguida (neste tipo de sistema a consistência imediata de dados é relativa).

3.2 Caracterização de CQRS

29 A Imagem 10 pretende reforçar outras características relativas à importância dos comandos e queries mas também quer manter presente que nem sempre existe consistência de dados.

Imagem 10 – Exemplo de fluxo CQRS (Abdullin, 2010e)

Os dados que são apresentados ao utilizador poderão estar incoerentes, devido a não serem feitos pedidos constantes para manter tudo consistente com a base de dados, e daí se visualizar na interface o detalhe temporal a que os dados se referem. Outro conselho dado é que para aparecer ao utilizador todos os dados deve ser feito à base de dados um pedido do género “SELECT * FROM CustomerView Where … “ de forma a que as queries sejam o mais simples possível e portanto que as respostas sejam mais rápidas. Em relação à alteração de dados é suposto que, por exemplo, quando apenas se quer corrigir um pormenor na morada, não seja preciso enviar sempre todos os dados do cliente juntamente com os novos dados, apenas seja necessário enviar um comando “ChangeAddressCommand” para que a única coisa a fazer seja identificar o utilizador em questão e os novos dados, evitando assim a passagem de dados desnecessários na rede.

Após o envio do comando de mudança de morada, este deverá ser colocado numa fila de forma a funcionar assincronamente, para que se o servidor responsável estiver desligado, possa na mesma ser processado posteriormente, sem ser preciso o utilizador fazer a mesma

30

ação. Quando um comando acaba de ser processado pelo Command Handler, então é necessário publicar essas mesmas alterações para que as queries possam o mais cedo possível devolver os novos dados. Em termos de tipo de comunicações é importante ter em atenção que as queries e os command handlers são síncronos porque tanto um como o outro são processados para aquele instante e necessitam os dois da informação na hora, enquanto a criação de um comando já é assíncrona pois poderá ser processado mais tarde, reduzindo a complexidade (pode-se dividir em vários comandos) e distribuindo a carga por vários servidores (Abdullin, 2010e).

Com estes factos e pelas Imagem 9 e Imagem 10, pretende-se dar resposta a alguns problemas empresariais e aconselhar para que o desenho das aplicações e arquitetura possam ser refinados, ajudando a identificar e corrigir certos bottlenecks de performance, visto que divide em duas grandes áreas leitura e escrita. Escalar facilmente, visto que é mais fácil aumentar o número de máquinas apenas para uma determinada operação; resolver e prevenir problemas de concorrência, uma vez que, funcionando com eventos, se algo grave acontecer, será possível repor; evitar perda de dados no sistema, pois está tudo registado como um log detalhado através dos eventos; reduzir a complexidade de design, porque ao dividir em duas áreas permite ter as melhores tecnologias e metodologias que se aplicam a cada área; e por fim torna o desenvolvimento e manutenção mais fácil, visto desenvolver apenas para um modelo do sistema que não irá ter impactos no resto do sistema, sendo a nível de manutenção permitido por exemplo, atualizar faseadamente o software. O padrão CQRS tenta lidar com estes problemas tentando refinar o mindset atual e permitindo construir arquiteturas de uma forma diferente que ajudará a expansão das empresas a nível do seu sistema atual (Abdullin, s.d.).

Para além das características principais de CQRS já faladas, (Dahan, 2011) existe outra denominada Single Responsibiliy Principle (SRP), que se baseia em linguagens orientadas a objetos (OO), em que cada objeto encapsula os respetivos dados, não expondo nem permitindo alterar sem qualquer controlo. Em vez disso são utilizados métodos que permitem ter acesso e trabalhar com os dados internos do objeto. Com isto, o SRP permite conduzir-nos para que não existam os mesmos dados em diferentes objetos, ou seja, se o nome de um cliente está em dois objetos, o objetivo será de rapidamente fazer um refactor do código de forma a apenas estar centralizado num único sitio e quem necessitar dessa informação saber que apenas existe um único sitio onde o ir pesquisar. Contudo, poderá existir a necessidade de num sistema, o nome do cliente ter de ser exposto tanto na área pessoal do cliente, como na parte do BackOffice, e assim a mesma informação poderá estar em dois sítios, com a principal diferença que poderá estar otimizado, mais, ou menos detalhado ou até ir pesquisar informação a diferentes sítios, e é neste ponto que o CQRS explica que o SRP não deve ser utilizado como se existisse uma única forma de visualizar ou aceder a informação (Dahan, 2011).

Dependendo do tipo de sistema e negócio a que se queira aplicar este padrão, é necessário saber em que nível e até que nível, se deve aplicar estes conceitos, para que não provoque um excesso de divisões quando na realidade não existe essa necessidade ou apenas aplicado a

3.2 Caracterização de CQRS

31 micro contextos. Um exemplo será a Amazon.com onde, se quiséssemos criar apenas uma única vista dos dados seria extremamente complexo, visto que na página inicial poderemos ver, os produtos mais vendidos, o que temos no carrinho, os comentários de utilizadores, produtos aconselhados, etc. Para além de ser complexo iria ser necessário muita duplicação de informação, por exemplo quando se adicionava um artigo ao carrinho, seria necessário voltar a mostrar os clientes que o compraram, os seus nomes, imagens, etc.

Para combater o problema anterior existe o conceito de Autonomous Business Component (ABC) que em vez de usar o CQRS no nível mais elevado da arquitetura, de forma a obter toda esta informação, permite usa-lo num nível abaixo, ou seja, ter um ABC responsável pelos nomes dos produtos, outro pelas imagens, outro pelos comentários, etc., utilizando na mesma o CQRS mas incorporado em cada ABC. Assim, consegue-se uma imagem para o utilizador com toda a informação, e não apenas uma vista da informação. Em termos de performance permite em cada ABC fazer caching, e como cada ABC tem uma área específica torna-se mais fácil criar esse cache e geri-lo, aumentando assim a performance, mesmo separando um insert de forma a atualizar dados e introduzi-los em histórico, tornando-se muito importante porque é necessário sempre saber quando é que uma mudança aconteceu (muito usado em event sourcing) (Dahan, 2011).

Existem ainda duas noções importantes para a utilização de CQRS. Uma será a criação de uma arquitetura circular (Circular Architecture), que se baseia em ter as leituras e escritas de forma desacoplada de forma a utilizar diferentes modos de comunicações, com mensagens assíncronas (comandos e eventos) e queries síncronas. Outra será o recurso a eventos (Event Sourcing), que permite fazer persistir as mudanças através de uma forma contínua e temporal, sabendo sempre num determinado momento em que estado é que o sistema se encontrava (Abdullin, 2010h).

Após compreender os conceitos base de CQRS torna-se necessário detalhar em que consistem as queries e comandos, o que irá ser realizado nos próximos dois subcapítulos.