Armadilhas para desenvolvedores: em busca do componente perdido

O sonho de todo desenvolvedor é a componentização, mas a partir de algumas conversas das quais participo me pergunto: será que as pessoas realmente sabem do quê estão falando? Componentes aniquilam a repetição desnecessária, e  ingênuamente pensando, nada poderia dar errado, certo?

Definindo

Uma definição inicial de componente de software é: código que implementa determinada funcionalidade visando ser aplicado em diferentes contextos (sistemas) sem a necessidade de ser alterado. Lendo-a pela primeira vez temos a falsa impressão de que estamos lidando com algo razoavelmente simples de ser obtido. Sendo assim vou ir um pouco além expondo quais os atributos que um componente deve ter:

Estabilidade: o componente possui um comportamento que pode ser previsto por seus usuários. Para que isto ocorra faz-se necessário que seu código seja maduro e, de preferência, imutável, mas sim estendido por seus clientes (fechado para modificação, aberto para extensão). Só tem um problema: no universo tudo muda (certo Heráclito?).

Versionamento: a solução para o problema da mutabilidade é o versionamento. Tudo bem que os objetos se alterem com o tempo, mas em um momento específico estes estão em um estado acabado. O usuário de um componente para poder prever o seu comportamento precisa de um intervalo de versões. Por exemplo: sei que um certo recurso do MySQL possui determinado comportamento das versões 5.1 a 5.5.

Plugabilidade: o componente deve fornecer algum tipo de interface que possibilite sua interação com seus clientes e que explicite o quê pode fazer.

Essencialidade: o componente deve representar a essência da funcionalidade que implementa. Por exemplo: um banco de dados que só permita persistir e pesquisar informações médicas é um componente de uso bastante restrito. Em contrapartida um SGBD relacional já pode ser usado em inúmeras situações distintas. Problema: esta generalidade sozinha é inútil sem saber aonde pode ser aplicada.

Contextualidade: aonde o componente pode ser aplicado. Uma regra de negócio, por exemplo, pode ser vista como um componente dentro de um sistema mas será que tem uso fora deste? Normalmente não.

Isolabilidade: de nada adianta o nosso componente ser reaproveitável se não pudermos trata-lo de forma isolada. Este sempre deve poder ser substituído por outro (que vise o mesmo fim, lógico) de tal modo que seus clientes não precisem ser muito modificados neste processo. Traduzindo: um componente não pode aumentar o acoplamento nos sistemas que o usam. Um componente cujo código fonte foi alterado para um uso específico perde a sua capacidade de ser adotado em outras situações.

Como pode ser visto, um componente não é algo fácil de ser construído. Estamos lidando com uma criatura complexa e difícil de ser encontrada. É por isto que não me sinto à vontade quando vejo este conceito representado por metáforas visuais como peças de quebra-cabeça ou um mero cubo. Elas transmitem a idéia de que estamos lidando com algo simples o que não é o caso.

Finalmente uma definição mais precisa:

Componente é um software isolado e versionado que implemente a essência de uma funcionalidade e que possa ser reaplicado sem modificações em diferentes contextos.

Agora algumas armadilhas

Componentização prévia

É um erro muito comum em fábricas de software ou ambientes nos quais a pressão por alta produtividade esteja instalada. Os desenvolvedores são pressionados a escrever código que possa ser usado no maior número de situações possível. Problema: normalmente tentam criar o componente antes que uma segunda situação semelhante em que aquele código pudesse ser reaproveitado surja. Sabe, é importante lembrar um negócio aqui:

O reaproveitamento surge quando uma segunda, terceira ou enésima situação na qual uma mesma solução pudesse ser aplicada aparece.

Por via de regra, costumo pensar na possibilidade de criar um componente só a partir da terceira ocorrência. Dica: é muito raro sua lógica de negócio ter uso real fora do sistema em que surgiu. Normalmente os componentes mais bem sucedidos são aqueles que lidam com problemas mais básicos, como persistência, ordenação, elementos visuais ou outra funcionalidade cuja aplicação seja transversal dentro da sua empresa.

Dê a uma criança um martelo e o mundo se torna um prego

Há um detalhe muito pouco mencionado a respeito dos componentes. Como estes implementam a essencialidade de uma funcionalidade, em seu uso puro, como solução para o seu problema serão sempre o menor denominador comum. Não é raro em minhas consultorias chegar a empresas nas quais foi escolhido um componente que deva ser aplicado sempre que certo tipo de necessidade surja independente das suas características intrínsecas.

Um bom exemplo disto é a adoção indiscriminada de um SGBD específico. Será que sua empresa ao adotar apenas um SGBD consegue de forma produtiva e eficiente atender a todas as suas necessidades de persistência e pesquisa? Outro exemplo: será que usar apenas SOAP como estratégia de integração atende todas as suas necessidades?

Sim, é importante ter um componente padrão, mas melhor ainda é ter um leque de opções para a mesma categoria à qual o problema pertence. Só pode ter uma opção em sua empresa? Pelo menos escolha algo flexível ou fácilmente expansível (sinto cheiro de fanboy por aí).

Excesso de componentes levando a excesso de integrações

Componentes possuem uma verruga que se chama integração. Como na essência deste conceito está a isolabilidade, sempre que um componente é adotado, faz-se necessária a sua integração no sistema cliente.

Na maior parte dos casos a integração é via código mesmo: o componente é escrito na mesma linguagem ou já existe algum binding entre plataformas de desenvolvimento que permita seu uso de forma transparente. No entanto, nem sempre temos um mundo tão simpático assim. Lembre-se que em integrações nas quais é necessário executar transformações sempre há perda de performance.

Conclusões

Não me assustaria se algum leitor comentasse no blog que sou contra a componentização. Isto seria um erro: sou a favor do componente pensado e não naquele cuja origem foi forçada. Acredito que  devam surgir naturalmente a partir da experiência da empresa pois só assim conseguem de fato agregar algo à equipe.

É importante que o desenvolvedor tenha em mente os princípios que mencionei para que caso precise lidar com um gerente ou cliente mal informado lhe pressionando na execução desta “missão” possa expor as dificuldades inerentes ao problema e assim evitar ter mais retrabalho que reaproveitamento no final das contas.

10 thoughts on “Armadilhas para desenvolvedores: em busca do componente perdido

  1. Artigo bacana, Weissmann.

    Junte estrelinha metido a arquiteto com poderes gerenciais + gerentes pressionados com prazos = desenvolvimento orientado ao ego do “metido a arquiteto”, logo: adoção indiscriminada de “frameworks” e criação indiscriminada de “componentes”, que geralmente não atendem a pelo menos 1 dos critérios/atributos que você mencionou neste artigo.

    O que mais vi nesses ultimos anos foi o abandono de projeto desses estrelinhas e fanboys quando a arquitetura/componentes “proposta/criada” tornou o projeto passível a:
    – se tornar algo “Frankstein” [integrações montras e gordurosas];
    – não ser escalável;
    – ter infindáveis bugs de código [mas não de regras de negócios];
    – ter um custo muito maior do que o projeto;
    entre outros malefícios e prejuízos…

    Talvez se fizéssemos uma análise dos fatores filosóficos e psico-sociais que levam o animal [leia ser humano] a se portar ou apresentar tal postura, e considerando um pouco da filosofia de Hegel [O espírito é real / O verdadeiro é o todo / O real é racional], de forma bem sarcástica, chegaríamos a conclusão que fanboys e estrelinhas “são reais e possuem espírito de porco, porém mais irracionais do que racionais” …

    Responda

    Fabricio Reply:

    É a velha estória de fazer só porque pode ser feito.
    Esquecem que “nem tudo que se pode fazer deve ser feito”… E esse princípio tem mais 2000 anos…
    Desse tipo de motivação vem também projetos sobrecarregados de patterns, só para provar que sabe usar patterns.
    Não é porque tenho mil tipos de parafusos que vou usar um quando eu preciso mesmo é um prego – ou então soldar as peças.

    Responda

  2. “O mal prematuro é a raiz de toda otimização”.

    Eu adoro essa frase invertida porque faz muito mais sentido hehehehehe

    Responda

    Kico (Henrique Lobo Weissmann) Reply:

    Boa boa!

    Responda

  3. Véi, na boa… recentemente eu não tenho visto esforço concreto nenhum de criação de componentes ou estruturas realmente reaproveitáveis. A correria é tão grande, o prazo tão apertado, que o que eu tenho ouvido é: “Vamos pensar se não estamos fazendo o ótimo em lugar do bom.” e outras “ladainhas” do tipo.

    Entre componente porcaria e nenhum componente, fico com a segunda opção. Dá menos trabalho.

    Responda

    Kico (Henrique Lobo Weissmann) Reply:

    Sem dúvida, este é um comportamento que observo com frequência também.

    No entanto, agora que finalmente consegui escrever sobre o problema linguístico, o que fica claro é que o foco na componentização que vemos no início de projetos é na realidade diretamente relacionado à metáfora da fábrica de software. O que é uma fábrica? Uma linha de montagem: uma linha de montagem na qual você acopla divesos componentes pra ter um produto final.

    Responda

    Fabricio Reply:

    Matheus, fazer componentes direito dá muiiiito trabalho.
    E geralmente surgem quando eu efetivamente estou para reutilizar uma funcionalidade e tenho que refatorar a código que implementa. Dai, a coisa engrena, pois existe pelo menos um cenário de utilização para ver se funciona quando integrado ao código de produção. Criando do zero é muito mais difícil garantir que vai funcionar – ou mesmo, que será útil. Duvido que um componente fique realmente bom antes do 3o/4o usando-o.

    Responda

    Kico (Henrique Lobo Weissmann) Reply:

    bem observado

    Responda

    Matheus Moreira Reply:

    Concordo com suas observações, Fabrício. O que eu queria destacar é que eu observo um descompasso entre as exigências de produtividade que uma empresa tem sobre suas equipes e o investimento interno para que as equipes sejam realmente produtivas. Eu acredito que um dos reflexos do descompasso é a falta de uma gestão efetiva de componentes reutilizáveis.

    Responda

    Fabrício Reply:

    O desenvolvimento desses componentes deveria ser uma atividade de R&D separada dos projetos de clientes.

    Mas como não há investimento nisso no nosso país – fora do setor acadêmico, e mesmo nesse é falho – chegamos nesse estado de coisas.

    Responda

Leave a Reply

Your email address will not be published. Required fields are marked *