sábado, 30 de março de 2013

Acoplamento - Comparação Entre Web Services e Mensageria

Baixo Acoplamento e Alta Coesão são dois termos muito escutados em orientação a objetos. Se formos nas raízes dos termos, podemos fazer analogias com coisas não relacionadas a sistemas. Vamos tomar o ato de pagar uma conta em um banco como exemplo.
Focando em Baixo Acoplamento, quando você vai até a boca do caixa para pagar uma conta, um detalhe que você precisa saber é onde está o caixa; você não precisa saber quem está atrás do caixa -- tanto faz se todo dia dez você paga suas contas e sempre há um atendente diferente. Obviamente, isso não exemplifica todos os aspectos de baixo acoplamento, mas considere que não existe acoplamento com a pessoa que lhe atende, mas apenas com o caixa. O caixa (objeto não pessoa) introduz uma camada a mais entre você e o atendente -- uma camada de indireção entre vocês dois.

Em software, conseguimos baixo acoplamento adicionando níveis de indireção. Quando um objeto interage com outro por intermédio de uma interface, essa interface é uma camada de indireção. Essa nova onda de nuvem, virtualização, etc. está intrinsecamente relacionada com a indireção de recursos de computação em relação ao hardware, por exemplo.

Existe também uma questão chamada sincronismo. Quando você mantém um diálogo com uma pessoa, existe um sincronismo. Você, se for educado, espera a pessoa concluir uma ideia e então complementa o diálogo -- existe uma atenção para a ordem das falas de cada um; existe um sincronismo. O sincronismo cria um acoplamento temporal. Interações sem sincronismo (assíncronas, nos termos de software) são desacopladas temporalmente. Você pode interagir com outra pessoa deixando um recado em sua caixa postal, por exemplo. Você sabe (espera e conta com isso) que vai haver uma interação com a pessoa quando ela ouvir seu recado, mas não existe atenção ao tempo das coisas (ignorando coisas do tipo "e se eu precisar de uma resposta até tal dia?").

Web Services


Em integração/interação entre sistemas, o baixo acoplamento pode ser desejável também. Em integrações entre sistemas via web services existem os acoplamentos de tempo -- o servidor precisa estar em execução --, e localização -- quem faz a chamada, precisa fazer a chamada para um determinado endereço. A imagem a seguir mostra que uma Aplicação A (quem chama) precisa saber onde a Aplicação B (o servidor) está.


No modelo acima, por mais que exista um modelo compartilhado entre as aplicações, esse modelo terá que ser traduzido (de um formato em XML para objetos locais e vice-versa) tanto para evocar quando para responder à requisições.

RabbitMQ em Cluster


Em um modelo de integração/interação usando mensageria com RabbitMQ, por exemplo, não existe acoplamento de localização se configurarmos as instâncias do RabbitMQ em cluster, ou usando o plugin Shovel ou Federation. Para interações assíncronas, o acoplamento temporal também não existe. Entretanto, para interações onde uma resposta imediata for necessária, não há como fugir do acoplamento temporal. A imagem a seguir demonstra que uma Aplicação A não precisa saber onde está a Aplicação B. E para o caso de uma interação assíncrona, a Aplicação B não precisa nem estar em execução; basta que ela esteja em execução em algum momento no qual um requisito funcional demande.


Nesse modelo, assim como em interações via web services, também deverá haver uma tradução das mensagens para objetos locais. Como disse anteriormente, para diminuir o acoplamento, se faz necessária uma camada de indireção. Nesse caso, a camada de indireção entre as Aplicações A e B é o RabbitMQ. Tudo que as aplicações precisam saber sobre localização é o famoso e bem aventurado localhost. Obviamente, existe o acoplamento de localização em algum ponto dessa solução, mas ele é totalmente delegado à infraestrutura.

Prós e Contras das Soluções


Uma outra vantagem da solução baseada em mensageria sobre a solução com web services é a escalabilidade horizontal -- ela é natural nessa arquitetura. Uma infraestrutura baseada em instâncias RabbitMQ em cluster, permite que os sistemas envolvidos só precisem saber os nomes de suas filas e entrem em acordo sobre os tipos dos objetos que irão enviar e receber (contrato). É possível escalar horizontalmente um serviço baseado em web services, mas isso requer um esforço e configuração maiores.

Uma desvantagem sobre o modelo de mensageria apresentado em relação ao modelo com web services e como qualquer solução com menor acoplamento é o esforço de implementação. Toda camada adicional, obviamente, adiciona trabalho para construí-la. Mas, em contra partida, indireção facilita manutenção. Como tudo na vida, o segredo é sabermos ponderar as coisas levando o máximo de fatos em consideração.