Quantos de vocês já passaram por este cenário?
- Um departamento da empresa solicita recursos para a criação de um novo componente de software (ou um serviço técnico). A justificativa é a padronização da forma de resolver um certo problema, e o conseqüente ganho de produtividade.
- Os recursos são aprovados e o tal componente é desenvolvido.
- Projetos começam a usar o componente, acham bom, ganham produtividade. Começam a solicitar novas features e correções de defeitos.
- Depois de algumas iterações do passo 3, os projetos estão reclamando da complexidade. O time de arquitetura então solicita recursos para fazer um refactoring do componente. A justificativa é a redução da complexidade e conseqüente ganho de produtividade.
- Volte ao passo 2. Não passe pelo início, não receba $200.
Existem vários nomes para este fenômeno; pode ser “Feature Creep”, “Scope Creep”, ou até “crescimento desenfreado”. É fácil encontrar exemplos, tanto em projetos comerciais dentro das organizações quanto em projetos open-source (estou olhando pra você, Axis!). E vêm algumas perguntas: Onde é que nós erramos? E como não errar mais?
Bom. Pode ser que isso não seja um erro, afinal.
Fatalmente, durante o desenvolvimento de qualquer parte de um software, estamos sujeitos ao impasse de fazer tudo rápido e corrido, ou esperar demais e deixar a oportunidade passar. Na prática, estamos sempre pendendo para o primeiro extremo: criamos software que atende um certo problema, sem nos preocuparmos demais com os detalhes, justamente na esperança de evoluir e adaptar conforme os requisitos vão ficando mais claros. Isso é um ciclo de vida natural. Para um componente ou serviço já nascer redondinho, otimizado, seria necessário muito tempo, recursos, e conhecimento das especificações (“escolha quaisquer dois…”).
Pode ser que o pulo do gato não seja evitar o refactoring. Talvez o certo seja considerá-lo uma necessidade, como uma troca de pele, e apenas nos programarmos para que essa troca não tenha grandes impactos. Neste ponto de vista, o componente nasce, ainda simples e rude; evolui, ganhando features e perdendo defeitos, tornando-se quase um “ouriço de software”; e por fim sofre uma metamorfose, onde os espinhos são aparados e sua forma é reavaliada.
Isto ocorre tanto com componentes e frameworks “tradicionais” de software, quanto com serviços em uma SOA. Contudo, esta última está muito melhor preparada para tratar os sintomas.
Considere uma arquitetura convencional, onde componentes de software são bibliotecas (JARs ou DLLs, por exemplo) de objetos, métodos e funções.
- O acoplamento ainda é alto; mesmo usando fábricas e interfaces (Programação Orientada a Interfaces, uma das melhores práticas de SOA), uma nova versão de um componente implica pelo menos na implantação de um novo pacote.
- Esse empacotamento é delicado: versões erradas ou duplicadas de classes num mesmo pacote podem causar erros estranhos, intermitentes e extremamente difíceis e frustrantes de corrigir.
- Alterações que modificam a API (alterações das grandes!) implicam em alterar os clientes; na melhor das hipóteses, serão criados métodos sobrescritos, para que alguns fluxos continuem funcionando. Pode não parecer, mas a manutenção desses métodos sobrescritos é muito custosa: no decorrer do tempo, eles se acumulam e viram lixo, poluindo o código e dificultando o trabalho.
Agora considere uma arquitetura orientada a serviços, onde existe um nó intermediário (Message Oriented Middleware — o seu ESB).
- Este nó ajuda a reduzir o acoplamento entre clientes e provedores (como visto em um post anterior). Alterações que não afetam a API não precisam nem mesmo da implantação de um pacote; basta atualizar o provedor de serviços. Não há alterações físicas de código, pois estamos usando mensagens neutras.
- Não é necessário manter métodos sobrescritos; o ESB pode, ao invés disso, aplicar content-based routing. Mensagens para a versão 1.0 do serviço são transformadas e encaminhadas para a 2.0; ou então um outro serviço de adaptação é criado para tratar esses casos. Manter o que já existe rodando e ao mesmo possibilitar novos cenários de uso é mais fácil.
- A composição de serviços torna possível, e de fato exige, uma política de governança. Saber quais serviços são interligados, quais são as versões atuais, quem está usando as versões antigas.
Ao fim e ao cabo, o ciclo nascimento-evolução-refactoring pode não ser nocivo. Ao contrário, pode ser bom para a maturidade do componente ou do serviço. O mais importante é gerenciar os riscos, saber quando é hora de limpar os espinhos, e saber usar um intermediário para facilitar esse trabalho de “jardinagem de software”.
Enviado por: joseventura
Posts relacionados:
- Princípios Básicos de SOA – Serviços são Capazes de se Compor
- Princípos Básicos de SOA – Serviços Abstraem a Lógica
- Princípios Básicos de SOA – Baixo Acoplamento
- Seis perspectivas a se considerar antes de adotar SOA
- Cenários e etapas para implantação SOA
Categorias:
Divulgue esse post:
LinkTo 