Muitas vezes nos perguntamos se é ou não possível arrumar a casa, ou se devemos demolir e criar novamente tudo do zero, ou pelo menos de algo próximo disso.
Hoje quero falar sobre algumas experiências que tive e falar sobre o framework que usei para tornar algumas experiências de recuperação de projetos em cases bem interessantes.
Não é de hoje que eu me envolvo nesses projetos malucos, nessa refatorações que envolvem projetos à beira do precipício, que após uma imensa bateção de cabeça, resolviam me chamar para tentar arrumar.
Esses foram projetos de enorme risco, inclusive para minha carreira e reputação, mas o desafio parecia interessante o suficiente para justificar o esforço.
Hoje olho para esse passado me lembro desse meme (abaixo).
Bom, já faz alguns anos desde o último grande desses desafios, e desde então tenho sido mais criterioso. A idade, a maturidade, sei lá. O que posso dizer é que depois do último projeto, eu já estava com a certeza de que minha sorte uma hora acabaria. E decerto, em algum momento algum desses projetos daria errado de um jeito sem precedentes.
Afinal, todo sistema tem jeito?
Essa definitivamente não é uma boa pergunta. Ela é abstrata e intangível. O que significa dar jeito?
A primeira coisa quando se analisa esse tipo de projeto é entender com clareza qual o critério de aceite. Ou melhor, qual o critério de sucesso: um marco, um limite claro e límpido que define que sua reestruturação foi um sucesso ou um fracasso. A partir de determinado cenário, quando alguma coisa (alguma conquista desejada, mas não obtida ainda) for atingida, então poderemos todos concluir que foi um sucesso.
Aqui está uma das partes mais importantes a se entender, antes de começar o projeto.
Qual é o objetivo da restruturação.
Qual o objetivo a ser conquistado.
Sem saber qual o objetivo, você está sempre de mãos vazias, sempre em dívida, sempre devendo o que sequer sabe que está devendo. Você se torna refém, se torna pesa fácil com fortes tendências a bode expiatório.
De forma bem prática, sim, todo projeto tem jeito. Seja lá o que “dar um jeito” signifique para seu projeto. A questão é se temos tempo e recursos para tal. Com prazo e recursos infinitos, tudo tem jeito.
A primeira busca: Critério de aceite
Uma das coisas que aprendi com bons gestores com quem já trabalhei, era a capacidade de, meio a cenários intangíveis e abstratos, conseguirem fazer com que o cliente dissesse o que nunca havia dito antes. Em vez de uma resposta evasiva como “Estar funcionando”, as perguntas que faziam conduziam para que entendêssemos o que “estar funcionando” significa. Então quando eu pegava um projeto desses, tinha discussões assim:
– EU: O que você precisamos ter ao final desse projeto para podermos dizer que esta restruturação foi um sucesso?
– CLIENTE: O sistema precisa estar funcionando!
– EU: Ok, mas o que significa estar funcionando? Se eu conseguir atender a somente 1 usuário, simultaneamente é estar funcionando?
– CLIENTE: Não! Tem de atender ao menos 400 usuários.
– EU: Ótimo, então você está me dizendo que: se o sistema funcionar para 400 usuários, é o critério de sucesso?
E por aí vai, item-a-item, do abstrato e intangível, para o prático e mensurável. Ao final era possível criar um contrato, algo escrito em pedra, de tal forma que “novas regras” (ou novos critérios de aceite) são entendidos como mudança de escopo.
Entenda, o objetivo não é criar burocracia, ou dificultar as coisas, o objetivo é ter clareza e transparência sobre quais são as metas do trabalho, removendo a subjetividade desse tipo de tarefa. Assim saímos de algo intangível, abstrato, para algo concreto, que poderia ser mensurável e exibido em um dashboard em uma TV.
Tenha clareza sobre os recursos disponíveis
Uma vez que você tenha uma meta clara, saber quais recursos que possui e quais você não disponibiliza é importante para conseguir elaborar uma estratégia.
Saber se pode contar com mais ferramentas, mais equipe. Na prática, não é tão fácil assim e você não tem tudo na hora que precisa, às vezes leva tempo até o convencimento, e depois até a burocracia fazer aqueles recursos estarem disponíveis e prontos para uso. Portanto, entender desde cedo o que está disponível é um aprendizado importante para poder antecipar dificuldades.
Meu case de 2015
Em 2015, minha meta era que a aplicação a ser restruturada conseguisse suportar 1000 usuários simultâneos. Era uma aplicação asp.net webforms, que estava em desenvolvimento desde 2010. Em dezembro de 2014 tentaram implantá-la em produção, mas durante todo o mês, não conseguiram fazer com que ela passasse dos 12 usuários sem ter de reiniciar o IIS. Fazendo com que fosse feito o rollback da implantação. E durante 2015 eles teriam 12 meses para recuperar esse projeto.
Olhando para o meu LinkedIn, até para ser mais preciso, e para não cometer nenhuma gafe, vi que entrei no projeto em fevereiro de 2015. Me lembro que as conversas haviam começado no mês anterior ainda.
Uma grande preocupação nesse tipo de projeto é com a uniformidade da arquitetura. Projetos desenvolvidos por empresas com muitas culturas, projetos que passaram por muitas fases que fazem do projeto ter diversas arquiteturas, e diversos estilos de design muito diferentes, aumentam a complexidade.
Nesse caso, por se tratar de um time de consultoria, embora o projeto tivesse problemas, havia uma arquitetura homogênea ali. Projetos desenvolvidos com estagiários ou júniores, sem supervisão, onde cada um traz para o projeto seu próprio jeito de ver o mundo sem uniformidade na arquitetura, aumentariam substancialmente o risco.
A supervisão de um sênior ou de um arquiteto, ajudam na condução desse tipo de projeto. Mas nos 4 anos de desenvolvimento desse projeto, eles só contaram com arquiteto no 1.º ano. Aliás, amigo meu. Mas quando ele saiu da consultoria, não repuseram o papel, nem promovendo ninguém do time, nem alocando outro profissional, muito menos trazendo alguém do mercado.
Entenda em que terreno você está pisando
Como falei no parágrafo anterior, eu sabia que estava lidando com um projeto minimamente uniforme. Ou seja, sem muitos desvios de uma arquitetura padrão por todo o projeto.
Não estou aqui questionando a arquitetura nem fazendo julgamento, o fato é que se há uniformidade, há como trabalhar unificadamente de forma estratégica.
É preciso considerar o tamanho do projeto. Quanto maior o projeto, mais código possui, portanto, mais erros você pode inserir ao refatorar. Assim se torna menos provável que você vá precisar de diversas soluções, uma para cada cenário, você tende a conseguir olhar para uma solução apenas que resolva o problema.
Em contrapartida, quando vemos arquiteturas mistas, isso ao invés de termos 1 só grande problemas, temos vários, o projeto que era um só se multiplica em quantas arquiteturas forem. E você tem de avaliar cada uma das arquiteturas para entender como resolver em cada caso.
Aqui vai minha dica: em projetos não uniformes, recuse! Evite esse tipo de jornada. A complexidade que já é alta se torna exponencial.
No meu caso, em 2015, eu buscava a possibilidade de refatorar pontos centralizados da arquitetura. Classes-base de repositório, algo nessa direção.
Não concorra com implementações de negócio
Para o sucesso desse tipo de refatoração, trazer mudanças de negócio dificulta aferir se você que trouxe algum bug ou se a nova implementação que trouxe. Quanto maior a maturidade do time, mais fácil é a convivência, mas quanto menor a maturidade, maior serão os desafios para lidar com você tocando no “filho” (feio) recém-concebido.
Uma coisa de cada vez. Ou o negócio primeiro e depois a refatoração, ou a refatoração primeiro, depois o negócio. Os 2, nunca juntos!
Observabilidade é importante!
Em 2015 a falta de observabilidade foi um problema que afetou a identificação dos gargalos, o fluxo de obtenção de logs era:
Desenvolvedor -> Gerente Consultoria -> Gerente Cliente -> Analista de Infra
Entre você querer e a coisa acontecer, no mínimo 3 comunicações precisavam acontecer. Isso para que eu pudesse ir à mesa do Analista de infra, abrir o log com ele, analisar o que eu queria do log e pegar algumas linhas.
https://gago.io/blog/projetos/enterprise-application-log/Não precisei de mais do que 2 meses para dizer que com esse fluxo não acabaria no ano corrente. Em menos de 2 meses já estávamos com o Enterprise Application Log no ar ali.
Claro que o projeto que você conhece hoje, é uma versão evoluída dele. Mas a lógica continua a mesma há pelo menos 10 anos: RabbitMQ + ELK Stack.
Meça o antigo, antes de refatorar o novo
O momento para começar a gerar números é antes de refatorar de fato o projeto, portanto, como no meu caso, eu conseguia resolver tudo com números: números de usuários, números de análises, etc. Conseguir entender como estava antes para mostrar a evolução, me permitiu ter um ponto de comparação.
Então era óbvio que para conseguir capital político, naquele jogo de interesses, era importante conseguir mostrar evoluções intermediárias. Não adiantaria nada, estar bem, mas afundado em algum assunto que levasse uma ou duas semanas de trabalho, ao ponto de não conseguir demonstrar evolução por causa dessa atividade. Eu precisava mostrar transparência, e para isso métricas públicas, tornaram minha vida um tanto quanto mais fácil.
Agora se prepara, é preciso maturidade. Seja cruelmente transparente. Erro teu, levante a mão e seja o primeiro a dedurar a própria falha.
Então, era importantíssimo criar métricas da versão antiga para poder comparar. Isso me obrigou a conduzir de tal forma que fosse realizada primeira a instrumentação básica da versão antiga, principalmente nos hot paths. Para somente de posse dos números antigos, refatorar de fato e produzir novos números comparativos.
Empatia, faz bem!
Pensa bem: O time não conseguiu colocar o projeto de pé em produção, uma terceira pessoa, no caso você, foi chamado a resolver o problema. Soa domo um salvador da pátria, certo? Sim! Certo!
Você acha que esse time está feliz em ter você ali?
Você acredita que será fácil?
Claro que não. Primeiro você, ao olhar deles, parece um charlatão. Ora, se eles não conseguem, como você conseguiria? Esse é o pensamento mais natural. Na cabeça deles, não tem muita mágica. Claro que se passaram 7 anos e em 2022 falar em Redis, RabbitMQ, ELK Stack é outra coisa. Mas naquela época, eu era observado como se fosse um ET.
Então, em relação ao time, entenda: eles não fizeram por mal. Eles nunca fazem por mal. É a natureza humana. Dificilmente fazemos algo de fato errado, sabendo que está errado. Na maior parte do tempo consideramos que aquilo é o melhor que dá, o melhor que dá para ser feito, o melhor possível para o momento.
O papo que você me vê falando no telegram de: tem de fazer certo e ponto. É real quando você está nessa posição, onde todos estão olhando para você. Mas eu e você sabemos que no dia-a-dia, no mundo real, a galera faz o que dá. Alguns mais, outros menos, mas é isso.
Ainda sobre empatia, é importantíssimo não buscar culpados, eu acho que já disse isso antes. Sua presença ali já é uma demonstração de que o job realizado ali não foi suficiente. Então entenda, jogue junto. Ataque problemas e ideias, nunca pessoas. As pessoas só estão fazendo o melhor que podem com o que possuem de recursos.
Outro ponto importante a se ressaltar, é que você, no meio desse caos, está em um contexto privilegiado, lembre-se em gestão de caos, as liberdades aumentam, a autonomia, o poder, o budget muda. Quando se chega nesse estado de caos, os processos são suprimidos, e a disponibilidade de recursos é vezes maior. Portanto, você é privilegiado nesse jogo. Não se esqueça disso.
Hora de definir uma estratégia
Gosto de atacar um ponto periférico para testar e validar minha tese, já dá para sentir se sua percepção sobre o código que você leu é a mesma de quando você está metendo a mão.
Assim um cenário de pouco uso e baixa complexidade, é o ponto inicial, e logo em seguida gosto de usar um cenário de alta complexidade.
O que quero é validar se a teoria que estou formulando se aplica como solução em casos fáceis e em casos complexos. O cenário fácil, ajuda a tangibilizar a mudança e validar se sua percepção de solução era válida. Se for inválida, levou pouco tempo e esforço. É o princípio do fail-fast, aplicado à refatoração. Então de volta à prancheta.
Supondo que seja um sucesso nesse primeiro case, vá para outro difícil. Aquele que demanda um pouco mais de energia e empenho. Busque o pior, se possível.
Se der certo também, precisamos agora pensar em como aplicar essa ideia em todo o projeto ou ao menos nos caminhos críticos.
Teremos parte 2
Precisamos continuar em um novo post, esse aqui já ficou grande demais.
Resumo:
Primeiro começo entendendo o escopo, fechando um escopo que seja mensurável, aferível, booleano.
Evite aceitar refatorar soluções que não possuam arquitetura uniforme.
Uma vez definido o escopo, tentaremos vislumbrar estratégias possíveis para o problema. Sem questionar viabilidade ainda.
Uma vez com soluções em mente, validamos a viabilidade de cada uma delas.
Antes de começar a refatoração de fato, instrumente e use produza métricas para gerar números que possam servir de comparação no futuro.
Na hora de colocar a mão na massa, busque cenários rápidos, para começar. Mas logo em seguida, busque cenários complexos (cenário rápido: um CRUD, por exemplo. Cenário complexo: fluxo de pagamento, pedido, etc.).
Seja empático, ouça, e mostre pelo exemplo, pela prática, a sua solução. Ensine se necessário.
Ainda ficou faltando falar da condução, ela é fundamental. Mas isso é assunto para outro post.
0 comentários