Se o time for indivisível, o software também o será! Elemar Jr. |
Modernizar softwares legados para manter-se relevante no mercado é a realidade de boa parte das empresas atuais. A decisão sobre qual caminho trilhar para atingir esse objetivo exige ponderação e cuidado das lideranças de tecnologia, pois, comumente, temos encontrado times com dificuldades após terem optado por abordagens desnecessariamente complexas.
Temos observado empresas que decidem focar apenas na modernização tecnológica do software, mas deixam de lado o mapeamento dos objetivos arquitetônicos (integrações, restrições, atributos de qualidade e objetivos de negócio). A atualização tecnológica é importante, contudo, focar apenas nesse fator, pode influenciar o time a tomar decisões somente com viés de tecnologia, ou seja, recorrentemente adotar estilos arquitetônicos mais complexos do que o necessário.
Em nossa experiência, trabalhar de forma estratégica identificando os objetivos arquitetônicos, para o projeto de modernização, traz reflexões sobre os motivadores da modernização, como por exemplo, escalabilidade e manutenibilidade. Uma vez identificados os objetivos que motivam a modernização, optar pela mudança do estilo arquitetural geralmente não é o melhor caminho, afinal, existem estratégias mais simples e baratas que podem viabilizar a evolução.
Comece pelo mais simples
Assumindo que o motivador para a modernização seja escalabilidade, verifique os limites de escala previstos pelo negócio, já que o volume de dados ou a quantidade de requisições a serem suportadas são indicadores poderosos que podem conduzir as decisões sobre alterações na arquitetura. Evidenciada a hipótese de problemas de escalabilidade, existe uma chance significativa de resolvermos o problema de formas mais simples do que migrar para outro estilo arquitetural. Aliás, decompor o sistema em serviços menores geralmente não é a resposta para escalar aplicações. Incluir estratégias de caching, balanceamento de carga, transformar aplicações statefull em stateless para facilitar escala horizontal e otimizar o código em caminhos críticos são algumas das formas que podem auxiliar uma aplicação a ganhar escala, mesmo sendo um monólito.
Por outro lado, se o motivador para a modernização apontar para manutenibilidade, recomendamos identificar as features mais instáveis (com maior taxa de alteração no código), e, posteriormente, focar na refatoração desses recursos. Simplificar o design, removendo camadas que não fazem nada e só servem como proxies, refatorar o código seguindo princípios de boas práticas como Clean Code e Solid são estratégias interessantes para tornar o sistema mais fácil de manter. É importante que esse processo de refatoração seja incorporado como cultura dentro da equipe, reforçando a modernização contínua da aplicação. Para assegurar que o processo de refatoração não introduza defeitos, é importante adicionar uma rede de segurança de testes automatizados (unidade ou integração) e testes de performance periódicos, priorizando os pontos críticos e garantindo que não houve mudança de comportamento do sistema.
Contudo, no momento em que começamos a adotar soluções mais simples e baratas para auxiliar o processo de modernização, precisamos ter uma uma forma de validar se estamos atendendo os objetivos arquitetônicos. A utilização de fitness functions é uma forma eficaz para tangibilizar o resultado de ações realizadas, uma vez que os objetivos arquitetônicos devem estar organizados de forma quantitativa.
E somente quando se esgotarem as soluções mais baratas, e o sistema continuar apontando necessidade de evolução, chega o momento de avaliar outros estilos arquitetônicos. A decisão por alterar a arquitetura do software nunca é fácil, mas uma vez tendo os objetivos arquitetônicos mapeados, é possível mitigar o risco de uma decisão mais complexa que o necessário. O ponto chave para nós arquitetos é atuarmos para evitar que modismos, influências de terceiros ou preferências do time reflitam em uma arquitetura com qualidade questionável. Ou seja, além de planejar a arquitetura para entregar componentes com baixo acoplamento, que funcionam e evoluem de forma independente, devemos estar alinhados com a estrutura organizacional da empresa e seus objetivos de negócio.
Decisões que afetam a arquitetura do software devem ser tomadas no último momento responsável mitigando o risco de adicionar complexidade acidental, que por consequência coloca em risco a manutenibilidade, aumentando o custo do sistema. Buscar um novo estilo arquitetural é uma decisão de alto risco, portanto, antes de tomá-la nós arquitetos temos a responsabilidade de garantir a seleção do estilo arquitetônico mais adequado às necessidades (integrações, atributos de qualidade, restrições e objetivos de negócio).