Ser um arquiteto de software tem tudo a ver com equilíbrio, com as compensações entre diferentes recursos, tecnologias e padrões. Uma das decisões difíceis que você e sua equipe podem enfrentar ao dimensionar é decidir entre manter sua base de código atual e reconstruir em uma nova arquitetura.
Por um lado, se você se depara com essa decisão, provavelmente tem um aplicativo ou serviço que já durou algum tempo e gerou uma demanda significativa do usuário. Parabéns, são bons problemas para se ter. O sistema que você construiu primeiro trouxe você até aqui e sua equipe investiu muito tempo nele. Mas certos pontos fracos podem ter se tornado mais problemáticos com o tempo. Tentar adaptar recursos na arquitetura errada só causará mais problemas.
Para algumas empresas de tecnologia, a decisão de reconstruir seus sistemas do zero foi uma decisão corajosa e um grande sucesso. Para outros, isso os arruinou. Neste artigo, discutirei a mentalidade da arquitetura sacrificial e como ela pode ajudar sua equipe a aceitar o sacrifício de seu próprio código em favor de um novo sistema que pode permitir que sua organização cresça ou torne muito mais fácil manter como seu escalas de produto. Também discutiremos quem é o responsável por essa difícil decisão e quando é melhor refatorar do que sacrificar.
Rápido, depois estável
Nos anos 90, o eBay começou com um script Perl simples. Ele foi reescrito em C ++ e, novamente, no início do novo milênio, foi reescrito em Java. Isso significa que as primeiras versões do eBay foram um desastre completo? A resposta é não. Foi a decisão certa reescrever em um novo idioma? Sim, foi neste caso.
Quando o eBay começou, era como qualquer outra startup: eles precisavam encontrar o conjunto de recursos que levaria as pessoas a usar o serviço. Atender a uma grande base de usuários simultâneos não era o desafio, mas sim encontrar a adequação ao mercado do produto.
No início, o projeto precisava ser iterado rapidamente, então Perl fazia sentido. Naquela época, Perl era apelidado de “ a motosserra das linguagens de script do Exército Suíço ” e considerada a linguagem de programação que mantinha a internet unida.
Mas com o passar dos anos, o tráfego aumentou rapidamente, enquanto o conjunto de recursos tornou-se mais maduro. Nessa nova fase de crescimento da empresa, eles precisavam de um sistema mais estável e escalável. Mudar de Perl para Java pareceu uma decisão sábia porque Perl não era uma linguagem estrita sintática e semanticamente, o que a tornava adequada para desenvolvimento rápido, mas não ideal para programação em larga escala. Java, por outro lado, é projetado para permitir que os desenvolvedores escrevam uma vez e executem em qualquer lugar. Durante os primeiros dias, eles tinham apenas alguns usuários, portanto, não havia necessidade de uma arquitetura complexa para garantir alta disponibilidade de tráfego. Quando eles encontraram os recursos que atraíram os usuários, o desempenho e a alta disponibilidade tornaram-se essenciais para o crescimento dos negócios. Os clientes mudarão para um concorrente se o serviço for muito lento.
Isso leva a uma ideia vital para a arquitetura de software: “Desempenho é um recurso”.
Desempenho é um recurso
Quando Jeff Atwood disse, “ desempenho é um recurso ”, muitos desenvolvedores entenderam que isso significava que o desempenho é a primeira coisa a se preocupar, mas isso não está certo.
Ao adicionar recursos a um produto, você pode escolher entre eles, priorizá-los e implementá-los. Como na história do eBay, no início, o desempenho não é necessariamente a primeira prioridade. Como arquiteto de software, “desempenho é um recurso” significa que você precisa conviver com as compensações. Nem todos os recursos solicitados farão parte do MVP. No futuro, no entanto, você pode descobrir que é necessário permanecer competitivo ou reter os usuários que adquiriu.
Reconstruindo para um propósito atencioso
Em agosto de 2020, o Twitter lançou sua nova API pública. O lançamento não continha apenas novos recursos. Foi um repensar da arquitetura geral.
“O lançamento de hoje marca a reconstrução mais significativa de nossa API pública desde 2012. Ela foi construída para fornecer novos recursos, mais rapidamente e para melhor servir o conjunto diversificado de desenvolvedores que constroem no Twitter. Ele também foi desenvolvido para incorporar muitas de nossas experiências e lições aprendidas nos últimos quatorze anos de operação de APIs públicas.”
[Mergulhe fundo no mundo da tecnologia e cadastre-se no Avance Network a verdadeira comunidade criptografada]
A API pública do Twitter v1.1 foi implementada como um conjunto de microsserviços HTTP, afastando-os de um monólito. Embora os microsserviços tenham permitido à equipe do Twitter acelerar o processo de desenvolvimento, isso resultou em endpoints dispersos e heterogêneos como equipes independentes projetadas e construídas para seus próprios casos de uso específicos. O Twitter precisava de uma nova arquitetura, pois a antiga não correspondia às expectativas futuras. A nova versão da API do Twitter v2 precisava ser mais escalonável para atender a um grande número de novos endpoints planejados que oferecem suporte a novas funcionalidades. Ele também deve fornecer mais consistência para desenvolvedores externos e reforçar mais uniformidade.
Em outras palavras, eles adicionaram um novo recurso: melhor desempenho.
Arquitetura sacrificial
Nesses exemplos, o eBay e o Twitter passaram por reconstruções completas de sua arquitetura para ter sistemas estáveis e de alto desempenho que pudessem ser dimensionados e oferecer suporte a novos recursos. Suas arquiteturas antigas não eram uma perda de tempo; foram fundações que tiveram de ser sacrificadas para chegar onde estão hoje.
Martin Fowler explicou a arquitetura sacrificial como uma mentalidade de arquitetar um sistema:
“Essencialmente, significa aceitar agora que, em alguns anos, você (com sorte) precisará jogar fora o que está construindo atualmente.”
Nem sempre jogamos código fora porque é terrível, mas porque as necessidades mudaram. Isso é exatamente o que o eBay e o Twitter fizeram quando reconstruíram seus serviços.
Quando falei anteriormente sobre projetar sua primeira versão e aceitar que ela seja jogada fora, não quero dizer que você deva construir um sistema ruim ou defeituoso. Arquitetar um sistema insatisfatório prejudicará suas chances de chegar ao estágio em que será necessário refazer a arquitetura de seu sistema. O que quero dizer é, pense na qualidade do seu código como se ele fosse executado para sempre, mas se adapte às mudanças como se o seu código estivesse obsoleto amanhã.
Qualidade ainda importa
A arquitetura sacrificial não deve ser uma desculpa para sistemas ruins. Você deve considerar apenas sacrificar seu sistema antigo, ou parte dele, para atender às novas necessidades que surgiram desde que o sistema anterior foi projetado. Se as necessidades não mudaram, sua base de código deve continuar com um bom desempenho.
Em um estágio inicial de uma empresa de software, você tem menos certeza do que precisa fazer; por isso é essencial focar na flexibilidade e extensibilidade, em vez de desempenho ou disponibilidade. Isso é vital para adicionar novos recursos sem problemas. Flexibilidade e desacoplamento não são características que devem ser consideradas apenas para projetos de alto nível. Conceitos como SOLID e padrões de projeto também podem ajudar a manter seu projeto de código de baixo nível desacoplado. Quando as peças do sistema são desacopladas, elas podem ser substituídas. Quanto mais flexibilidade seu sistema tiver, mais fácil será sacrificar peças e melhorar o sistema como um todo.
A modularidade permite que você trabalhe na mentalidade sacrificial sem necessariamente exigir uma remoção e substituição completa. Talvez você não precise sacrificar todo um sistema. Talvez sejam apenas alguns módulos que causam a desvantagem.
“Modularidade é a característica mais importante de um aplicativo sustentável. Modularidade é o grau em que os componentes de um sistema podem ser separados e recombinados. Um aplicativo modular não é um desperdício - as peças podem ser alteradas, substituídas ou jogadas fora sem afetar o resto do aplicativo ” Justin Meyer.
Uma base de código sustentável pode responder com eficiência às mudanças e melhorar rapidamente, resultando em resultados de alta qualidade. Um sistema sustentável é determinístico, o que significa que deve haver uma maneira obviamente correta de estender seu sistema, seja adicionando ou removendo recursos, sem quebrar nada. Não deve ser uma decisão aleatória ou arbitrária. Ao projetar seu módulo, planeje como ele se conectará aos outros módulos e planeje como ele pode ser desconectado / substituído quando chegar a hora. Entenda as dependências de seus sistemas e certifique-se de que eles podem tolerar falhas e substituições.
É responsabilidade da equipe
É mais fácil escrever código do que lê-lo. É por isso que Martin Fowler sugere que a equipe que desenvolveu um sistema é, em última instância, quem decide se e quando sacrificá-lo. Uma nova equipe pode odiar o sistema porque não entende totalmente suas decisões subjacentes. Mas eles provavelmente terão os mesmos problemas se reconstruírem do zero sem entender as razões por trás do sistema antigo. Uma nova equipe não consegue entender totalmente todas as compensações feitas pela equipe anteriormente responsável.
O novo código é melhor do que o antigo?
O novo código nem sempre é melhor. O código antigo foi usado e testado por usuários reais, usando dados precisos e sob pressão do mundo real. Muitos bugs foram encontrados e corrigidos, e muitas iterações e melhorias foram aplicadas. Se o seu motivo para descartar um código é devido a um misterioso "se-condição", talvez tudo o que você precise é algumas iterações de refatoração.
Quando o código está alinhado com as metas de negócios atuais e futuras, você não precisa sacrificá-lo. Mesmo um sistema com erros pode ser refatorado até um certo ponto, e esta deve ser sua primeira abordagem no caminho para um sacrifício total.
Devo começar de novo?
Embora o eBay e o Twitter tenham tido muito sucesso ao sacrificar a antiga base de código, nem todas as empresas têm sorte. Deixe-me apresentá-lo ao Netscape - lembra deles? É o lado oposto da moeda.
“A Netscape foi a primeira empresa a tentar capitalizar na emergente World Wide Web. O primeiro produto da empresa foi o navegador da Web, denominado Mosaic Netscape 0.9, lançado em 13 de outubro de 1994. Quatro meses depois de seu lançamento, ele já havia conquistado três quartos do mercado de navegadores. Tornou-se o principal navegador dos internautas em tão pouco tempo devido à sua superioridade sobre os demais concorrentes. Este navegador foi posteriormente renomeado para Netscape Navigator. Em 9 de agosto de 1995, a Netscape fez um IPO extremamente bem-sucedido . A ação fechou a US $ 58,25, o que deu à Netscape um valor de mercado de US $ 2,9 bilhões. ” Fonte Wikipedia
Naquela época, a Microsoft estava começando a agregar o Internet Explorer ao sistema operacional Windows. Depois que a competição se tornou mortal, a Netscape decidiu jogar fora sua base de código antiga e reconstruí-la do zero. O processo de reescrita levou quase três anos. Quando foi finalmente lançado, estava muito aquém do que estava então no mercado. Três anos se passaram sem fornecer nenhum recurso essencial. Isso foi o suficiente para levar um unicórnio para o túmulo. Mas podemos culpar a arquitetura sacrificial pelo fracasso do Netscape? Acho que não.
Arquitetura sacrificial é uma mentalidade que permite aceitar a ideia de desistir de seu próprio código. A escolha da hora certa depende inteiramente de você.
A Netscape não foi a única empresa que cometeu esse erro. Em meados dos anos 90, a Borland comprou a Ashton-Tate e a WordTech. Ambas as empresas estavam desenvolvendo sistemas de gerenciamento de banco de dados para microcomputadores, dBASE de Ashton-Tate e Arago da WordTech. A Borland decidiu usar o Arago como a nova base do dBASE para Windows 5.0. Enquanto isso, a Microsoft lançou o MS Access. Quando a Borland lançou o dBASE para Windows 5.0, eles descobriram que o mercado havia mudado para outro lugar. A Microsoft quase caiu na mesma armadilha quando decidiu reescrever o MS Word em um projeto chamado “Pirâmide”. Felizmente para a Microsoft, eles decidiram encerrar o projeto e continuar com a base de código antiga.
Em conclusão, a arquitetura sacrificial pode ser sua única maneira de aprender as coisas. No entanto, não deve ser uma desculpa para a construção de software de baixa qualidade, pois será sacrificado de qualquer maneira. Não tenha vergonha de desistir de parte do seu próprio código, mas faça-o com sabedoria. Mesmo as grandes empresas tomam decisões erradas, e podemos aprender com isso (se funcionou para elas, não significa que funcionará para você também, e vice-versa)
Você já reconstruiu um sistema do zero ou conhece outra história de reconstrução de sucesso / falha? Conte-nos sua história em um comentário.
O Avance Network é uma comunidade fácil de usar que fornece segurança de primeira e não requer muito conhecimento técnico. Com uma conta, você pode proteger sua comunicação e seus dispositivos. O Avance Network não mantém registros de seus dados; portanto, você pode ter certeza de que tudo o que sai do seu dispositivo chega ao outro lado sem inspeção.