SOA tem uma base sólida em Design by Contract (DbC) e Component Based Development (CBD). Isso implica em questões interessantes sobre serviços: contratos e interfaces; camadas e serviços; EDA.
Contratos e interfaces
Podemos considerar serviços como interfaces que definem uma topologia corporativa. Alguns autores enfatizam que é possível definir SOA como “Arquitetura Orientada a Interfaces”, mas com um foco corporativo, não no contexto de uma única aplicação. Desenvolver para interfaces traz grandes benefícios.

Uma interface encapsula um determinado backend e deve ser projetada como um contrato, um acordo entre consumidor e fornecedor. De forma que, se o cliente cumprir sua parte (pré-condições), o serviço garante o resultado especificado (pós-condições) com algumas exceções também especificadas. Caso o cliente não garanta a sua parte no acordo, o serviço tem seu comportamento comprometido de forma imprevisível.
Pré-condições: são os parâmetros de entrada e os estados do sistema que devem ser validados antes da “execução” do serviço.
Pós-condições: especificação do estado do sistema (por exemplo, objetos criados ou destruídos, atributos e relacionamentos alterados) ou os parâmetros de saídas garantidos/válidos após a “execução” do serviço. Em outras palavras, o resultado esperado da “execução” do serviço.
Exceções: todas as situações em que a “pós-condição” não pode ser garantida, mesmo com a “pré-condição” atendida.
As definições de “pós-condições”, “pré-condições” e “exceções” não devem ter um caráter de documentação. A atitude mental deve ser de projetar um contrato que proporcione a maior coesão possível, obtida com refinamentos sucessivos (durante todo o ciclo de vida do serviço o contrato deve ser considerado e evoluído), pois todas as decisões neste âmbito terão conseqüências diretas na arquitetura corporativa.
No contrato é especificado onde ficará a lógica, evitando, sobretudo, redundância e falta de coesão. Se uma determinada lógica estiver coesa com o serviço (normalmente a lógica utiliza somente os dados encapsulados no serviço), ela é implementada no próprio serviço, “disparando” possíveis exceções. Caso contrário, o cliente implementaria ou delegaria a lógica (cumprindo as pré-condições) para garantir a execução e obter o resultado esperado. Portanto, a lógica nunca dever ser duplicada no serviço e no cliente.
Alterações devem respeitar o contrato. Em uma alteração do contrato, ou seja, alteração da interface de um serviço, todos os seus clientes devem ser revistos. Interfaces publicadas devem ser bem projetadas, para garantir mudanças de forma controlada. Testes automatizados para garantir o contrato também são importantes, tornando alterações viáveis.
Serviços encapsulam os dados de seu backend – essa é uma questão essencial. Caso um determinado cliente esteja utilizando dados obtidos por intermédio de um serviço para a “execução” de uma regra de negócio, provavelmente essa regra ficaria mais coesa no serviço, não no cliente, ou seja, o serviço deveria fornecer uma operação que encapsula a regra, retornando, por exemplo, um boolean, evitando desta forma que o cliente receba dados desnecessários.
Seguindo o mesmo princípio, um serviço não deve receber dados de outros serviços para cumprir uma regra de negócio. Normalmente, tudo o que recebem são seus próprios dados ou, no máximo, identificadores únicos de conceitos de outros serviços, nunca dados/objetos que não estejam coesos.
Eventualmente, temos regras de negócio que não pertencem exclusivamente a um serviço (utilizam dados/objetos de vários serviços). Neste caso, um serviço composto pode oferecer uma pequena camada de código que orquestra dois ou mais serviços, a fim de cumprir a regra. O serviço composto seqüencia as operações de outros serviços mais básicos, criando uma indireção.

Serviços encapsulam seus dados, por isso, sempre achei estranhas as abordagens de BI com SOA. BI consolida dados, para isso, consomem dados; serviços seguem o caminho oposto, escondem dados. Ainda temos questões de desempenho envolvidas pela característica distributiva dos serviços. No entanto, um interessante artigo da InfoQ, mostra que SOA com EDA pode, em muitos casos, substituir abordagens ETL para consolidar bases, com vantagens, para apoiar iniciativas de BI. EDA é um tema pouco explorado, mas que merece muito mais atenção do que tem recebido no Brasil. EDA usa mensagens assíncronas e promove baixo acoplamento de forma muito interessante; favorece, também, abordagem com BAM e CEP.
Camadas e serviços
A identificação de serviços é uma tarefa importante. As operações de um serviço devem estar coesas com seus dados e com sua interface. Além disso, os serviços devem fazer sentido para o negócio. Neste artigo, existem alguns tipos de serviços básicos definidos por Thomas Erl.
Contudo, serviços bem identificados não bastam. Serviços devem ter o máximo de independência possível. Pensar serviços em termos de camadas traz benefícios importantes, pois essa abordagem pode evitar que seus serviços fiquem parecidos com a figura abaixo. Usar uma ferramenta ESB não resolve.

Pode-se citar como exemplo aplicações que são divididas em camadas (apresentação, aplicação, negócios, infra-estrutura), possibilitando que as alterações sejam contidas. Dessa forma, alterações simples na apresentação ou na persistência não obrigam que quase todo o sistema seja alterado como conseqüência direta.
A abordagem com camadas possui regras simples. A camada mais alta usa vários serviços definidos pela camada mais baixa, mas a camada mais baixa ignora a existência da camada mais alta. Além disso, cada camada normalmente esconde suas camadas mais baixas, conceito conhecido como “camada opaca”; mas também são possíveis “camadas transparentes”, conforme a figura abaixo.

Thomas Erl define algumas camadas básicas para SOA (são possíveis abordagens mais elaboradas com mais camadas, por exemplo, uma camada para serviços de entidades compostos e outra para serviços básicos), na figura abaixo.

No caso de serviços básicos, que encapsulam diretamente o domínio (serviços de entidade, por exemplo), é interessante também que sejam controladas as trocas de mensagens de diretas na mesma camada. Neste caso, podemos usar uma camada superior como indireção, orquestrando serviços da camada inferior. Com essa abordagem, temos um controle da dependência de forma mais simples possível. Apesar de sua característica “procedural”, essa abordagem evita dependências cíclicas. No geral, não existem respostas fácies, pois existem muitas outras variáveis como, por exemplo, desempenho, cada caso deve ser avaliado.
Event-driven architecture
Conforme mencionado anteriormente, abordagens EDA promovem um grande desacoplamento. EDA não é apenas uma questão arquitetural, pois eventos são encontrados no negócio. Um evento pode ser qualquer alteração de estado do negócio. Essa abordagem deve ser seriamente considerada em todos sistemas em uma estratégia SOA.
Normalmente, um sistema que origina o evento envia uma mensagem para uma ferramenta ESB, por exemplo. A ferramenta notifica todos os serviços que assinaram o evento , alterando o fluxo mais comum de uma abordagem SOA ( request-and-reply pattern ) para uma abordagem “inversa” ( publish-and-subscribe pattern). Em certos cenários são possíveis combinações das abordagens.
Fluxo mais comum de uma abordagem SOA:
Event Driven Architecture:
Enviado por: Gustavo S. Sinis
Posts relacionados:
- Seis perspectivas a se considerar antes de adotar SOA
- Carnaval, futebol e SOA
- Princípios Básicos de SOA – Serviços são Capazes de se Compor
- Webinar sobre Lightweight SOA
- Caso de Sucesso com SOA
Categorias:
Divulgue esse post:
LinkTo