Olá amigos. Antecipando o lançamento do curso
“Backend PHP Developer” , tradicionalmente compartilhamos com você a tradução de material útil.
O software resolve cada vez mais tarefas diárias, tornando-se cada vez mais difícil. Como Mark Andressen disse uma vez, engole o mundo.

Como resultado, as abordagens para o desenvolvimento e entrega de aplicativos mudaram drasticamente nos últimos anos. Foram mudanças de escala tectônica que, como resultado, levaram ao surgimento de um conjunto de princípios. Esses princípios se mostraram úteis na criação de equipes, no design, no desenvolvimento e na entrega de seu aplicativo aos usuários finais.
Os princípios podem ser resumidos da seguinte forma: o
aplicativo deve ser pequeno, conectado em rede e ter uma arquitetura orientada ao desenvolvedor . Com base nesses três princípios, você pode criar um aplicativo abrangente e confiável, que pode ser entregue com rapidez e segurança ao usuário final e pode ser facilmente dimensionado e expandido.

Cada um dos princípios propostos possui vários aspectos que discutiremos para mostrar como cada princípio contribui para a consecução do objetivo final, que é fornecer rapidamente aplicativos confiáveis e fáceis de manter e usar. Consideraremos os princípios em comparação com seus opostos, a fim de esclarecer o que significa, digamos: "Certifique-se de usar o
princípio da pequenez ".
Esperamos que este artigo o incentive a usar os princípios propostos para criar aplicativos modernos que forneçam uma abordagem unificada para o design no contexto de uma pilha de tecnologia sempre crescente.
Ao aplicar esses princípios, você
se beneficiará das últimas tendências de desenvolvimento de software, incluindo a abordagem do
DevOps para desenvolvimento e entrega de aplicativos, o uso de contêineres (por exemplo,
Docker ) e estruturas para orquestração de contêineres (por exemplo,
Kubernetes ), o uso de microsserviços (incluindo a
NGINX Microservice Architecture) e
arquitetura de comunicação de rede para aplicativos de microsserviço.
O que é uma aplicação moderna?Aplicações modernas? Pilha moderna? O que exatamente significa "moderno"?
A maioria dos desenvolvedores tem apenas uma idéia geral do que consiste um aplicativo moderno; portanto, é necessário fornecer uma definição clara desse conceito.
Um aplicativo moderno suporta vários clientes, seja uma interface do usuário na biblioteca JavaScript React, um aplicativo móvel para Android ou iOS ou um aplicativo que se conecte a outro por meio da API. Um aplicativo moderno implica a presença de um número indefinido de clientes para os quais fornece dados ou serviços.
Um aplicativo moderno fornece uma API para acessar os dados e serviços solicitados. A API deve ser imutável e constante, e não escrita especificamente para uma solicitação específica de qualquer cliente em particular. A API é acessível via HTTP (S) e fornece acesso a toda a funcionalidade que está na GUI ou na CLI.
Os dados devem estar acessíveis em um formato geralmente aceito e compatível, como JSON. A API fornece objetos e serviços de maneira clara e organizada, por exemplo, a API RESTful ou GraphQL fornece uma interface decente.
Aplicativos modernos são criados em uma pilha moderna, e uma pilha moderna é a pilha que suporta esses aplicativos, respectivamente. Essa pilha permite que o desenvolvedor crie facilmente um aplicativo com uma interface HTTP e limpe os pontos de extremidade da API. A abordagem escolhida permitirá que seu aplicativo receba e envie dados facilmente no formato JSON. Em outras palavras, a pilha moderna corresponde aos elementos do aplicativo Twelve-Factor para
microsserviços .
Versões populares desse tipo de pilha são baseadas em
Java ,
Python ,
Node ,
Ruby ,
PHP e
Go .
A arquitetura
NGINX Microservice representa um exemplo de uma pilha moderna implementada em cada um dos idiomas mencionados.
Observe que não defendemos exclusivamente uma abordagem de microsserviço. Muitos de vocês trabalham com monólitos que precisam evoluir, enquanto outros lidam com aplicativos SOA que se expandem e evoluem para se tornarem aplicativos de microsserviço. Outros ainda estão migrando para aplicativos sem servidor, e alguns estão apresentando combinações dos itens acima. Os princípios estabelecidos no artigo são aplicáveis a cada um desses sistemas com apenas algumas pequenas alterações.
PrincípiosAgora que temos um entendimento comum sobre o que é um aplicativo moderno e uma pilha moderna, é hora de mergulhar nos princípios de arquitetura e desenvolvimento que o ajudarão no desenvolvimento, implementação e suporte de um aplicativo moderno.
Um dos princípios é "criar pequenas aplicações", vamos chamá-lo de
princípio da pequenez . Existem aplicativos incrivelmente complexos que consistem em um grande número de componentes móveis. Por sua vez, a criação de um aplicativo a partir de pequenos componentes discretos simplifica seu design, manutenção e o trabalho com ele como um todo. (Observe que dissemos "simplifica", não "simplifica".)
O segundo princípio é que podemos aumentar a produtividade dos desenvolvedores, ajudando-os a focar nos recursos que eles desenvolvem, enquanto os livram de preocupações com a infraestrutura e o CI / CD durante a implementação. Então, em poucas palavras, nossa abordagem está
focada nos desenvolvedores .
Por fim, tudo sobre o seu aplicativo deve estar conectado à rede. Nos últimos 20 anos, fizemos grandes avanços em direção a um futuro em rede, pois as redes são mais rápidas e os aplicativos mais complexos. Como já descobrimos, um aplicativo moderno deve ser usado na rede por muitos clientes diferentes. O uso do pensamento de rede na arquitetura tem vantagens significativas que vão bem com o
princípio da pequenez e o conceito de uma abordagem
orientada ao desenvolvedor .
Se, durante o desenvolvimento e implementação do aplicativo, você observar esses princípios, terá uma vantagem inegável no desenvolvimento e na entrega do seu produto.
Vejamos esses três princípios em mais detalhes.
Princípio da pequenezÉ difícil para o cérebro humano perceber ao mesmo tempo uma grande quantidade de informações. Na psicologia, o termo carga cognitiva significa a quantidade total de esforço mental necessário para armazenar informações na memória. Reduzir a carga cognitiva nos desenvolvedores é uma prioridade, pois nesse caso eles podem se concentrar na solução do problema, em vez de se lembrar do modelo complexo atual de todo o aplicativo e das funções que estão sendo desenvolvidas.
Os aplicativos são decompostos pelos seguintes motivos:
- Diminuição da carga cognitiva nos desenvolvedores;
- Acelere e simplifique os testes;
- Entrega rápida de alterações no aplicativo.
Existem várias maneiras de reduzir a carga cognitiva para os desenvolvedores, e é aí que o princípio da pequenez entra em cena.
Portanto, existem três maneiras de diminuir a carga cognitiva:
- Reduza o prazo que eles devem levar em consideração ao desenvolver uma nova função - quanto menor o prazo, menor a carga cognitiva.
- Reduza a quantidade de código em que o trabalho único é realizado - menos código - menos carga.
- Simplifique o processo de fazer alterações incrementais no aplicativo.
Reduzir prazos de desenvolvimentoVoltemos aos dias em que a metodologia em
waterfall
era o padrão para o processo de desenvolvimento, e o prazo de seis meses a dois anos para o desenvolvimento ou atualização do aplicativo era prática comum. Normalmente, os engenheiros leem primeiro os documentos relevantes, como requisitos de produto (PRD), documento de referência do sistema (SRD), plano de arquitetura e começam a combinar todas essas coisas em um modelo cognitivo, segundo o qual eles escreveram o código. Como os requisitos e, consequentemente, a arquitetura foram alterados, esforços sérios tiveram que ser feitos para informar a equipe inteira sobre atualizações no modelo cognitivo. Na pior das hipóteses, essa abordagem poderia simplesmente paralisar o trabalho.
A maior mudança no processo de desenvolvimento de aplicativos foi a introdução da metodologia ágil. Uma das principais características da metodologia
agile
é o desenvolvimento iterativo. Por sua vez, isso leva a uma diminuição na carga cognitiva dos engenheiros. Em vez de exigir que a equipe de desenvolvimento implemente o aplicativo em um ciclo longo, a abordagem
agile
permite que você se concentre em pequenas quantidades de código que podem ser testadas e implantadas rapidamente, além de receber feedback. A carga cognitiva do aplicativo mudou do período de seis meses para dois anos, levando em consideração o grande número de especificações para uma adição de duas semanas ou alterações de recursos, visando um entendimento mais vago de um aplicativo grande.
Mudar o foco de um aplicativo massivo para pequenas funções específicas que podem ser concluídas em um sprint de duas semanas, prevendo apenas uma função do próximo sprint na cabeça, é uma mudança significativa. Isso nos permitiu aumentar a produtividade do desenvolvimento e reduzir a carga cognitiva, que flutuava constantemente.
A metodologia
agile
pressupõe que o aplicativo final será uma versão ligeiramente modificada do conceito original; portanto, o ponto final de desenvolvimento é necessariamente ambíguo. Somente os resultados de cada sprint específico podem ser claros e precisos.
Pequenas bases de códigoO próximo passo na redução da carga cognitiva é reduzir a base de código. Como regra, os aplicativos modernos são enormes - um aplicativo corporativo confiável pode consistir em milhares de arquivos e centenas de milhares de linhas de código. Dependendo da organização dos arquivos de comunicação e das dependências do código e dos arquivos, eles podem ser óbvios ou vice-versa. Até a depuração do código em si pode causar problemas, dependendo das bibliotecas usadas e quão bem as ferramentas de depuração distinguem entre bibliotecas / pacotes / módulos e código do usuário.
Construir um modelo mental funcional do código do aplicativo pode levar uma quantidade impressionante de tempo e, novamente, colocar uma grande carga cognitiva no desenvolvedor. Isso é especialmente verdadeiro para bases de código monolíticas, onde há uma grande quantidade de código, cuja interação entre os componentes funcionais não está claramente definida e a separação de objetos de atenção é frequentemente borrada, porque os limites funcionais não são respeitados.
Uma das maneiras eficazes de reduzir a carga cognitiva dos engenheiros é a transição para uma arquitetura de microsserviço. Na abordagem de microsserviço, cada serviço se concentra em um conjunto de funções; o significado do serviço é geralmente definido e compreensível. Os limites do serviço também são claros - lembre-se de que a comunicação com o serviço é realizada usando a API, para que os dados gerados por um serviço possam ser facilmente transferidos para outro.
A interação com outros serviços geralmente é limitada a vários serviços de usuário e vários serviços de provedor que usam chamadas de API simples e limpas, por exemplo, usando REST. Isso significa que a carga cognitiva no engenheiro é seriamente reduzida. A tarefa mais difícil é entender o modelo de interação entre serviços e como coisas como transações ocorrem em vários serviços. Como resultado, o uso de microsserviços reduz a carga cognitiva, reduz a quantidade de código, indica limites claros do serviço e fornece um entendimento do relacionamento entre usuários e provedores.
Pequenas mudanças incrementaisO último elemento do princípio da
pequenez é o gerenciamento de mudanças. É uma tentação especial para os desenvolvedores olharem para a base de código (mesmo, talvez, por conta própria, códigos mais antigos) e dizerem: "Isso é uma porcaria, precisamos reescrever tudo". Às vezes, essa é a decisão certa e outras não. Isso coloca o ônus da mudança global de modelo na equipe de desenvolvimento, o que, por sua vez, leva a uma enorme carga cognitiva. É melhor que os engenheiros se concentrem nas alterações que eles podem fazer durante o sprint, a fim de implementar posteriormente a funcionalidade necessária em tempo hábil, ainda que gradualmente. O produto final deve lembrar um pré-planejado, mas com algumas modificações e testes para atender às necessidades do cliente.
Ao reescrever grandes partes do código, às vezes é impossível entregar alterações rapidamente, pois outras dependências do sistema entram em jogo aqui. Para controlar o fluxo de alterações, você pode usar o recurso oculto. Em princípio, isso significa que a funcionalidade está em produção, mas não está disponível usando as configurações de variáveis de ambiente (env-var) ou algum outro mecanismo de configuração. Se o código passou em todos os processos de controle de qualidade, ele pode estar em produção em um estado oculto. No entanto, essa estratégia só funciona se o recurso estiver ativado. Caso contrário, ele apenas desarruma o código e adiciona carga cognitiva, com a qual o desenvolvedor precisará lidar com o trabalho produtivo. O gerenciamento de mudanças e mudanças incrementais em si mesmas ajudam a manter a carga cognitiva dos desenvolvedores a um nível acessível.
Os engenheiros precisam superar muitas dificuldades, mesmo com a simples implementação de funcionalidades adicionais. Por parte da gerência, seria razoável reduzir a carga extra na equipe para que ela pudesse se concentrar nos elementos-chave do funcional. Há três coisas que você pode fazer para ajudar sua equipe de desenvolvimento:
- Use metodologia
agile
para limitar o prazo dentro do qual uma equipe deve se concentrar nas principais funções. - Implemente seu aplicativo como vários microsserviços. Isso limitará o número de recursos sendo implementados e fortalecerá os limites que retêm a carga cognitiva durante o trabalho.
- Prefira alterações incrementais a grandes e volumosas, altere pequenos pedaços de código. Use a ocultação de recursos para implementar alterações, mesmo se elas não estiverem visíveis imediatamente após a adição.
Se você aplicar o princípio da pequenez em seu trabalho, sua equipe ficará muito mais feliz, concentrará-se melhor na implementação das funções necessárias e terá maior probabilidade de implementar mudanças qualitativas mais rapidamente. Mas isso não significa que o trabalho não possa ser complicado; às vezes, pelo contrário, a introdução de novas funcionalidades exige a modificação de vários serviços e esse processo pode ser mais complicado do que o semelhante em uma arquitetura monolítica. De qualquer forma, os benefícios de uma pequena abordagem valem a pena.
O fim da primeira parte.
Em breve publicaremos a segunda parte da tradução e agora aguardamos seus comentários e convidamos você a
abrir o dia , que será realizado hoje às 20h00.