A arquitetura do software é superestimada, o design simples é subestimado

imagem

Oferecemos a tradução do cargo de Gergel Oros, que ocupa o cargo de gerente de engenharia da Uber. Nele, ele compartilha sua visão sobre o design de sistemas em larga escala, com base em sua própria experiência prática no Uber e na Microsoft. Combinado com comentários no Hacker News que adicionam contra-argumentos pesados ​​e complementam o ponto de vista do autor, seu artigo se tornou um dos posts mais interessantes da semana. O termo "design de código" é usado no artigo para comparar com a "arquitetura" tradicional - mais sobre ele pode ser encontrado aqui .

Eu já tive experiência suficiente no design e criação de sistemas em larga escala. Participei da reescrita do sistema de pagamento distribuído da Uber, projetando e liberando o Skype no Xbox One e liberando os RIBs disponíveis ao público, uma estrutura de arquitetura móvel criada pela Uber. Todos esses sistemas tinham um design cuidadosamente pensado, passaram por várias iterações e muitas reuniões foram realizadas no quadro branco e outras discussões. Em seguida, o design veio com um documento de design, que foi distribuído entre outros desenvolvedores para coletar feedback adicional, que continuou até o desenvolvimento.

Todos esses sistemas eram em larga escala: centenas de desenvolvedores os criaram - ou os usaram em seus projetos - e hoje eles batem no coração dos sistemas que milhões de pessoas usam todos os dias. Além disso, esses projetos não foram criados a partir do zero. O sistema de pagamento deveria substituir dois outros sistemas de pagamento existentes usados ​​por dezenas de outros sistemas e dezenas de equipes, todos sem causar danos aos negócios. Reescrever o aplicativo Uber era um projeto no qual várias centenas de engenheiros trabalhavam ao mesmo tempo - incluía transportar todas as funcionalidades existentes para a nova arquitetura.

Deixe-me começar com algo que pode parecer inesperado. Primeiro, nunca usamos ferramentas de planejamento de arquitetura de software padrão para trabalhar nos projetos desses sistemas. Não usamos nem UML , nem o modelo 4 + 1 , nem ADR , nem C4 , nem os diagramas de dependência . Desenhamos muitos diagramas, mas nenhum deles seguiu regras rígidas. Apenas eram necessários bons retângulos e setas antigos - e obtivemos diagramas semelhantes a este, que descreve fluxos de informações , ou outro, que descreve a estrutura da classe e o relacionamento entre os componentes . Dois gráficos no mesmo documento de design geralmente tinham um estilo diferente, pois eram frequentemente adicionados ou editados por pessoas diferentes.

Em segundo lugar, não tínhamos arquitetos responsáveis ​​pelo design. Não havia arquiteto de TI nem arquiteto corporativo . Isso é verdade - nem o Uber nem o Skype / Mircrosoft têm uma posição em tempo integral para arquitetos de software. Engenheiros de nível superior, como os da posição de Engenheiro da equipe, ainda devem escrever código regularmente. Todos os nossos projetos têm engenheiros experientes - no entanto, nem uma única pessoa possui arquitetura ou design sozinho. Enquanto engenheiros experientes foram a força motriz por trás do processo de design, outros desenvolvedores estiveram envolvidos na discussão, incluindo até o “junho” verde - além disso, eles frequentemente desafiaram as decisões de outros e criaram opções alternativas para discussão.

Em terceiro lugar, quase nunca nos referimos a padrões arquiteturais comuns e outro jargão geralmente aceito, usado na literatura popular sobre arquitetura de software, como o manual de Martin Fowler . Não havia referências a microsserviços, arquitetura sem servidor, limites de aplicativos , arquitetura orientada a eventos ou qualquer outra coisa. Alguns desses termos surgiram durante as sessões de brainstorming; no entanto, não precisamos nos referir a eles mesmos na documentação do projeto.

Design de software em empresas e startups de tecnologia


Então, como lidamos com tudo? E por que não seguimos abordagens comuns à arquitetura de software?

Eu discuti esse problema com colegas engenheiros que trabalham em outras empresas de tecnologia - tamanhos de FANG (Facebook, Amazon, Netflix, Google) e pequenas startups. A maioria das equipes e projetos - grandes ou pequenos - combinou uma abordagem semelhante ao design e implementação:

  1. Comece com uma tarefa comercial. Que problema estamos tentando resolver? Que produto estamos tentando criar e por quê? Como podemos medir seu sucesso?
  2. Brainstorm para a "abordagem" escolhida. Reúna-se com a equipe e encontre uma solução funcional em algumas sessões. Não demora demais com esta fase. Comece do nível superior e abaixe-se gradualmente até os níveis abaixo.
  3. Desenhe sua abordagem no quadro. Reúna a equipe e permita que um de vocês descreva a abordagem na qual a equipe está inclinada. Você deve ser capaz de explicar claramente a arquitetura do seu sistema / aplicativo com a ajuda de uma placa - começando no nível mais alto e, se necessário, indo cada vez mais baixo. Se você tiver dificuldades com alguma explicação ou se não for claro o suficiente para os colegas, precisará trabalhar melhor os detalhes de sua decisão.
  4. Corrija-o na forma de documentação simples, com diagramas simples, com base no que você explicou anteriormente com o quadro branco. Mantenha o jargão no mínimo: você quer que os juniores compreendam o que está sendo dito. Use uma linguagem clara e fácil em sua descrição . No Uber, usamos um documento semelhante ao RFC com base em um modelo simples.
  5. Discuta trocas e alternativas . Bom design de software e boa arquitetura são a escolha certa para compensações. Por si só, nenhuma das opções de design é boa ou ruim: tudo depende do contexto e dos objetivos. Sua arquitetura está dividida em diferentes serviços? Mencione por que você decidiu não fazer um grande serviço, para o qual poderia haver outras vantagens, como uma implantação mais simples e rápida. Você decidiu expandir o módulo ou serviço com novas funcionalidades? Em vez disso, avalie a possibilidade de desenvolver um serviço ou módulo separado e quais são os prós e os contras dessa abordagem.
  6. Distribua o documento de design dentro da equipe / organização e obtenha feedback. Anteriormente, na Uber, enviamos todos os documentos de design do software a todos os nossos engenheiros - até o momento em que nossa equipe cresceu para 2.000 pessoas. Agora que chegamos a essa escala, ainda estamos tentando alcançar o maior público possível - mas, ao mesmo tempo, começamos a garantir que o nível de ruído das informações não exceda o limite permitido. Incentive outras pessoas a fazer perguntas e sugerir alternativas. Seja pragmático sobre os prazos para discutir o feedback e incluí-lo no documento, quando necessário. Desejos específicos podem ser aplicados imediatamente e rapidamente, enquanto o feedback detalhado é melhor para desmontar pessoalmente.

Por que nossa abordagem é diferente da normalmente mencionada na literatura sobre arquitetura de software? De fato, nossa abordagem não é fundamentalmente diferente do que é descrito nos manuais de arquitetura. Quase todos os manuais sugerem começar com uma tarefa comercial, além de descrever soluções e compensações - também fazemos isso. O que não estamos fazendo é não usar ferramentas mais sofisticadas que muitos arquitetos e livros de arquitetura defendem. Documentamos o design da maneira mais simples possível, usando as ferramentas mais simples e óbvias, como Google Docs ou Office 365.

Acredito que a principal diferença em nossa abordagem se resume à cultura de engenharia de diferentes empresas. Um alto grau de autonomia e uma hierarquia minimizada é um recurso comum entre empresas e startups modernas de tecnologia; no caso de empresas mais tradicionais, isso está longe de ser sempre verdade. Essa também é a razão pela qual, nesses locais, eles recorrem frequentemente ao "design baseado no senso comum", em vez de ao design baseado em um processo com regras estritas.

Conheço bancos e empresas de automóveis em que os desenvolvedores são desencorajados a tomar decisões arquitetônicas sem ter que subir na cadeia e obter aprovação dos arquitetos vários níveis mais altos, que supervisionam várias equipes. Isso torna o processo mais lento e, com um grande número de solicitações, os arquitetos ficam sobrecarregados. Portanto, esses arquitetos criam documentos ainda mais formais, na esperança de que o sistema se torne mais compreensível - usando todas as ferramentas que a literatura familiar a você descreve. Esses documentos são respaldados por uma abordagem de cima para baixo, pois agem de maneira intimidadora para os engenheiros - afinal, eles não são arquitetos e não devem duvidar ou contestar decisões, porque já foram documentados usando métodos formais nos quais são pouco versados. Portanto, eles geralmente não fazem isso. Honestamente, essas empresas fazem o mesmo para tornar os desenvolvedores um recurso intercambiável - porque isso lhes permite transferir pessoas de um projeto para outro em pouco tempo. Provavelmente não será uma surpresa para você que ferramentas diferentes sejam mais adequadas para ambientes diferentes.

Design simples de software sem jargão em vez de padrões arquiteturais


O objetivo do design do sistema deve ser a simplicidade. Quanto mais simples o sistema, mais fácil é entender - e mais fácil é encontrar problemas nele e implementá-lo. Quanto mais clara a linguagem pela qual é descrita, mais acessível é o design. Evite usar jargões que todos os membros da equipe não entenderão - mesmo os colegas mais inexperientes devem ser capazes de entender o que está em jogo no nível dos outros.

Um design limpo é como um código limpo: é fácil de ler e entender. Existem muitas maneiras excelentes de escrever código limpo. No entanto, muitas vezes você ouvirá que alguém sugere começar a aplicar padrões de design de "grupo de quatro" ao seu código. O código limpo começa com o princípio de responsabilidade exclusiva, nomes claros e convenções fáceis de entender. Esses princípios se aplicam igualmente à arquitetura pura.

Então, qual é o papel dos padrões arquiteturais? Acho-os úteis - tão úteis quanto os padrões de design de código. Eles podem fornecer idéias sobre como você pode melhorar seu código ou arquitetura. Pegue os padrões de design do código: noto por mim mesmo quando noto um singleton no código - e levanto as sobrancelhas e me aprofundo mais quando vejo uma classe que se comporta como uma fachada , mas, na verdade, apenas faz chamadas. Mas ainda não chegou o dia em que eu teria pensado: "uma fábrica abstrata está apenas pedindo aqui". Na verdade, demorei muito tempo para descobrir o que esse padrão faz e antes que me ocorresse; O entendimento veio como resultado do trabalho duro com injeção de dependência , uma das poucas áreas em que esse padrão é generalizado e extremamente útil . Também admito que, embora tenha passado muito tempo lendo e compreendendo os padrões de design da "turma dos quatro", eles tiveram muito menos influência no meu desenvolvimento profissional como programador do que o feedback que recebi de outros desenvolvedores em relação ao meu código.

Da mesma forma, conhecer padrões arquitetônicos comuns é uma coisa boa: ajuda a reduzir o tempo gasto em discussões com pessoas que os entendem da mesma maneira que você. Mas os padrões arquiteturais não são o objetivo e não substituirão as opções mais simples de design do sistema. Ao projetar um sistema, você repentinamente percebe que aplicou acidentalmente algum padrão comum - e isso é bom, porque mais tarde será mais fácil você se referir à abordagem usada. Mas você nunca deve pegar um ou mais padrões e usá-los como um martelo, para o qual sempre verá unhas.

Os padrões arquiteturais surgiram quando os engenheiros chamaram a atenção para o fato de que, em certas situações, faz sentido tomar decisões semelhantes em relação ao design e sua implementação. Com o tempo, essas decisões receberam nomes, foram registradas e discutidas pelo público em geral. Os padrões arquitetônicos são ferramentas que surgiram após a descoberta de soluções, na esperança de que isso ajudasse a facilitar a vida de outras pessoas. Como engenheiro, você deve definir como meta uma busca independente por soluções para seus problemas e aprender durante esse processo - em vez de adotar um padrão arquitetural de "hype" na esperança de que isso resolva seu problema.

Como aprender a projetar melhor os sistemas


As pessoas costumam me pedir conselhos: como "bombear" a arquitetura e o design dos sistemas? Engenheiros experientes geralmente recomendam a leitura sobre padrões arquiteturais, bem como livros sobre arquitetura de software. Apoio totalmente a recomendação de ler o máximo possível - especialmente livros, pois eles permitem que você mergulhe no assunto muito mais profundamente do que postagens curtas - no entanto, tenho algumas recomendações mais práticas.

  • Envolva um dos membros da equipe e faça o quadro branco juntos. Desenhe no quadro em que você está trabalhando e explique o significado da imagem. Certifique-se de que seus colegas entendam o que está sendo dito. E quando você finalmente for entendido, peça feedback.
  • Descreva seu design em um documento simples e compartilhe-o com sua equipe, solicitando feedback. Não importa o quão simples ou complexa a tarefa em que você está trabalhando - pode ser uma pequena refatoração ou um projeto de grande escala - você deve resumir isso concisamente. Faça de tal maneira que, para você, este documento faça sentido e, para o resto, seja compreensível; para inspiração - aqui está um exemplo de como isso é feito no Uber . Compartilhe este documento com sua equipe em um formato que permita comentar - por exemplo, usando o Google Docs, Office 365 ou algo semelhante. Peça a outras pessoas para complementá-lo com seus pensamentos e perguntas.
  • Crie dois desenhos diferentes e compare-os. Quando muitos de nós projetam arquitetura, eles geralmente seguem um caminho: aquele que aparece na cabeça deles. No entanto, a arquitetura não é algo em preto e branco. Crie uma segunda opção de design de arquitetura que também possa funcionar na sua situação. Compare os dois projetos e explique por que um é melhor que o outro. Indique que você considerou a segunda opção há algum tempo como uma alternativa e explique por que você tomou uma decisão que não era a favor dele.
  • Decida os compromissos que você está pronto para fazer - descubra por que os aceita e o que deseja alcançar com a ajuda deles. Estabeleça claramente as restrições existentes que você foi forçado a levar em consideração.
  • Realize uma revisão dos projetos de outras pessoas. E faça isso com sabedoria. Se a sua empresa possui uma cultura de compartilhamento de projetos que as pessoas compartilham usando o quadro de comunicações, reuniões ou documentos - obtenha mais deles. Geralmente, durante uma revisão, as pessoas percebem o design do código de outra pessoa como observadores; em vez disso, faça perguntas esclarecedoras para partes que você não entende. Pergunte quais alternativas eles consideraram. Pergunte quais compromissos eles fizeram e quais limitações eles consideraram. Seja o advogado do diabo e sugira outra alternativa, possivelmente mais simples - mesmo que não seja melhor que a solução deles - e pergunte o que eles acham da sua proposta. Mesmo que você não tenha pensado em seu design tão bem em comparação com quem o apresenta, sua discussão ainda pode trazer algo novo e ajudá-lo a entender melhor a tarefa que está realizando.

O melhor design de software é simples e fácil de entender. Na próxima vez em que você iniciar um novo projeto, em vez de ponderar a pergunta " Como vou projetar esse sistema, quais padrões devo usar na batalha e com qual metodologia formal devo documentá-lo? ", Pense - Como posso chegar ao design mais simples possível - um que será facilmente entendido por qualquer pessoa? "

As melhores práticas de arquitetura de software, padrões arquiteturais de aplicativos corporativos, formas formais de descrever sistemas são todas as ferramentas úteis para possuir, porque um dia elas podem ser muito úteis para você. Mas, ao projetar sistemas, vale a pena começar com um simples e continuar a mantê-lo o mais simples possível. Tente evitar a complexidade que arquiteturas e ferramentas formais mais complexas inevitavelmente trazem aos seus sistemas.

Este post causou uma discussão acalorada entre os trabalhadores da indústria que compartilharam suas experiências e atitudes em relação à arquitetura de software. Você pode ler essas discussões em Hacker News , Lobste.rs e Reddit .

Enquanto a maioria dos comentaristas concorda com a mensagem principal do artigo, outros observam que, na realidade, essa abordagem pode ser pouco aplicável ao mundo da "empresa sangrenta", onde os arquitetos "comem o pão" por um bom motivo; — 20 « », 300 IT- , — API, 5000 7000 .

Source: https://habr.com/ru/post/pt467997/


All Articles