Pontos Principais
-
A pressão não nos faz mais rápidos, nem mais produtivos. Ela aumenta o estresse e tira o foco. Precisamos de criatividade, efetividade e foco;
-
Contratar melhores talentos, fazer juntos, praticar juntos e aprender juntos para melhorar o domínio técnico e cultivar o craftsmanship na organização;
-
Melhorar a adaptação da equipe e a eficiência dos processos fazendo planos e revisando eles frequentemente, coletando, analisando e eliminando o desperdício;
-
Sem ter um código base de qualidade, não podemos ser ágeis. Reduzir os defeitos, entregar frequentemente, testar primeiro e refatorar, e então focar sobre um design simples;
-
Software funcionando não precisa ser bem elaborado. Apenas bons profissionais podem construir software bem construído, e apenas software bem construído permite uma construção mais rápida.
Ir rápido e sem controle pode ser o maior inimigo do desenvolvimento de software. As três áreas principais em que se deve diminuir o ritmo são: as pessoas, o processo e o produto. Antes de entrar em detalhes, vamos começar com uma história.
Acho que foi em 2011. Me juntei a uma equipe responsável por construir uma plataforma de marketing online. Minha principal responsabilidade era adicionar novas funcionalidades ao sistema tão rápido quanto possível. Fui contratado como desenvolvedor sênior, chamamos de desenvolvedor "sênior" quem consegue desenvolver mais rápido que os outros, certo? No entanto quando me juntei a eles, notamos que era quase impossível ir mais rápido devido ao débito técnico e aos desafios de design. Em cada tentativa de ir mais rápido, notamos que aumentávamos a complexidade e destruíamos a qualidade. Parecia que a única maneira de melhorar era reescrever todo o sistema do zero.
Lembro que liguei para o gerente de produtos e disse que precisávamos reescrever todo o sistema. Depois de 30 segundos de silêncio ao telefone, o gerente de produtos respondeu, "está dizendo que a equipe escreveu o produto com qualidade tão pobre que o mesma equipe tem que reescrever o mesmo produto novamente, mas dessa vez melhor. Certo? Desculpe, isso é inaceitável. Vocês deveriam ter implementado melhor."
Softwares zumbis precisam ser reescritos, de novo e de novo
De acordo com o Standish Group's Chaos Report, 94% dos projetos de software são desenvolvidos do zero mais de uma vez. Isso é muito. Similarmente, quando vejo os produtos que trabalhei no passado, vejo que quase todos eram reescritos do zero com novas tecnologias, arquitetura e design. Reescrever é tão comum no setor que frequentemente grandes empresas vêem isso como a única opção em gerenciamento de projetos e inovação. Escrevemos, reescrevemos e reescrevemos, de novo e de novo.
Temos que entender nossos piores inimigos do desenvolvimento de software. No mundo do software, ser rápido é vital. Não apenas ser o primeiro no mercado é importante, mas também responder aos clientes adicionando novas funcionalidades e eliminando bugs rapidamente e mantendo a satisfação alta. Mas todos temos um problema com "velocidade". Assumimos que ir mais rápido, mais inteligentes e mais eficientes está relacionado com dar prazos para as metas. Pensamos que somos mais rápido trabalhando mais ou com mais pessoas. Portanto adicionamos novas pessoas ou fazemos hora extra para aumentar a produção. A pressão não nos faz mais rápidos, nem mais produtivos. A pressão aumenta o estresse, tira o foco e destrói a produtividade. Precisamos, ao invés disso, de criatividade, efetividade e foco.
O desenvolvimento de software é extremamente difícil e complexo. Não podemos nos livrar da complexidade. Portanto temos que viver com ela. A necessidade por velocidade cria um ambiente instável e insustentável, nos deixa estressados, menos focados e menos produtivos. Isso simplesmente não funciona. A capacidade da equipe, o bom planejamento, a estimativa, as horas de trabalho fixas, os prazos e os conceitos de velocidade são imaginários, a incompetência é a realidade. Os prazos de entrega têm uma dependência direta sobre as habilidades das pessoas, a eficiência dos processos e a qualidade da saída. Na maioria das vezes, os desenvolvedores dão prazos secretos a si mesmos sem qualquer necessidade real.
No final do dia, temos software legado. A pressão por prazos combinados com a incompetência leva ao software legado. O beco sem saída de um software funcionando. Tenho usado um termo diferente para software legado por um tempo: software zumbi. Software zumbi se encaixa melhor porque esse tipo está literalmente morto, mas parece vivo em produção. Ele funciona em produção e as pessoas ganham dinheiro dele, mas ele precisa de sangue, vida e energia dos desenvolvedores de software para continuar funcionando de alguma forma. Os desenvolvedores estão com muito medo de tocá-lo, portanto, se funciona, ninguém quer mudá-lo.
Robert C. Martin tem uma frase perfeita sobre os sintomas de software legado no Twitter:
"Se seu software está ficando cada vez mais e mais difícil de desenvolver, alguma coisa está errada." (tradução livre).
Enquanto nos apressamos, estamos destruindo a qualidade, tanto que a cada passo que damos a frente, fazemos o processo e o fluxo mais lento que antes. Acredito que desacelerar até chegar a um ponto sustentável é a única maneira de ir mais rápido.
Apressar-se é um mal no desenvolvimento de software
Como Robert C. Martin menciona sobre o valor primário do software em CleanCoders, "A habilidade de um sistema de software de tolerar e facilitar a mudança contínua é o valor primário do software" (tradução livre). Apressar-se é um mal em desenvolvimento de software. Qualquer tentativa de pressa causa danos dramáticos na produtividade, foco, eficácia das pessoas, capacidade de adaptação e tolerância do software.
Por exemplo, sempre temos tempo para resolver bugs, mas nenhum tempo para escrever testes. Não refatoramos e escrevemos testes porque não temos tempo o suficiente. Mas temos tempo para debugging, hackear código e resolver bugs.
Focamos tanto sobre processos que frequentemente esquecemos do principal ativo em desenvolvimento de software: pessoas. Os processos ajudam as pessoas a melhorar a maneira que elas constroem produtos, aumenta a motivação e cultiva um ambiente saudável. No final, a eficiência dos processos é importante, mas as pessoas são essenciais.
Temos que admitir que ninguém é perfeito. Clientes, chefes, gerentes, colegas de equipe, pessoas de negócios, nem mesmo você, todos estão longe de ser perfeitos. Os requisitos, os documentos, as ferramentas, o código, o sistema construído, e o design, podem também nunca ser perfeitos. Portanto, temos que parar de correr e acelerar sem controle. A única maneira de ir mais rápido em um passo sustentável é desacelerar, em três importantes áreas:
- Pessoas para melhorar o domínio técnico e o craftsmanship;
- Os processos para melhorar a adaptação e a eficiência;
- Os produtos para melhorar a automação e a qualidade.
Áreas para desacelerar quando se trata de pessoas
Os processo e as ferramentas não constroem produtos, mas as pessoas sim. Temos que admitir, "contratar talentos" é a funcionalidade mais importante de uma organização. Isso tem um impacto direto no futuro da companhia e do próprio produto.
Contrate os melhores talentos para a organização. Dizendo "o melhor", não quero dizer os mais inteligentes, ou as pessoas mais experientes. Procure por paixão, disciplina e motivação no mínimo. Se todos os três existem em um talento, as outras habilidades podem crescer com facilidade. Contratar é um processo ganha-ganha, então ambos os lados devem ganhar no processo. Devemos desacelerar o processo de contratação e investir em melhorá-lo. Pessoas juntam-se a companhias nas quais acreditam. Modele o comportamento que quer ver. E por meio da cultura, visão e pessoas da companhia, faça os talentos acreditarem em você.
O ego é um cianureto e mata as organizações lentamente. Nunca deixe que o ego entre pela porta da organização. De idiotas adoráveis até idiotas geniais, nunca permita que extremos se juntem a equipe. Nunca contrate pessoas com ego. Com essas pessoas, nunca é possível construir uma cultura corporativa que as pessoas admirem.
Pare de trabalhar sozinho e comece a trabalhar junto. Nunca permita a ocorrência de silos, porque silos ou desenvolvedores heróis são os sintomas de organizações disfuncionais. Sente-se junto, perto. Defina padrões da equipe em conjunto. Trabalhe em pares e grupos; revise junto. Deixe a responsabilidade ser compartilhada entre a equipe.
Praticar em conjunto é a maneira mais eficiente de melhorar suas habilidades. Colaborando, não apenas inspiramos as pessoas, mas também aprendemos uns com os outros. Organize retiros de código, randoris e coding dojos regularmente com a equipe. Gaste 30 minutos de cada dia de trabalho apenas para praticar.
Deixe o conhecimento fluir entre as pessoas. Aprenda junto. Tenho organizado sessões de Brown Bag / Lunch / Learn (reuniões de marmita, tradução livre) desde 2010 toda semana nas equipes em que trabalhei. Ouvi duas vezes, em momentos diferentes, dos meus colegas, "participar de sessões toda quarta-feira me permite melhorar e isso me motiva muito". Isso reflete o poder e o impacto de meetups internos e regulares nas empresas.
Colete e dê feedback. Para ter feedback coletivo, organize grandes retrospectivas como tenho feito por anos. A propósito, a grande retrospectiva (Grand Retrospective) é um tipo de retrospectiva para investigar problemas com mais de 20 pessoas.
Ensinar e compartilhar é a melhor maneira de dominar um tópico. Ser um palestrante e retribuir à comunidade.
Desenvolvedores parecem odiar documentação, mas na realidade, é o oposto. Qualquer produto que as pessoas leiam é uma documentação, de código em produção a código de teste, de uma mensagem de commit para um gráfico de commit. Então documente, desde que as pessoas leiam para entender, faça o melhor.
As empresas não são nossos pais. Temos que ter propriedade sobre nossas carreiras e investir em nosso conhecimento. Se investir significa gastar tempo e dinheiro, então faça por você.
Como podemos otimizar os processos diminuindo a velocidade?
Todos os dias nos deparamos com novos desafios. Estes desafios não deveriam ser apenas sobre necessidades do mercado ou novos requisitos. Desafios técnicos também têm um grande impacto sobre o progresso.
Planos não são nada, mas planejamento está em todas as coisas. Faça planos e revise eles frequentemente. Especialmente nas fases iniciais de startups quando precisam de agilidade extrema. Um alinhamento por dia, seja por daily Scrum ou daily standup, não são o suficiente. Tem que haver colaboração de perto, trabalhar em pares e alinhar mais do que uma vez todos os dias. Mantenha o tamanho da iteração curta, tão curta quanto uma semana. Crie múltiplos canais de loops de feedback organizando revisões regulares e sessões de demonstração.
Defina metas de curto prazo e propósitos de longo prazo. Metas de curto prazo criam foco para a equipe, e propósitos de longo prazo previnem a perda de foco.
Se quer entender onde está errando, comece visualizando os fluxos, tanto técnicos quanto de negócios. Visualize falhas para impulsionar seus aprendizados de experiências passadas.
Nunca tome decisões baseadas em instinto. Sempre colete dados, analise e tome decisões baseada em dados. É também importante permitir que cada desenvolvedor acesse métricas de código e de produto. Isso aumenta a propriedade coletiva e o senso comum em torno do desenvolvimento do produto.
O desperdício é qualquer coisa produzida que não tem valor para o negócio. Detecte e elimine o desperdício, em seu código e no processo que o segue. Os escoteiros deixam os acampamentos mais limpos do que quando encontraram ele. A mesma filosofia é válida em desenvolvimento de software. Siga a regra dos escoteiros e deixe o código mais limpo. Quando abrir um arquivo para adicionar uma nova funcionalidade e notar um problema, resolva ele sem pedir qualquer permissão. Não esqueça de escrever testes antes de resolver os problemas. Isso te deixa confiante e confortável ao manipular o código.
Podemos detectar os desperdícios em todos os pontos do ciclo de vida do desenvolvimento de software. Obedeça a definição de feito e elimine tarefas "90% feito, 90+ restante". Nunca permita branches de vida longa. Branches de vida longa são considerados ruins. Não verifique o código testando manualmente. Testes manuais validam principalmente o caminho feliz. Todos os outros cenários podem apenas ser validados por código de teste. Então leve isso a sério.
Como desacelerar pode melhorar a qualidade dos produtos?
Uma coisa é clara. Sem um código base de qualidade, não há como ser ágil, desculpe. A primeira coisa a se fazer é eliminar o débito técnico e resolver os bugs. Se precisar, pare de construir funcionalidades por um tempo, e foque em eliminar os bugs.
"Resolver bugs e fazer o deploy para os servidores depois" não é um processo adequado hoje. Isso contém riscos e perigos. Precisamos de uma maneira melhor e mais disciplinada de fazer isso. Quando quer resolver um bug, primeiro escreva um teste e reproduza o problema programaticamente. Então resolva o bug e veja que os testes estão passando. Assim, o deploy para a produção se torna seguro.
Trabalhei em equipes que gastavam quase todo o tempo resolvendo bugs e mantendo o código base. Estas equipes sofreram com a instabilidade do produto. Para continuar desenvolvendo novas funcionalidades enquanto resolviam bugs, era necessário dividir a equipe em equipes virtuais. Por exemplo, selecionamos dois colegas em cada iteração para entregar suporte técnico direto e continuar resolvendo bugs. Chamamos eles de Batman / Robin. Não importa que tipo de funcionalidades está correndo para fazer, bugs têm de ser resolvidos sem qualquer interrupção.
Hoje, desenvolvedores normalmente usam uma prática para desacelerar o progresso, a fim de acelerar. Isso é, usando pull requests. Eles param a linha de produção, fazem verificações e code reviews para melhorar a qualidade do código. Eles nunca fazem o deploy sem code review para a produção.
Nosso objetivo final deve ser a entrega contínua, e frequente. De mecanismos de branching do git a estratégias de deploy, de mecanismos de feedback a práticas de testes automatizados, isso necessita de uma mentalidade diferente.
As práticas que usa em SDLC indica quão rápido você desenvolve. Para o mecanismo de git branching, a filosofia "commit antes, commit frequentemente, aperfeiçoe depois, publique uma vez" e desenvolvimento baseado em trunks com feature toggling (ou feature flags - alternância de funcionalidades, tradução livre) permite eliminar o desperdício.
Tenho usado TDD por anos. Muitas pessoas reclamam sobre o impacto do TDD na velocidade da programação. Joe Rainsberger compartilhou seus pensamentos sobre TDD no twitter: "Preocupado que o TDD vai diminuir a velocidade dos seus programadores? Não fique. Eles provavelmente precisam desacelerar." (tradução livre).
O TDD possui mais refatoração do que teste, mais pensar que codificar, por isso leva à melhor qualidade. Desenvolva com TDD, tenha apenas testes o suficiente e design simples.
Nunca chegou a 100% de cobertura de código? Consegui isso em um projeto de três meses. Escrevi testes unitários para cada linha do código de produção. Naquela vez, me senti como um herói com super poderes. Mas quando fizemos o deploy para um ambiente de pré-produção para UAT (User Acceptance Testing), notamos que quatro funcionalidades não estavam funcionando. Tive de escrever testes de integração e funcional para detectar bugs e resolvê-los. Então percebi que testes unitários não garantem bom design e código em funcionamento. Pare de calcular a cobertura de código. Taxas de cobertura de código nada mais são que irradiadores estúpidos de informação.
Resolva os bugs se tiver 30 minutos ou menos para resolvê-los. Adicionalmente, use 20% do seu tempo eliminando débito técnico.
Normalmente escrevemos código para não mudar no futuro. Portanto quando projetamos software, similarmente selecionamos tecnologias e ferramentas para não mudá-las no futuro. Mas estamos errados. A refatoração deveria estar em cada estágio do processo de desenvolvimento. Como Kent Beck diz, temos que fazer mudanças fáceis para fazer fácil as mudanças. Para conseguir isso, governamos todos os microservices em um mono repositório. O mono repositório é para tornar o refactoring mais fácil, e é isso o que realmente precisamos.
Qualquer decisão de design tomada antes de ser necessária está errada. Portanto esperamos até o momento mais responsável para agir. Usamos arquitetura hexagonal para ativar baixo acoplamento e alta coesão em design de alto nível de sistema. Isso também leva a monolitos bem projetados. A propósito, monólitos não são maus, mas design ruim é. Sempre começamos com um monolito e com a ajuda de ports / adaptors, extraímos algumas funcionalidades como microservices. Como Martin Fowler diz em seu artigo "Monolith First", "ir diretamente para uma arquitetura de microservices é um risco, considere um sistema monolítico primeiro. Divida em microservices quando e se precisar." (tradução livre).
Desacelerar para ir mais rápido como uma filosofia
Andreas Möller mencionou como ele se sente sobre o desenvolvimento de software em um tweet: "Eu não quero escrever código que apenas funcione. Quero escrever código que é limpo, fácil de manter, fácil de entender e bem testado." (tradução livre).
Para conseguir isso, precisamos focar em três áreas: pessoas, processos e produto. Ao desacelerar as pessoas, nosso objetivo é melhorar o domínio técnico e o craftsmanship. Ao desacelerar os processos, nosso objetivo é melhorar a adaptação e a eficiência. E ao desacelerar os produtos, nosso objetivo é melhorar a automação e a qualidade. Quando focamos nessas áreas, começamos a cultivar uma cultura de desenvolvimento que possibilita o rápido desenvolvimento.
Não devemos esquecer do seguinte: software funcionando não tem que ser software bem elaborado. Apenas bons profissionais podem construir software bem elaborado. E apenas software bem elaborado permite construir funcionalidades ainda mais rápido.
Sobre o Autor
Lemi Orhan Ergin é um mestre em software com paixão de aumentar o nível de sua profissão e compartilhar suas experiências com a comunidade. É co-fundador do Craftbase e da Comunidade de Software Craftsmanship da Turquia. Ele programa desde 2001 e é praticante e mentor de Scrum, XP, práticas de engenharia e tecnologias de desenvolvimento web.