Arquitetura de Software: simples e clara é subestimada
Tags: arquitetura, desenvolvimento, clean
Published: 2020-02-20 19:19:13

O texto abaixo é uma tradução livre do artigo escrito por Gergely Orosz, <a href="https://dev.to/gergelyorosz/software-architecture-clear-and-simple-design-is-underrated-2bj9">Software Architecture: Clear and Simple Design is Underrated</a>. Sintam-se convidados a sugerir correções e melhorias na tradução.

>Eu já pude, muitas vezes, projetar e desenvolver sistemas de grande escala. Fiz parte da reescrita dos sistemas distribuídos de pagamento do Uber, projetei e entreguei o Skype no Xbox One e o framework mobile open-source do Uber, RIBs. Todos esses sistemas tiveram projetos minuciosos, passando por várias iterações, com muito whiteboarding e muito debate. Os projetos se tornaram documentos de design que eram circulados para mais feedbacks antes de iniciarmos a desenvolver.

>Todos esses sistemas eram de larga escala: centenas de desenvolvedores os construíram – ou estavam envolvidos neles – e alimentavam os sistemas utilizados por milhões de pessoas por dia. Eles também não eram apenas projetos novos. O sistema de pagamento reescrito tinha que substituir dois sistemas já existentes, que eram utilizados por dezenas de outros sistemas e times. Tudo isso, sem impactar no negócio. Essa reescrita foi um projeto que algumas centenas de engenheiros trabalharam simultaneamente portando funcionalidades existentes para a nova arquitetura.

>Me deixe iniciar com algumas informações que podem surpreender. **Primeiro, nenhum desses projetos usava as ferramentas padrão de planejamento de arquitetura de software.** Nós não usamos UML, nem o modelo 4+1, nem ADR, nem o C4, tampouco diagramas de dependência. Nós criamos diversos diagramas, mas nenhum seguia estritamente alguma regra. Apenas os bons e velhos setas e caixas, similar a este que descreve informações de fluxo ou este que evidencia a estrutura das classes e os relacionamentos entre componentes. Era comum que dois diagramas dentro de um mesmo documento tivessem estruturas diferentes e eram comumente adicionados e alterados por engenheiros diferentes.

>**Segundo, não havia arquitetos nos times.** Verdade seja dita, nem o Uber e nem o Skype/Microsoft têm posições específicas para arquitetos. Nessas empresas, é esperado que engenheiros de alto nível ainda façam codificação regularmente. Para todos os projetos, nós tínhamos engenheiros experientes envolvidos. No entanto, ninguém era detentor da arquitetura ou do projeto. Mesmo que esses desenvolvedores experientes liderassem o processo de design, os membros mais junior do time estavam envolvidos também, desafiando as decisões tomadas e sugerindo alternativas para serem discutidas.

>**Terceiro, nós tínhamos praticamente zero referências aos padrões de arquiteturas comuns** e outros jargões utilizados na literatura da arquitetura de software, como o guia de arquitetura de Martin Fowler. Sem menções a micro serviços, serverless, fronteira de aplicação, arquitetura dirigida a eventos e tantas outras. Alguns desses conceitos surgiram durante os brainstormings. No entanto, não havia necessidade de referenciá-los nos documentos de design.

>###Design de software em empresas de tecnologia e startups

>Então, como nós fizemos? E porque não seguimos nenhuma abordagem conhecida de arquitetura de software?
>Tive essa discussão com engenheiros que trabalhavam em outras empresas de tecnologia - FANG (Facebook, Amazon, Netflix e Google) – e também em pequenas startups. A maioria dos times e projetos – pequenos e grandes – partilhavam uma abordagem similar de design e implementação. 
>1.	**Comece com o problema do negócio.** O que estamos tentando resolver? Quais produtos estamos tentando desenvolver e porquê? Como podemos medir o sucesso?
>2.	**Faça brainstorm da abordagem.** Reúna-se com o time várias vezes para descobrir qual solução irá funcionar. Mantenha esses brainstorms pequenos. Comece em alto nível e desça aos níveis mais baixos.
>3.	**Desenhe a abordagem.** Junto ao time escolha uma pessoa para desenhar a abordagem para qual o time está convergindo. Vocês devem ser capazes de explicar, facilmente, a arquitetura do sistema/aplicativo em uma lousa. Iniciando pelo alto nível e se aprofundando quando for necessário. Se vocês tiverem problemas com essa explicação ou caso ela não esteja clara o suficiente, é necessário trabalhar mais nos detalhes.
>4.	**Escreva a documentação de forma simples** com diagramas simples baseado no que vocês explicaram em lousa. Mantenha o mínimo de jargões possíveis. Vocês vão querer que mesmo engenheiros junior entendam do que se trata. Escreva o documento com linguagem clara e fácil de entender. Na Uber, nós usamos um documento parecido com RFC com um template básico.
>5.	**Fale sobre escolhas e alternativas.** Bom design de software e boa arquitetura se resumem a fazer as escolhas corretas. Nenhum design é bom ou ruim por si só; tudo depende do contexto e dos objetivos. Sua arquitetura se divide em diferentes serviços? Diga porque vocês decidiram isso em vez de um serviço grande, que pode ter outros benefícios, como deploy mais direto e rápido. Vocês escolheram estender um serviço ou módulo com novas funcionalidades? Compare com a opção de desenvolver um serviço ou módulo separado e quais são os prós e contras que esta abordagem pode ter.
>6.	**Circule o documento de design dentro dos times/organização para obter feedback.** No Uber, nós enviávamos nosso documento de design para todos os engenheiros, na época nós éramos em torno de 2000. Agora que somos bem mais, ainda distribuímos bem amplamente nosso documento, mas começamos a nos atentar mais à relação de sinal/ruído. Encoraje as pessoas a perguntarem e oferecerem alternativas. Sejam pragmáticos em definir prazos, para discutir os feedbacks e incorporá-los, onde for necessário. O feedback direto pode ser rapidamente abordado no local, enquanto um feedback mais detalhado pode ser mais rápido para se estabelecer pessoalmente.

>Porque nossa abordagem foi diferente do que é comumente escrito na literatura da arquitetura de software? Na verdade, nossa abordagem não é tão diferente assim, a princípio, da maioria dos manuais de arquitetura. Quase todos os guias sugerem iniciar com o problema de negócio e evidenciar as soluções e escolhas: que é o que fazemos. O que não fazemos é utilizar muitas das ferramentas complexas que muitos arquitetos e livros defendem. Nós documentamos o design o mais simples que conseguimos usando ferramentas diretas como Google Docs ou Office365.

>Acredito que a grande diferença na nossa abordagem reside na cultura de engenharia dessas empresas. Alta autonomia e pouca hierarquia é um traço que empresas de tecnologia e startups compartilham; algo que as vezes não é verdade em empresas mais tradicionais. Essa é a razão pela qual esses lugares realizam muito mais “design baseado em senso comum” do que design dirigido por processos, com regras restritas.

>Sei de bancos e empresas automotivas onde os desenvolvedores são ativamente desencorajados a tomarem decisões de arquitetura sem escalá-las, obtendo aprovação de arquitetos alguns níveis acima, que são responsáveis por acompanhar vários times. O processo se torna mais lento e os arquitetos podem ficar sobrecarregados com as demandas. Então esses arquitetos criam mais documentos formais, na esperança de tornar o sistema mais limpo, utilizando muito mais as ferramentas comuns que a literatura descreve. Esses documentos reforçam a ideia de hierarquia, já que é mais intimidador para o engenheiro, que não é um arquiteto, a questionar ou desafiar as decisões que já foram tomadas e documentadas usando métodos formais nos quais ele não está ambientado. Então ele geralmente não tenta. Para ser honesto, essas mesmas empresas querem otimizar os desenvolvedores tornando-os recursos intercambiáveis, permitindo-as a realocar as pessoas em diferentes projetos em curto prazo. Não deveria ser surpresa que diferentes ferramentas trabalhem melhor em ambientes diferentes.

>###Design de software simples e sem jargão em vez de padrões de arquitetura

>O objetivo em desenhar um sistema deve ser a simplicidade. Quanto mais simples o sistema, mais simples é para entende-lo, para encontrar problemas nele e para implementá-lo. Quanto mais clara for a linguagem para descrevê-lo, mais acessível é seu design. Evite utilizar jargões que não são de entendimento de todos os membros da equipe: a pessoa com menos experiência deve ser capaz de entender igualmente às demais.

>Design limpo é como código limpo: é fácil de ler e compreender. Existem muitos jeitos ótimos para escrever código limpo. No entanto, raramente você encontrará alguém sugerindo que você deve começar seu código aplicando padrões de projeto do GOF. Código limpo inicia-se com responsabilidade única, nomes claros e convenções fáceis de entender. Esses princípios aplicam-se à arquitetura limpa.

>Então, qual o papel dos padrões de arquitetura? Vejo-os de forma similar à utilidade dos padrões de projeto de código. Podem dar ideias de como melhorar seu código ou sua arquitetura. Para padrões de código, eu enxergo singleton quando vejo um e levanto minha sobrancelha e escavo mais quando vejo uma classe que age como uma facade apenas realizando chamadas. Mas ainda não consigo imaginar “isso pede por uma abstract factory”. Na verdade, me levou muito tempo para entender o que esse padrão faz para ter meu momento “aha!”, depois de trabalhar muito com injeção de dependência – uma das poucas áreas onde esse padrão é, de fato, muito comum e útil. Devo admitir também que, apesar de ter passado muito tempo na leitura e compreensão dos padrões de projeto do GOF, eles tiveram um impacto menor em me tornar um desenvolvedor melhor do que os feedbacks que recebi de outros engenheiros.

>Ao mesmo tempo, conhecer sobre padrões de arquitetura comuns é algo bom: ajuda a encurtar os debates com pessoas que os entendem da mesma forma que você. Porém, padrão de arquitetura não é o objetivo e não vai substituir designs simples de sistemas. Quando projetar um sistema, você pode se encontrar na situação de acidentalmente aplicar um padrão dos famosos, e isso é algo bom. Mais tarde você poderá referenciar sua abordagem mais facilmente. Mas a última coisa que você quer fazer é pegar um ou mais desses padrões e utilizá-los como martelo procurando pregos para pregar.

>Os padrões de arquitetura nasceram depois que engenheiros observaram quão similar eram as escolhas feitas em alguns casos e como eram implementadas de forma similar. Elas foram então nomeadas, escritas e debatidas extensivamente. Padrões de arquitetura são ferramentas que vem **depois** que uma solução foi criada, na esperança de facilitar a vida de todos. Como um engenheiro, seu foco deve ser resolver problemas e aprender com eles em vez de pegar um padrão de arquitetura lindo e cheiroso na esperança de que ele resolva todos os seus problemas.

>Melhores práticas de arquitetura de software, padrões de arquitetura corporativas e jeitos formais de descrever sistemas são ferramentas importantes para se conhecer e podem se tornar úteis eventualmente. Mas, quando estiver projetando um sistema, comece de forma simples e tente manter a simplicidade o quanto for possível. Tente evitar a complexidade que arquiteturas mais formais tendem a introduzir automaticamente.