Introdução

Essa é apenas uma transcrição/arquivo do artigo "Entropia no software e a teoria da janela quebrada: Como afeta seu dia a dia?" de Rafael dos Santos Miguel Filho, que achei válido traze-lo aqui pela sua grande utilidade e importância. Portanto nada do artigo a seguir foi escrito por mim.

Sim, você ouviu direito: Entropia no Software e a Teoria da Janela Quebrada. Pode parecer um pouco estranho no começo, talvez até esteja se perguntando "mas o que esses conceitos têm a ver com o mundo do software?". Esses dois conceitos não são termos comumente associados um ao outro, mas ao explorar mais a fundo, descobrimos que essas duas teorias podem oferecer uma perspectiva única sobre a gestão eficaz do desenvolvimento e manutenção de software. Neste artigo, exploramos como esses dois conceitos se inter-relacionam e como podem ser utilizados para melhorar as práticas de desenvolvimento de software.

Entropia

Parece um termo científico complicado, não é? Não se preocupe, juntos vamos desmistificar essa palavra e entender o que ela realmente significa, especialmente quando aplicada ao mundo do software. Pegue um café e vamos lá! ☕

Vamos começar no século XIX (19), com um cientista chamado Rudolf Clausius. Foi ele quem nos apresentou a entropia no mundo da termodinâmica. Mas como isso pode ser comparado ao desenvolvimento de software? Prometo que vamos chegar lá, mas antes vamos entender um pouco mais sobre o que Clausius queria dizer com entropia.

Entropia, no campo da física, é uma forma de medir a imprevisibilidade ou, como alguns preferem simplificar, a "desordem" dentro de um sistema. Agora, quando falo em "desordem", não quero dizer bagunça no sentido comum da palavra. Na verdade, estou falando sobre como a energia está distribuída em um sistema.

Imagine que temos uma caixa cheia de partículas. Se todas essas partículas estiverem concentradas em um único canto, podemos dizer que a entropia é baixa - há uma certa "ordem". Mas, se as partículas estão espalhadas de maneira aleatória por toda a caixa, aí temos uma alta entropia - a distribuição de energia é mais "imprevisível" ou "desordenada". A natureza tende ao estado de maior entropia, ou seja, as partículas irão se dispersar, a menos que algo externo intervenha. É como se a natureza gostasse de um pouco de imprevisibilidade

Agora, chegou a hora de conectar essa ideia com o mundo do software 🌉. Quando falamos em entropia no desenvolvimento de software, estamos nos referindo a essa tendência natural dos sistemas de software de se tornarem mais complexos e "desordenados" com o passar do tempo. E quando falo "desordem" aqui, estou falando de coisas como código mal estruturado, documentação insuficiente, bugs não corrigidos, code smells, e por aí vai.

O que acontece é que conforme o software cresce e evolui, é preciso esforço constante para evitar que essa entropia aumente. Precisamos trabalhar para manter o sistema organizado e eficiente - similar a como as partículas na caixa necessitam de uma força externa para não se espalharem aleatoriamente.

Agora que entendemos rapidamente o que é entropia, vamos entender alguns pontos que podem contribuir para o seu aumento dentro do software. Vou aproveitar essa parte para comentar algumas que, infelizmente, já presenciei também na indústria de software.

A falta de requisitos claros!

Vou compartilhar com você uma história que, apesar de fictícia, poderia facilmente se passar na realidade de muitas equipes de desenvolvimento de software. Prometo que é uma história com uma lição valiosa para todos nós: programadores, gerentes de projeto, product owners e qualquer um interessado em construir produtos de software de sucesso.

Pense em uma startup inovadora que está desenvolvendo um aplicativo de entrega de alimentos. Entre os muitos recursos desse aplicativo, surge um requisito especial: a opção de os usuários compartilharem um pedido com amigos, permitindo que todos adicionem seus itens preferidos à mesma ordem. Isso parece um diferencial competitivo incrível, não é mesmo?

No entanto, a descrição desse requisito é um pouco vaga e não entra em detalhes sobre como essa funcionalidade deve ser implementada. Deve existir um limite de usuários por pedido compartilhado? Como lidar com a divisão dos custos de entrega?

Nosso time de desenvolvimento, sempre buscando a eficiência, interpreta o requisito da melhor forma possível com as informações disponíveis. Eles decidem que não haverá limites para a quantidade de usuários em um pedido compartilhado, e que os custos de entrega serão divididos igualmente entre todos os participantes.

Quando o recurso é lançado, a reação dos usuários é mista. Alguns adoram a ideia, mas outros ficam frustrados. Eles não acham justo que um usuário que adicionou apenas um item pequeno pague a mesma taxa de entrega de alguém que pediu vários itens maiores. A falta de limites também causa problemas, com pedidos gigantescos causando atrasos nas entregas.

A lição aqui? Requisitos mal definidos podem levar a mal-entendidos, implementações imprecisas e até mesmo a um feedback negativo dos usuários.

Portanto, cada vez que um novo recurso é proposto, é fundamental não aceitarmos requisitos que pareçam insuficientemente detalhados ou que não estejam coerentes com a realidade. Esse é um dever compartilhado: a equipe de especialistas do domínio deve se esforçar para esclarecer as funcionalidades, enquanto os gestores de tecnologia precisam estar prontos para questionar e clarificar qualquer requisito que pareça vago.

E como isso afeta e colabora para a alta desordem do software?

Quando um recurso é implementado com base em requisitos mal definidos, pode levar a um código mal estruturado ou a uma arquitetura de software que não está alinhada com a verdadeira necessidade do negócio. Isso pode causar problemas, como dificuldades de manutenção, problemas de performance e até a introdução de bugs. Além disso, se os desenvolvedores precisam revisitar continuamente o recurso para corrigir mal-entendidos ou implementar mudanças, isso pode causar ainda mais complexidade e "desordem".

Isso gera estresse para a equipe. Afinal, provavelmente recursos que não foram planejados corretamente precisam de novas definições e modelagem de dados. Talvez novas tabelas precisem ser criadas, novos relacionamentos e entidades. Isso consequentemente pode gerar prazos de entregas irrealistas para correr atrás do prejuízo. Sabemos que muitas empresas deixam de lado em momentos críticos a qualidade, muitos recursos novos ou até os já existentes podem precisar de uma revisão completa, mas isso não é feito com qualidade. Percebe a cascata de problemas gerados? Isso é a desordem!

Portanto, requisitos mal definidos aumentam a entropia tanto no software quanto no negócio. Eles contribuem para um código mais caótico e complexo e podem levar a resultados de negócios indesejados. Ao mesmo tempo, lidar com esses requisitos e suas consequências demanda tempo e recursos, que poderiam ser usados para criar novos recursos ou melhorar outros aspectos do sistema. É por isso que é tão importante se esforçar para definir claramente os requisitos desde o início.

Má Comunicação entre equipes!

Vamos explorar um outro cenário bastante comum no mundo do desenvolvimento de software. Este é especialmente relevante se você já fez parte de uma equipe de desenvolvimento.

Vamos visualizar uma startup, trabalhando em um aplicativo de rede social. Temos dois times, temos um desenvolvedor encarregado de construir uma API que é o coração do sistema de notificação do aplicativo, responsável por alertar os usuários sobre novos likes, comentários e mensagens.

Por outro lado, temos outro programador, em outra equipe, cuja tarefa é desenvolver a interface de usuário (frontend) que exibirá essas notificações. Este desenvolvedor depende da API para receber esses dados e exibi-los de forma intuitiva e atraente para os usuários.

Agora, imagine que o desenvolvedor responsável pela API, na busca pela excelência, faz algumas melhorias significativas, otimizando a forma como os dados são entregues. No entanto, esquece-se de informar ao colega que depende dessa API sobre as mudanças realizadas, ou sobre a nova versão do serviço.

O programador frontend, completamente alheio à atualização, continua a trabalhar com a versão antiga da API. Quando o aplicativo é lançado, os usuários começam a reclamar que as notificações não estão funcionando como esperado, ou até mesmo aparecendo de forma errada.

A situação acima ilustra como um simples deslize na comunicação pode conduzir a um aumento na entropia do software. Essa disfunção não apenas introduz bugs, mas também pode causar frustração e confusão na equipe, e pior ainda, insatisfação no usuário final.

Portanto, a lição aqui é clara: a comunicação eficaz é fundamental para controlar a entropia no software. Manter todos na equipe informados sobre as mudanças e atualizações pode evitar equívocos e garantir que todos estejam alinhados, contribuindo para um software mais eficiente e um ambiente de trabalho mais harmônico.

E como a situação acima colabora para a alta desordem do software?

A situação descrita acima contribui significativamente para a alta entropia do software, ou desordem, de várias maneiras. Vamos dividi-la em pedaços para entender melhor.

  1. Código Desatualizado ou Incompatível: O desenvolvedor que trabalha na interface do usuário está usando uma versão desatualizada da API. Isto pode levar a inconsistências no código, erros de compatibilidade e até mesmo falhas no sistema. Além disso, pode haver um impacto na performance do sistema.
  2. Esforço Desnecessário: A equipe agora terá que gastar tempo extra corrigindo os problemas causados pela falta de comunicação. Isso significa tempo de desenvolvimento perdido que poderia ter sido usado para adicionar novos recursos ou melhorar outros aspectos do software.
  3. Introdução de Bugs: A interface do usuário que depende da API desatualizada pode não funcionar como esperado, levando a bugs. Dependendo da gravidade desses bugs, eles podem afetar a experiência do usuário e até mesmo levar a perdas de dados.
  4. Insatisfação do Usuário: A experiência do usuário pode ser prejudicada devido a funcionalidades mal implementadas ou bugs. Isso pode levar a feedback negativo, perda de usuários e danos à reputação do produto.

Esses fatores combinados aumentam a "desordem" ou entropia dentro do projeto de software. Eles criam uma situação onde a complexidade e a confusão dominam, dificultando a implementação de melhorias e correções. É por isso que a boa comunicação é tão crucial!

Mudanças frequentes nos requisitos!

Imagino que você já tenha se deparado com uma situação onde os requisitos para um software mudam constantemente, certo? Isso pode ser um grande desafio. Tais mudanças podem incluir novas funcionalidades, requisitos e processos que não foram considerados inicialmente. E o que isso causa? Aumento na complexidade do software, introdução de bugs e dificuldade para manter e evoluir o sistema.

Para ilustrar, vamos imaginar um programador desenvolvendo um software de gerenciamento de estoque. Durante o desenvolvimento, os requisitos estão em constante mudança: novos tipos de produtos são introduzidos, regras de desconto são alteradas e as informações dos produtos são variadas. Essa constante adaptação às mudanças pode resultar em uma arquitetura de software incerta e em constante fluxo.

Essa falta de estabilidade e clareza aumenta a entropia dentro do software. A fase de planejamento parece nunca chegar a uma conclusão definitiva, enquanto a lista de requisitos cresce e se transforma. A adição de caminhos de código desnecessários ou redundantes, em resposta a essas mudanças frequentes, pode levar a uma complexidade ainda maior, dificultando a compreensão do código e sua manutenção.

Além disso, com cada nova mudança, há um risco maior de introduzir bugs e falhas no software. Afinal, cada alteração requer uma revisão cuidadosa e testes completos para garantir que não está introduzindo novos problemas. Infelizmente, com prazos apertados e requisitos mal definidos, essa etapa crucial pode ser negligenciada, o que só aumenta a entropia do sistema.

Por fim, o que isso tudo tem a ver com o código que escrevemos? Bem, tudo! Quanto mais complexo o sistema se torna, mais difícil é para nós, desenvolvedores, entender e manter o código. Vamos conversar mais sobre esse assunto.

O código indesejado

A falta de diálogo entre as equipes, a falta de especificações claras e as mudanças frequentes nos requisitos podem impactar negativamente a forma como escrevemos código de várias maneiras:

Vamos começar com o Código inconsistente. Imagine uma equipe de desenvolvedores trabalhando em um projeto, mas com uma comunicação precária entre si. Isso pode resultar em diferentes interpretações dos requisitos e, portanto, inconsistências no código.

Agora, pense no Código mal mantido. Especificações nebulosas e mudanças constantes podem levar a um emaranhado de código "sujo", semelhante a um prédio mal conservado, que se torna cada vez mais difícil de manter.

Em seguida, temos os chamados "cheiros de código". Pense que está andando por uma rua e sente um odor desagradável. É um sinal de que algo não está limpo. No nosso código, os famosos code smells, são aspectos que sugerem problemas potenciais de qualidade ou design, geralmente provocados por mudanças frequentes nos requisitos ou até mesmo falta de experiencia dos programadores, falta de adoção de boas práticas entre outros fatores ligados a legibilidade do código.

Código redundante também é um problema. Sem especificações claras, podemos encontrar partes do código repetidas, aumentando a complexidade e o tempo de manutenção, principalmente pela falta de clareza e adoção do princípio DRY.

E quanto ao aumento de bugs? Isso pode ocorrer quando há falhas de comunicação e as especificações não são compreendidas corretamente. Mas principalmente ocorrem pela ausência de testes automatizados para validar os comportamentos que são esperados pelo software.

Como muitos lidam com esses problemas citados, quando se tornam insustentáveis?

Os desenvolvedores podem considerar refatorações significativas ou, em casos extremos, reescrever o software do zero. Mas atenção, essas são medidas de curto prazo. Se a equipe não adotar um plano consistente para controlar a entropia futura, a deterioração do código retornará. Mas o que tudo isso tem a ver com a teoria da janela quebrada?

A teoria da janela quebrada

No livro The Pragmatic Programmer, os autores argumentam que a entropia do software é contagiosa e, se não for controlada, torna-se uma epidemia. Além disso, fazem uma analogia com a teoria da janela quebrada. Vamos estudar isso mais afundo.

Proposta pelos criminologistas James Wilson e George Kelling e tendo um enorme impacto na política policial durante a década de 1990, a teoria das janelas quebradas é uma ideia que sugere que a desordem física em um ambiente urbano, como pichações e vidraças quebradas, pode levar a um aumento da criminalidade naquela área ou degradação por vândalos no local.

Bom, você deve estar se perguntando, "Mas o que isso tem a ver com a entropia em software?" A resposta é: muito mais do que você imagina!

Considere um código com inconsistências, redundâncias, bugs ou mesmo code smells. Cada um desses elementos pode ser visto como uma "janela quebrada" na engenharia de software. Deixá-los sem solução, ou pior, permitir que se acumulem, gera uma crescente desordem - ou seja, a entropia do software. Essa alta entropia faz com que o código se torne cada vez mais difícil de manter, entender e evoluir.

De maneira similar à Teoria da Janela Quebrada, um código mal cuidado e desorganizado pode incentivar práticas ruins de programação. Imagine que um novo membro da equipe se depara com um código repleto de inconsistências e bugs. Se não houver um esforço consciente para manter a qualidade do código, esse novo membro pode ser levado a pensar: "Se o código já está nesse estado, por que eu deveria me esforçar para escrever um código de qualidade?".

A consequência é um ciclo vicioso, onde a qualidade do software se deteriora, a produtividade diminui, os bugs aumentam e a entropia se torna incontrolável. Assim como em uma casa de bairro onde as janelas quebradas não são consertadas, a desordem acaba por tomar conta.

Podemos acrescentar ainda mais, códigos confusos sem documentação e testes inadequados podem indicar aos desenvolvedores e gerentes de projeto que a qualidade não é uma prioridade, levando a comportamentos e decisões inadequadas para o contexto. Isso pode incluir a adição de novos recursos sem levar em conta a manutenção, omitir refatorações necessárias e não monitorar a qualidade do código. Esses comportamentos inadequados podem levar a um efeito dominó de problemas, onde a entropia do código aumenta gradualmente.

A relação entre a Teoria da Janela Quebrada e a entropia é esta: ambos são formas de entender a importância da manutenção contínua e do cuidado com os detalhes. Tanto em uma cidade quanto em um sistema de software, a desordem se instala quando permitimos que pequenos problemas se acumulem. E a maneira de combater isso é através do cuidado constante, da manutenção regular e da atenção aos detalhes.

Como tratar esse problema grave?

A primeira coisa a se ter em mente é que qualidade e manutenção não são aspectos a serem considerados apenas no final de um projeto - eles devem estar presentes desde o início. Pare de pensar que testes e refatorações são perdas de tempo!

Segundo, mantenha a comunicação. Parece simples, mas é crucial. É necessário que todos os membros da equipe, sejam desenvolvedores, gerentes, proprietários de produtos ou outras partes interessadas, estejam alinhados em termos de requisitos, prazos e objetivos. Dessa forma, podemos reduzir mal-entendidos e evitar inconsistências que contribuem para a entropia.

Terceiro, ter uma política de código limpo e seguir as melhores práticas de codificação. Aqui entram padrões de codificação consistentes, revisões de código, testes automatizados e uma atitude proativa em relação à refatoração. Não se trata apenas de escrever código que funciona, mas de escrever código que outros possam entender e manter.

Quarto, devemos prestar atenção à arquitetura do nosso software. Uma arquitetura bem planejada e escalável reduz a probabilidade de termos que realizar mudanças drásticas no futuro, que podem introduzir novos bugs e aumentar a complexidade e a entropia. Uma arquitetura planejada de maneira precipitada leva a complexidade desnecessária e a um conflitos de ideias entre desenvolvedores dentro do projeto.

Por fim, a gestão eficaz das mudanças. Mudanças são inevitáveis em qualquer projeto, mas a maneira como lidamos com elas pode fazer uma grande diferença. Uma abordagem ágil, que encoraja o feedback contínuo e a adaptação, pode ajudar a gerir as mudanças de uma forma que reduza a entropia ao invés de aumentá-la.

Cada janela quebrada que consertamos é um passo na direção certa. Cada bug corrigido, cada inconsistência eliminada, cada "cheiro de código" resolvido contribui para o controle da entropia. E, ao manter a entropia sob controle, garantimos que nosso software seja sustentável, escalável, testável, compreendido e, acima de tudo, um fácil de modificar e trabalhar.

Como os testes ajudam a manter a entropia sobre controle?

Os testes continuam sendo uma ferramenta subestimada por muitos desenvolvedores na luta contra a alta entropia no software. Por que? Já tentou montar um quebra-cabeças sem a imagem de referência? Bem, se você já o fez, sabe o quão complicado é montar a imagem. Testes, meus caros leitores, são como essa imagem de referência na construção do nosso grande quebra-cabeças de software. Sem uma imagem clara do sistema, não podemos saber exatamente o que um software faz, ou seja, seu propósito. Seus principais recursos e objetivos. Testes refletem os comportamentos do software, são um espelho do software, que podemos executar e entender pelo que cada pedaço de código é responsável!

Os testes de software, unitários, de integração, funcional, de stress, entre outros, têm um papel crucial na prevenção e controle da entropia do software. Como exatamente?

  1. Detectando problemas mais cedo: Testes bem escritos ajudam a identificar bugs, inconsistências e falhas mais cedo, quando eles são mais fáceis (e mais baratos) de serem corrigidos. Testes automatizados executados regularmente garantem que qualquer "janela quebrada" seja prontamente detectada, evitando a propagação da entropia.
  2. Prevenindo a regressão: À medida que o software evolui, é fácil quebrar funcionalidades existentes sem perceber. Com uma suíte de testes abrangente, você tem uma rede de segurança que ajuda a prevenir esses problemas, garantindo que o software continue funcionando como esperado após cada mudança.
  3. Documentação viva: Testes são uma espécie de documentação viva do sistema, que descreve como ele deve funcionar. Ao consultar os testes, novos membros da equipe ou mesmo desenvolvedores veteranos podem entender melhor o código, mantendo a base de código consistente e minimizando a entropia.
  4. Melhora a qualidade do código: Testes incentivam os desenvolvedores a escreverem códigos mais modulares e independentes (fáceis de testar), o que por si só já contribui para reduzir a entropia.
  5. Fornece confiança para refatorar : Melhorar seu design sem alterar seu comportamento é uma atividade necessária para manter a entropia controlada. Testes fornecem a segurança de que, se algo quebrar durante a refatoração, será prontamente detectado.

No livro que estou escrevendo que pretendo anunciar o nome em breve, falo sobre esses pontos de uma perspectiva mais prática para a indústria de software. Realmente quando levamos muito a sério os testes, temos ganhos significativos de produtividade no dia a dia ao programar novos recursos e manter os que já existem. Obviamente não é uma tarefa simples, existem desafios e principalmente compromisso com a qualidade.

Em conclusão, a Teoria da Janela Quebrada nos ensina que a tolerância a pequenas falhas ou "janelas quebradas" no nosso código pode levar a uma cascata de problemas. Os desenvolvedores podem começar a achar que é aceitável produzir código de baixa qualidade, ou ignorar os testes, aumentando assim a entropia. Ao abraçar boas práticas e manter um olhar atento para "janelas quebradas", podemos manter a entropia sob controle e assegurar que nossos projetos de software permaneçam saudáveis e sustentáveis.

Novamente, é mais fácil escrever do que colocar em prática, por isso estou centralizando em um livro esse tema para abordar com mais liberdade e profundidade esse assunto tão complexo e interessante que faz parte do nosso cotidiano.

Fico por aqui. Espero que tenham gostado! Muito obrigada pela leitura até o final, espero que as dicas possam ajudar no dia a dia! Até o próximo artigo! 😄🖐️