Boas práticas de arquitetura com NodeJS + Express

Workshop IFRS
Workshop IFRS

Quando trabalhamos com uma plataforma nova como o Node.js, é muito comum ficarmos em dúvida de como proceder com a escala de nossas aplicações e principalmente com a arquitetura da mesma, conforme vão crescendo.

Além disso, considerando os fundamentos do Node.js, o fato de trabalhar com Javascript e sua inerente dinamicidade e pouco apreço por tipagem, orientação à objetos e muito mais, torna a transição de programadores mais tradicionais (Java, C#, etc) para esta plataforma um tanto confusa.

Eu mesmo, tenho feito apenas pequenos projetos em Node.js pois ainda não me sinto confortável para construir (se é que devo) grandes projetos com ele.

Esse post é para compartilhar as melhores dicas e boas práticas de arquitetura que tenho encontrado na Internet sobre a construção de aplicações Node.js, especialmente usando o Express, o framework de aplicações web mais famoso para Node.

O quão grande é a sua aplicação?

Aplicações web não são sempre a mesma coisa e, da mesma forma, não há uma única arquitetura e/ou estrutura de código que possa ser aplicada à todas aplicações express.js.

Sim, é possível criar grandes aplicações em Node.js uma vez que grandes empresas estão fazendo exatamente isso nos últimos anos, como Walmart, Netflix e Uber, só para citar algumas. A questão aqui é: sua aplicação realmente é grande e precisa de uma arquitetura como a deles?

Se sua aplicação é pequena, você não precisa de uma estrutura complexa de diretórios como a que vou mostrar aqui. Mantenha sua aplicação simples, garanta que os arquivos mais importantes estarão na raiz do diretório e está feito.

Agora, se sua aplicação é gigantesca, em algum ponto você pode precisar quebra’-la em pacotes NPM separados (semelhante ao que fazemos com as class libraries em Java e C#). Em geral, o que se recomenda a fazer com Node.js é sempre trabalhar com pacotes pequenos, especialmente para bibliotecas, uma vez que o fato de usar a linguagem Javascript não ajuda muito em manter o controle e previsibilidade de funcionamento em uma aplicação conforme ela fica muito grande. Sendo assim, conforme sua aplicação for crescendo e partes do seu código comecem a se tornar reutilizáveis, mova-os para um pacote como se fosse um subsistemas ou biblioteca, tornando-o independente no NPM.

Com iso em mente, o restante deste artigo foca em dicas e princípios para construção de uma estrutura funcional boa para aplicações médias que contenham as seguintes características:

  • O site tem algumas páginas e templates estáticos
  • A parte dinâmica do site é desenvolvida usando um estilo SPA
  • A aplicação expõe uma API no estilo REST/JSON para o navegador consumir
  • Os modelos da aplicação são de um único domínio de negócio, como por exemplo um site de revenda de automóveis.

Dito isso, vamos às dicas.

Princípios e Motivações Principais

Acima de qualquer estrutura que eu possa propor aqui, vale ressaltar alguns princípios e motivações que devem estar acima de quaisquer convenções em seu código:

Ajude seu cérebro a entender o projeto. Conseguimos lidar com apenas pequenas quantidades de informação de cada vez. Por isso que usamos pastas. Por isso que criamos funções. Elas nos ajudam a lidar com a complexidade do sistema nos permitindo mexer em pequenas porções dele de cada vez.

Crie apenas os diretórios que precisa. Não saia criando dezenas de diretórios que acabarão vazios ou com apenas um arquivo dentro. Comece com o básico de pastas que você precisa e vá adicionando conforme a complexidade for aumentando. Afinal, você não compra um ônibus como primeiro veículo pensando no dia em que pode querer dar carona para muita gente, certo?

Torne fácil localizar arquivos de código. Os nomes de pasta devem ser significativos, óbvios e fáceis de entender. Código que não é mais usado, bem como arquivos antigos, devem ser removidos do projeto, e não apenas comentados ou renomeados. Além disso, todos os códigos ficam dentro de um diretório app na raiz e seus subdiretórios, para facilitar buscas posteriores, especialmente via linha de comando. Ah, e o padrão do npm é usar nomes sempre em minúsculo para as pastas, sem acentos, e com os espaços substituídos por hífens (-). Então é melhor seguir esta regra, por mais que não goste dela.

Agrupe por feature, não por responsabilidade. Esta é uma sugestão que vai contra o que a maioria de nós está acostumado, de separar os arquivos por responsabilidade (controller, model, etc). Cada feature da sua aplicação Node possui uma série de arquivos que, se estiverem juntos (em uma pasta por feature), fica mais fácil de dar manutenção depois. Ex: preciso adicionar um novo campo em um model, na mesma pasta eu já posso mexer no controller que usa aquele model.

Guarde seus testes perto do seu código. Essa ideia vai de encontro à anterior. Coloque o arquivo JS de testes de cada feature na mesma pasta da feature, para facilitar os testes e correção dos bugs encontrados. Também ajuda a lembrar das features que ainda não possuem testes codificados.

Para não se perder com os nomes de arquivos a sugestão é usar uma convenção de nome baseada em sufixo, por exemplo:

  • o arquivo JS original é foo.js
  • o arquivo de teste do original é foo.test.js

Diminua o acoplamento e aumente o reuso de software. A ideia com essas duas últimas dicas é tornar sua aplicação mais modular, com cada feature sendo um módulo mais independente. Aqui a ideia permanece. Uma vez que você tenha módulos independentes, sua aplicação fica menos acoplada e a manutenção mais simples. Uma dica para aumentar o reuso de software mantendo o acoplamento baixo é não colocar código “especializado” nas suas chamadas de model e controller. Ex: após salvar um cliente no banco você precisa enviar um email pra ele. Não coloque o código que envia email logo após o salvamento no banco. Ao invés disso, dispare uma função de um módulo de email.

Priorize configuration over convention. Não faça coisas mágicas como assumir que o nome de um arquivo é x ou que os uploads vão parar sempre em uma pasta y. Isso é frágil e facilmente quebra sua aplicação quando alguma coisa muda e você não lembra de todas as convenções que criou para sua arquitetura. Programe de maneira que o código em si possa fazer com que o programador entenda todo o projeto.

Convencione nomes de arquivos no formato ‘lower-kebab-case’. Use apenas minúsculas e ‘-‘ como separador entre palavras. Isso evita problemas de sistemas de arquivos em SOs diferentes que sua aplicação Node possa rodar. Ex: cadastro-cliente.js

Outras dicas úteis

Somente app/server.js deve carregar o módulo app/config.js. Assim, ele se encarrega de passar os objetos options menores para configurar os demais subsistemas ao invés de ficar todo mundo carregando um arquivo cheio de informações globais, causando acoplamento desnecessário.

Centralize a criação de conexões ao banco. Passe as conexões criadas para os subsistemas ao invés de ficar passando informações de conexão por parâmetro e permitindo que eles criem suas próprias conexões.

Centralize o acesso às variáveis de ambiente NODE_ENV, mais especificamente no app/config.js. Os demais locais da sua aplicação que necessitem de variáveis de ambiente devem esperá-las por parâmetro.

Para mais dicas e exemplos de projetos usando estes princípios, dê uma olhada nesse repositório do Github, que serviu de inspiração para esse post.

Introdução à Arquitetura de Micro Serviços

Workshop IFRS
Workshop IFRS

Tem uns 2 anos que passei a ouvir falar de micro serviços (microservices) mas faz poucos meses que passei a me interessar realmente pelo tema, uma vez que comecei a estudar Node.js para uso em meus projetos.

Micro serviços é uma maneira particular de desenvolver aplicações de maneira que cada módulo do software é um serviço standalone cujo deploy e escala acontecem de maneira independentes da “aplicação principal”. Enquanto na arquitetura tradicional de software, chamada monolítica, quebramos uma grande aplicação em bibliotecas, cujos objetos são utilizados in-process, em uma aplicação modular como proposta na arquitetura de microservices cada módulo recebe requisições, as processa e devolve ao seu requerente o resultado, geralmente via HTTP.

A ideia não é exatamente nova, é usada em ambientes Unix desde a década de 60, mas recentemente se tornou o epicentro de uma grande revolução na forma como as empresas estão desenvolvendo software ágil baseado em equipes enxutas responsáveis por componentes auto-suficientes.

Neste post irei abordar os conceitos, detalhes, vantagens, desvantagens e principais dúvidas dessa arquitetura, bem como porque ela está sendo tão utilizada atualmente e como começar a organizar suas aplicações orientadas dessa maneira.

Veremos neste artigo:

A motivação por trás dos micro serviços

Muitas são as buzzwords do mundo de desenvolvimento de software e esta me pareceu mais uma quando a ouvi pela primeira vez. Apesar do seu nome ser auto-explicativo, é interessante estudarmos os reais impactos que uma arquitetura composta por diferentes módulos conversando via um canal lightweight como HTTP pode causar na forma como programamos e nos resultados que obtemos com software.

Resumidamente, o estilo de arquitetura em microservices é uma abordagem de desenvolver uma única aplicação como uma suíte de pequenos serviços, cada um rodando o seu próprio processo e se comunicando através de protocolos leves, geralmente com APIs HTTP. Estes serviços são construídos em torno de necessidades de negócio e são implantados de maneira independente geralmente através de deploy automatizado (pelo menos em um cenário ideal deveria ser assim). Existe um gerenciamento centralizado mínimo destes serviços e cada um deles pode ser escrito em uma linguagem diferente e utilizando persistências de dados diferentes também.

Para entender melhor a motivação por trás de microservices vale relembrar como os projetos são programados hoje, geralmente em três grandes partes: um client-side com a interface do usuário, uma base de dados com as informações do sistema, e uma camada server-side com a lógica da aplicação. A camada server-side lida com as requisições do usuário, executa a lógica de negócio, retornar e atualiza dados da base e disponibiliza informações prontas para o client-side exibir. Isto é um monólito ou aplicação monolítica, uma vez que gera uma única e grande aplicação com tudo junto. Qualquer mudança no sistema envolve em compilar tudo novamente e implantar uma nova versão do server-side inteiro no servidor.

Toda a aplicação roda em um único processo, usando uma única linguagem server-side e geralmente uma única tecnologia de persistência de dados. Para escalar esse tipo de aplicação você pode adicionar mais recursos no mesmo servidor (escala vertical) ou fazer cópias desse servidor e colocá-las atrás de um load balancer (escala horizontal).

Aplicações monolíticas não são ruins e podem ser muitíssimo bem sucedidas. No entanto, cada vez mais equipes estão frustradas com suas limitações, principalmente quando estão implantando projetos na nuvem. Nestes cenários, os ciclos de mudanças, geralmente rápidos e pontuais como os propostos no Lean Startup, acabam afetando toda a aplicação pois o deploy é monolítico, assim como a aplicação. A escala horizontal requer um custo alto, pois sempre deve ser duplicada a aplicação inteira, e não apenas a parte que necessita de mais desempenho.

Vale lembrar também que aplicações monolíticas exigem que todo o codebase server-side seja escrito na mesma linguagem de programação, o que impede que você tire o máximo proveito de cada cenário usando a ferramenta mais apropriada à ele. Também impede que cada time desenvolva com a maior velocidade possível uma vez que a base de código é a mesma entre todos times.

Estas frustrações levam à arquitetura microservices de construir aplicações como um conjunto de serviços. Como os serviços são implantados de maneira independente, a escala se dá individualmente, tanto na vertical quanto na horizontal, para os serviços que estão precisando de mais desempenho. Usando protocolos comuns e contratos (interfaces) bem definidos, você consegue usar linguagens de programação diferentes de cada serviço, bem como mecanismos de persistência auxiliares que possam ser necessários para cada um deles, como mecanismos de cache, filas, índices, etc.

Para finalizar esta seção, a imagem abaixo do blog do Martin Fowler ilustra bem a diferença da escala entre as duas arquiteturas: monolítica e de micro serviços:

Vantagens e desvantagens de microservices

Não existe uma definição formal de como uma aplicação baseada em micro serviços deve ser construída, mas depois de muito ler a respeito e estudar o assunto notam-se algumas particuliaridades frequentes que podemos denominar como um padrão comum para microservices.

Sempre existiu o desejo dentro da indústria de software de construir programas apenas plugando componentes. Os primeiros esforços neste sentido foram as bibliotecas de funções, mais tarde as bibliotecas de classes e atualmente está em voga os serviços. Note que a componentização sempre existiu, mas o que propõe-se com microservices é que cada componente seja uma aplicação separada e especializada em apenas uma parte da aplicação “completa”. A principal razão por trás dessa escolha, de serviços ao invés de bibliotecas, é que serviços podem ser implantados de maneira separada. Você já tentou atualizar seu software apenas subindo para produção uma DLL ao invés de todas (ou ao menos todas as suas)? É um risco que não vale a pena correr, pois o acoplamento entre as DLLs é muito alto e o ideal é sempre a recompilação do sistema como um todo.

Claro, existe uma desvantagem clara no uso de serviços ao invés de bibliotecas: performance. Bibliotecas rodam no mesmo processo da aplicação, usam memória compartilhada, etc. Serviços dependem de canais de comunicação, como HTTP, para conseguirem tratar e responder as requisições. Exigem também uma coordenação entre os contratos de serviço para que os consumidores consigam “conversar” com os serviço da maneira que eles esperam, bem como receber as respostas que estão preparados.

Esse problema é especialmente preocupante conforme você tenha muitas chamadas síncronas entre seus serviços, pois o tempo de espera total para seu sistema responder será igual à soma de todos os tempos de espera das chamadas síncronas. Neste momento você tem duas opções: mudar para uma abordagem assíncrona ou reduzir o máximo que puder o tempo de espera (e a quantidade) das requisições síncronas. Node.js é uma tecnologia que tenho estudado bastante recentemente e trabalha muito forte com o conceito de chamada assíncronas, muito usado pelo Netflix para não bloquear a experiência do usuário. No entanto, quando isso não é possível, como foi o caso do site do jornal The Guardian, tente limitar o número de chamadas síncronas que você vai precisar, o que no caso deles é a regra de apenas uma chamada síncrona por requisição do usuário.

Apesar desses problemas citados, os benefícios parecem superar os downsides dessa abordagem, pois cada vez mais empresas estão adotando-na.

O que você deve ter em mente

Os serviços irão falhar. Talvez não todos juntos, talvez não rapidamente, mas vaia acontecer. Sendo assim, você deve estar sempre preparado para a falha de um ou mais serviços.

Essa é uma consequência de usar serviços como componentes e sua aplicação deve ser projetada de maneira que possa tolerar a falha de serviços. Qualquer chamado a um serviço pode falhar devido à indisponibilidade de um fornecedor e você tem de saber lidar com isso de maneira amigável com o restante do sistema. Esta talvez seja a maior desvantagem dessa arquitetura se comparada ao jeito monolítico tradicional, uma vez que adiciona uma complexidade adicional significativa. Times que trabalham com micro serviços devem constantemente refletir como a falha de cada serviço afetará a experiência do usuário. No Netflix por exemplo, partes da bateria de testes diária deles inclui derrubar servidores e até datacenters para ver como a aplicação se comporta nestas situações.

Uma aplicação em micro serviços deve ser monitorada em um nível muito superior ao de uma aplicação monolítica tradicional, uma vez que os serviços podem falhar a qualquer momento e se possível, restaurar o funcionamento completo automaticamente. Monitoramento em tempo real deve ser enfático no processo de desenvolvimento, implantação e operação dos serviços. Não que você não tenha de ter esse mesmo cuidado com aplicações monolíticas, mas apenas que com micro serviços isso não é uma opção.

O quão grande é/deve ser um micro serviço?

Uma pergunta bem comum e que cai como uma luva para o próprio nome da “arquitetura’ é: o quão grande deve ser um micro serviço?

Infelizmente o nome micro serviço nos leva a perder tempo demais pensando no que exatamente micro quer dizer. Diversas empresas, de Amazon a Netflix, usam micro serviços de variados tamanhos e não há um consenso sobre eles. Especificamente na Amazon, considerando que cada micro serviço é (e deve) ser tratado como um produto separado e tem seu próprio time (squad, na verdade), eles usam a regra Two Pizza Team: se o time precisa de mais de duas pizzas por refeição para se manter alimentado é porque está grande demais, o que significa não mais de que 12 pessoas. No outro extremo, os menores times recomendados pela Amazon possuem 6 pessoas, o que eu pessoalmente, em minhas experiências como Scrum Master, acredite ser o ideal (você ainda pode chamar meus times de Two Pizza Team considerando que todo mundo gosta de comer vários pedaços de pizza!).

Resumindo, embora não exista uma regra, podemos assumir que se você precisa de uma equipe de mais de 12 pessoas para desenvolver e manter um serviço (considerando tudo: programação, infra, testes, etc), ele está grande demais e você deveria quebrá-lo em serviços menores.

Como começar com micro serviços?

Projetos usando micro serviços geralmente não nascem assim do dia para a noite. O que nota-se na maioria das implementações bem sucedidas é que elas vieram de um design evolucionários, vendo a decomposição em serviços como uma ferramenta que vai aos poucos ajudando a quebrar uma aplicação monolítica que está com problemas de escala, qualidade, etc em diversos componentes menores.

Neste cenário, o maior desafio é saber como que o monólito irá ser quebrado em serviços. O quê deve ser agrupado em conjunto? O que deve estar separado? Quais bases de dados serão usadas por quais serviços?

Um dos princípios-chave por trás dessas decisões é o de deploy e escala independentes entre os serviços. Se dois serviços sempre tem de ser colocados em produção em conjunto, eles deveriam ser um serviço só. Agora se eu tenho um serviço cujas publicações acontecem sempre por causa de alterações pequenas em um dos seus módulos internos, esse módulo interno deveria ser transformado em um serviço per se.

O site do jornal britânico The Guardian é um bom exemplo de aplicação que foi projetada e construída como um monólito e que vem evoluindo na direção de micro serviços. O monólito ainda é o core do site, mas eles têm adicionado novas funcionalidades usando micro serviços que consomem a API do site principal. Esta abordagem é particularmente interessante pra eles principalmente nos casos de módulos temporários, como um hotsite para cobrir um evento esportivo.  Estes hotsites podem ser programados rapidamente na linguagem que for mais conveniente e jogados fora uma vez que não fazem mais sentido.

E aí, motivado para trabalhar com essa abordagem? Vamos trocar experiências nos comentários!

 

9 vantagens de usar Scrum em seus projetos

700x395xteam.jpg.pagespeed.ic.f9By3MZ2aODesde 13 de novembro de 2001 pra cá, quando o Manifesto Ágil foi assinado por 17 das mentes mais brilhantes da indústria de software à época, que o hype em torno de métodos ágeis só cresce. Em parte pelo demérito dos métodos tradicionais de desenvolvimento que priorizam muitas vezes a burocracia em detrimento do resultado, mas gosto de pensar que a principal razão é porque Scrum e cia realmente funcionam.

No entanto, para quem é novo nesse mundo ágil e apenas ouviu falar em buzzwords (e bizarrices) como planejamento com Poker, reuniões em pé e equipes sem chefe, fica difícil entender porque alguém adotaria tais excentricidades no seu ambiente de trabalho.

Por que eu realmente devo utilizar métodos ágeis em meu ambiente de trabalho?

Por que usar Scrum?

Quais as vantagens?

No post de hoje falarei de 9 vantagens inerentes à aplicação de Scrum no seu time, embora os métodos ágeis compartilhem de praticamente as mesmas premissas.

#1 – Adaptabilidade

O controle de processos empíricos e a entrega iterativa fazem com que os projetos sejam adaptáveis e abertos à incorporação de mudanças.

Enquanto os métodos tradicionais de desenvolvimento, em especial o cascata, valorizam análise extensa e definições rígidas de requisitos, visando “segurança” (ou a falsa sensação dela), o Scrum abraça a imprevisibilidade que um projeto longo possui ao inserir mais resiliência em projetos.

Isso não é apenas algo etéreo, está lá, documentado no Scrum Guide como o terceiro pilar do framework!

bruce-lee

Como diria Bruce Lee, abrace a mudança, a imprevisibilidade, seja como a água, meu amigo! Não apenas o chinês está muito certo como outro dito oriental, desde vez japonês, do Karatê Goju-ryu, fala sobre resiliência quando cita que os pinheiros que duram mais tempo são aqueles que “aprendem” a se vergar nas tempestades. De nada adianta uma árvore imponente se ela for rígida e “imóvel”, sempre haverá uma tempestade forte o bastante para quebrá-la, e o mesmo acontece com projetos.

Como diria a equipe dev do Spotify, construa princípios sólidos e metas claras, mas adapte a execução conforme a necessidade. Isso é ser ágil.

#2 – Transparência

Todos as fontes de informações, tais como, o quadro de tarefas (Kanban) e o gráfico Burndown, são compartilhadas gerando um ambiente de trabalho aberto.

Na administração tradicional a Gestão à Vista não é algo novo e comprovadamente vantajoso para as organizações. Isso porque permite que todos vejam o que está acontecendo e consigam tomar atitudes em relação à isso.

Scrum fala de adaptação, mas não há como se adaptar ao que não se consegue ver, e por isso que o primeiro pilar da metodologia é a transparência. Tudo começa com ela.

Sem transparência não há:

  • inspeção adequada
  • adaptação
  • engajamento
  • confiança
  • evolução do time
  • sucesso no projeto

Gerentes temem expor informações que possam gerar medos e conflitos no time. Ao fazerem isso, impedem que o time amadureça e realmente “abrace a causa”. John Maxwell diz que não tem como o time saber se está ganhando se ele não pode ver o placar!

John-Maxwell-Quotes-3-1024x678

Tem um ditado que diz também o seguinte (adoro eles!): se você não sabe para onde está indo, qualquer lugar serve. Um projeto não fracassa se não havia um objetivo para o mesmo, certo?!

#3 – Feedback Contínuo

O feedback contínuo é fornecido através de processos denominados como a Reunião Diária e a Sprint Review.

O Scrum fornece diversos mecanismos de feedback, o que garante o segundo pilar do framework: inspeção.

Feedback contínuo não é dar tapinhas nas costas na reunião de final de ano da empresa. Feedback contínuo tem a ver com transparência, pois o time precisa saber se suas ações estão gerando resultado. Você precisa saber se está no caminho certo. O seu colega precisa saber como pode lhe ajudar e você precisa saber se ele precisa de ajuda também.

Inspeção leva à adaptação, em um ciclo virtuoso que gera a melhoria contínua.

4# – Melhoria Contínua

As entregas melhoram progressivamente, Sprint por Sprint, através do processo de refinamento do Backlog do Produto e do processo em si.

Na metodologia de inovação em startups denominada Lean Startup, existe um ciclo chamado construir-medir-aprender (build-measure-learn no original) que trabalha da seguinte maneira:

  1. Você constrói um incremento de produto
  2. Você mede o desempenho dele
  3. Você aprende com os erros e refina-o
  4. Volte ao passo 1

E assim o é também no Scrum.

O framework é enxuto, apenas 19 páginas. Talvez não cubra nem sequer 10% da “ciência” da gestão de projetos. Mas os seus princípios fundamentais te ajudam a pensar de uma maneira diferente, com o mindset correto. Ele próprio te ensina que a inspeção vai te levar inerentemente ao aprendizado (adaptação) e com isso à melhoria contínua dos processos e produtos.

Esqueça aquela ideia que alguns métodos pregam que você deve apenas confiar cegamente em um livro e seus problemas estarão resolvidos!

#5 – Entrega Contínua de Valor

Os processos iterativos permitem a entrega contínua de valor tão frequente quanto exigido pelo cliente.

Tenha em mente que ninguém compra software. Ninguém.

“Como assim?” você deve estar se perguntando agora… Sim, as empresas que usam softwares nunca quiseram ter aqueles programas instalados em seus servidores ou nas máquinas dos funcionários. Eles sempre quiseram soluções para seus problemas, sempre quiseram ser mais produtivas, mais assertivas, mais competitivas, etc.

Só quem gosta de software é programador. Cliente gosta de solução que entrega valor. Se o seu time não entrega valor, ele não vai ir muito longe. E se ele demora demais para entregar valor, também não.

A chave aqui é entregar valor continuamente, em pequenas porções mas frequentes, deixando sempre o cliente satisfeito e com um “gostinho de quero mais”. A cada iteração do Scrum (sprint), um incremento de produto é entregue ao cliente, um que gera valor ao mesmo. É assim que tem que ser em todos os projetos.

Você nunca terá como entregar tudo o que o cliente quer, no prazo que ele quer e dentro do orçamento dele. Isso não existe!

Mas o processo de criar e priorizar um Backlog de Produto garante que as exigências de maior valor ao cliente sejam atendidas primeiramente e que o valor que ele tanto busca (não confunda valor com custo) seja entregue em partes, à cada iteração.

Uma abordagem colaborativa com stakeholders (como a do Scrum) e a ênfase no valor de negócio, garantem uma estrutura orientada para o cliente. E não orientada ao software.

Lembre-se: seus clientes não querem seus softwares. Eles querem o valor gerado pelos mesmos. Eles querem ser “melhores” do que eram antes de comprar seu software.

#6 – Eficiência

O Time-boxing e a minimização de trabalho não-essencial conduzem a níveis mais altos de eficiência.

Eu sou obcecado por eficiência. Admito.

Já escrevi aqui no blog sobre como conduzir reuniões mais eficientes, sobre como ser uma pessoa mais eficiente e muitas outras dicas nesse mesmo sentido. E o Scrum, o meu framework ágil favorito prioriza a eficiência, por isso que o amo. S2

As coisas mais excêntricas existentes no Scrum são em prol da eficiência. E por isso que seguir o Scrum à risca é tão importante, principalmente em equipes imaturas do ponto de vista de agilidade.

Pense nas time-boxes: restrições pétreas quanto à duração de eventos no ciclo de desenvolvimento. Sprints de x semanas. Reuniões de x horas. E por aí vai. Isso não é algo negociável. Esse tipo de restrição estimula os desenvolvedores do time a pensar no que é mais importante ser desenvolvido HOJE rumo ao objetivo de AMANHÃ. Não há tempo a perder com coisas que não gerem valor à meta da sprint. Estimula o Product Owner a manter o backlog priorizado com o que realmente deve entrar no produto na próxima sprint, deixando para um futuro incerto o que não é essencial à aplicação.

Todos sabemos (ou deveríamos saber) que a falácia da próxima feature e a over-engineering são alguns dos piores maus que podem arruinar um projeto de software e até mesmo uma empresa. As restrições de tempo do Scrum (e as demais também) te ajudam a não cair nessas tentações, como essa outra, de reescrever todo o código da sua aplicação para que fique “melhor”, por exemplo.

#7 – Motivação

Os processos de conduzir a Reunião Diária e de Retrospectiva da Sprint conduzem a níveis mais altos de motivação entre os colaboradores.

Uma das chaves para a motivação é o que Simon Sinek chama de Golden Circle, neste brilhante vídeo. Conforme evidenciado não apenas nesse trabalho (do vídeo) mas em muitos outros, é necessário um ambiente de alta confiança para que o time se sinta motivado a seguir em frente em prol dos objetivos gerais da sprint.

Processos do Scrum (sim, ele ajuda nisso também) como a Reunião Diária e a Retrospectiva da Sprint promovem a transparência (pilar 1, lembra?) e a colaboração, resultando em um ambiente de trabalho de alta confiança, e garantindo baixo atrito entre os colaboradores, além de uma alta motivação, uma vez que o time tem o suporte e aval necessários para que consiga avançar sem impedimentos (né, sr. Scrum Master?!).

Quando os times confiam sem si mesmos e seus líderes confiam no time, a motivação se torna algo inabalável, gerando a responsabilidade coletiva e o comprometimento, que é o que todo gerente quer da sua equipe e toda empresa quer ver nos seus funcionários.

O processo de aprovar, estimar e comprometer-se às tarefas (ou histórias de usuário, casos de uso, etc) permite que os membros do time se sintam responsáveis pelo projeto e por seu trabalho, resultando em uma qualidade muito maior. Não importa se você vai usar planning poker ou não, mas se não houver confiança no time para tomar essas decisões, não haverá motivação para executar as tarefas.

Tudo começa na confiança!

#8 – Alta Velocidade

Uma estrutura de colaboração permite que os times multifuncionais atinjam o seu pleno potencial e alta velocidade.

Se o seu time vem vencendo nos demais quesitos como motivação, entrega contínua de valor, transparência, adaptação, etc você terá o que todo gerente de software almeja: alta velocidade!

Pausa para aquele momento em que uma música de cornetas toca e as nuvens se abrem para os céus porque você atingiu a iluminação.

Não, agilidade não é entregar software, pura e simplesmente, mais rápido. É sobre entregar valor mais cedo. Mas quando você entrega valor mais cedo, a percepção que TODOS tem (interna e externamente) é que o time está avançando mais rápido.

Pense comigo: o que vale mais, eu (um professor sedentário) correndo em linha reta por 100m ou o Usain Bolt correndo em zigue-zague para chegar no mesmo destino que está 100m à frente? É o mesmo para software!

Se você não está trabalhando com um backlog priorizado, não está entregando software com foco no cliente (ou seja, entregando valor pra ele), você está “andando em zigue-zague” rumo ao mesmo objetivo que poderia estar perseguindo em linha reta!

A alta velocidade obtida com o Scrum não está na quantidade de linhas de código que seu time vai escrever por sprint. Mas sim nas linhas certas que serão escolhidas para serem escritas. Aquelas que trarão os maiores resultados para o cliente em menos tempo.

Ponto.

Isso é velocidade, de maneira inteligente!

#9 – Ambiente Inovador

Os processos de Retrospectiva da Sprint e de Review da Sprint criam um ambiente de introspecção, aprendizagem e adaptabilidade, que levam a um ambiente de trabalho inovador e criativo.

Não custa repetir: transparência, inspeção e adaptação. Os três pilares do Scrum.

Esse ciclo virtuoso é a chave para a inovação. A inspeção e adaptação frequentes do Scrum levam o seu produto sempre aonde ele deve estar, agora, neste momento. E não conforme foi planejado um ano atrás com a diretoria em um lindo restaurante estrangeiro com todo mundo em seus belos ternos sob medida.

Ninguém sabe o amanhã, e embora seja extremamente válido (e aconselhável) definir as estratégias e médio e longo prazo, é a execução em curto prazo (aliado aos pilares do Scrum) que vão garantir a existência do projeto para TALVEZ chegar no destino desejado. Se ele ainda fizer sentido um ano depois de traçado.

A chance de revisitar o processo e ajustá-lo a cada sprint é única e dá ua vantagem muito grande ao time frente às metodologias tradicionais: a vantagem de poder errar. Mas errar rápido e aprendendo com esse erro, acertar.

Ninguém tem as respostas sobre como os softwares tem de ser desenvolvidos em todos os casos. Nem o Scrum. Mas se ele tem algo de valioso e memorável são que a inspeção e adaptação às mudanças devem ser o cerne dos projetos.

Be water, my friend!