Na última semana, tive a oportunidade de conversar com diversas pessoas e times de diferentes empresas. E alguns temas comuns vieram a tona, como problemas de motivação, qualidade de código, escolhas questionáveis de arquitetura e ciclos de entrega lentos.

Fiquei refletindo sobre esses problemas e um elemento em comum me pareceu claro entre eles: a falta de design, ou melhor, design ruim. Para discutir o que é um design bom ou ruim, vamos à uma definição:

Bom design é design que é informado por informação específica: que tipo de clima você tem, que tipo de leis de construção você tem, que tipo de comportamento social você tem e qual você gostaria de promover. Então, tudo que você faz é feito para um propósito específico. Eu acredito que bom design é cuidadoso, design ruim é descuidado (Ingels, 2015)

Como dá para notar, Bjarke Ingels não trabalha com software: ele fala sobre clima, burocracia e comportamento social. Ingels é um arquiteto, mas ele tem um bom ponto: design bom é informado e cuidadoso.

Uma transformação parcial

Na minha apresentação de introdução a Domain-Driven Design, eu começo discutindo sobre como design foi deixado de lado mesmo com a transformação Ágil que ocorreu nos últimos 16 anos. Sandro Mancuso discute em seu livro, The Software Crafstman, sobre como essa transformação foi parcial:

As transformações Ágeis focaram principalmente no processo: no empoderamento de pessoas, na redução da burocracia e do desperdício, na priorização, na visibilidade do trabalho em progresso, e na melhoria do fluxo de informação. Esses eram problemas reais e importantes que precisavam ser resolvidos (…). Entretanto, os princípios por trás do (Manifesto) Ágil foram esquecidos. Processo se tornou mais importante que excelência técnica. Excelência técnica, que é assumida em cada metodologia Ágil, é normalmente ignorada por gerentes e por coaches despreparados. (Mancuso, 2014)

Essa transformação parcial se manifesta nos problemas que mencionei no início desse texto além dos proverbiais “tentamos, mas não funcionou” e “isso nunca iria funcionar aqui”. Não há como metodologias e processos que dependem de ciclos de feedbacks terem sucesso sem excelência técnica, e, portanto, sem a qualificação dos profissionais que compõe o time. E temos o seguinte (triste) fato:

Muitos projetos Ágeis estão agora, regularmente e iterativamente, produzindo código ruim. (Mancuso, 2014)

Design em toda parte

O design que se manifesta em código é fruto de uma intersecção entre o design da organização e o design do time. A questão de design, então, passa ao largo de ser um problema de um indivíduo no time.

Vale destacar que na maior parte do tempo, quando eu falo sobre desenvolvimento de software, estou falando em uma empreitada humano-tecnológica que é feita em time. A maioria dos softwares são desenvolvidos por times.

Por trás das metodologias Ágeis, do Lean/Kanban e do DevOps, sempre se encontra princípios ou objetivos para a criação de times altamente funcionais. Do Manifesto Ágil (Beck et al, 2001), temos os princípios 8 e 11, por exemplo:

  • Os processos ágeis promovem desenvolvimento sustentável. Os patrocinadores, desenvolvedores e usuários devem ser capazes de manter um ritmo constante indefinidamente
  • As melhores arquiteturas, requisitos e designs emergem de equipes auto-organizáveis

Do Lean (Liker, 2003), temos os princípios 9 e 10:

  • Cresça líderes que entendam o trabalho completamente, vivam a filosofia e a ensine aos outros
  • Desenvolva pessoas e times excepcionais que sigam a filosofia da sua empresa

E do DevOps (Debois et al, 2016), dos Princípios de Aprendizado e Experimentação Contínuos, temos:

  • Habilite uma cultura de aprendizado organizacional e uma cultura de segurança
  • Institucionalize a melhoria do trabalho diário
  • Líderes reforçam uma cultura de aprendizado

Então, a atividade de desenvolvimento profissional de software ocorre em times, dentro de organizações. E o design da organização e do time influenciam no design de código. O doutor Melvin Conway tem umas palavras sobre esse fenômeno, que ficaram tão famosas que foram promovidas ao que é, hoje, conhecida como lei de Conway.

A lei de Conway

Qualquer organização que projeta um sistema (definido amplamente) irá produzir um design ao qual sua estrutura é uma cópia da estrutura de comunicação da organização (Conway, 1968)

A lei de Conway é uma observação sociológica que pode ser observada em diferentes tipos de organização de time. O famoso time de duas pizzas (T2P)1 da Amazon, por exemplo, limita o tamanho dos times para um máximo de 5-10 pessoas. Essa restrição tem efeitos importantes (Debois et al, 2016):

  1. O time tem um claro entendimento do sistema ao qual está trabalhando
  2. Limita a taxa de crescimento do produto ou serviço sendo trabalhado
  3. Descentraliza o poder e possibilita autonomia
  4. Promove uma cultura sem medo, já que o escopo menor de trabalho limita as consequências das falhas

Da mesma forma, me parece que os Squads do Spotify (Kniberg, 2012) contribuem para alcançar esses mesmos efeitos.

A diferença é que a Amazon é uma organização com orientação ao mercado, otimizada para responder rapidamente às necessidades dos clientes e composta por times multidisciplinares em uma hierarquia plana. Já o Spotify é uma organização com orientação em matriz, que combina os elementos de organizações com orientação funcional (otimizadas para expertise, divisão de trabalho e redução de custo) e ao mercado.

O ponto mais importante que essas diferenças mostram é a escolha consciente do design da organização. Se design bom é informado, adotar uma organização de time como o T2P da Amazon ou o Squads do Spotify requer o entendimento não apenas da estrutura dos times como também das interdependências entre eles e dos impactos dessas novas dinâmicas na organização.

Esse design, feito de forma cuidadosa, ditará como o trabalho será feito e os resultados alcançados (Debois et al, 2016).

Times, indivíduos e código

O design dos times é resultado direto do design da organização. Times com orientação ao mercado são, em um extremo, totalmente responsáveis não apenas pelo desenvolvimento do software, como também pelos testes, pela segurança, implantação e por suportar seu serviço em produção. São times DevOps (Debois et al, 2016).

Já o time Scrum clássico é também multidisciplinar, composto pelo Dono do Produto (Product Owner), pelo Scrum Master e pelo Time de Desenvolvimento. No entanto, o objetivo desse time é de entregar um incremento de produto, este potencialmente lançável (Schwaber, 2013). A responsabilidade desse time é limitada ao desenvolvimento do software.

A definição da estrutura dos times vai dizer muito sobre as interações entre eles e sobre seus potenciais conflitos. Geralmente, os desenvolvedores tem muita participação nessa definição sobre como trabalhar. No entanto, parecem não ter noção da sua influência não apenas na organização como também na sociedade no geral: o mundo depende cada vez mais de software.

Desenvolvedores são, em geral, indivíduos altamente motivados e curiosos. Mas essa mesma curiosidade parece levar a uma mentalidade extremamente orientada à tecnologia. Não é incomum ver times tentando resolver problemas com tecnologia ao invés de fazer design cuidadoso. O modelo do software vira então uma Grande Bola de Lama (Foote; Yoder, 1999), com pouco a quase nenhum conhecimento do negócio codificado de forma expressiva.

É aqui que nós, como indivíduos, temos o dever de agirmos como profissionais. Ser profissional exige disciplina. As organizações ainda não nos entendem. O Uncle Bob (Martin, 2016) dá uma boa explicação sobre como ser profissional:

Em particular, o negócio não entende as nossas disciplinas (…), não entende Programação em Par, Desenvolvimento Guiado por Testes, Refatoração, Design Simples. Essas são disciplinas técnicas e não estão no expertise do negócio.

E não deveriam estar. Elas pertencem a nós, é parte do nosso expertise técnico. Então o negócio não pode aprová-las ou endossá-las. Você não pode chegar no negócio e dizer “Tudo bem se eu fizer testes?”. (…) Quando você faz isso, você está tentando se livrar do risco, você não está querendo tomar o risco, você o joga no negócio, que não pode avaliá-lo e tomá-lo. (…)

E o risco, francamente, é nosso. Nós somos os donos do risco. Nós que sabemos como as coisas precisam ser testadas, refatoradas, como que o software precisa ser feito e nós temos que tomar o risco como parte da nossa operação normal. Como profissionais. E é isso que profissionais fazem: eles tomam o risco no que eles sabem que deve ser feito.

Outra responsabilidade profissional que temos é o de entender o domínio do negócio em que trabalhamos:

(…) se os programadores não estão interessados no domínio, eles aprendem apenas o que a aplicação deve fazer, não os princípios por trás dela. Software útil pode ser desenvolvido dessa maneira, mas o projeto nunca chegará em um ponto onde novas funcionalidades poderosas surgirão como desdobramento de funcionalidades existentes (Evans, 2003)

Tanto o Uncle Bob quanto o Eric Evans expõe implicações econômicas profundas. Nosso profissionalismo pode ser a diferença entre o negócio realizar o retorno do investimento feito no desenvolvimento do software ou, ter software que é apenas custo.

Não podemos fugir das nossas responsabilidades: temos o dever, como profissionais, como indivíduos, de nunca parar de aprender e de melhorar em nosso ofício.

Design informado e cuidadoso

Uma aproximação de desenvolvimento de software que suporta design informado e cuidadoso é o Domain-Driven Design (DDD). O DDD é uma forma de desenvolver software que tem, como objetivo, implementar o melhor design de software baseado em modelos que refletem as competências da organização. DDD ajuda a desenvolver software que dá vantagem competitiva ao negócio, porque força a organização a entender no que ela deve se distinguir (Vernon, 2016).

Pra suportar as atividades de design na intersecção organização/time, o DDD possui ferramentas de design estratégico e tático. O design estratégico tem a ver com dividir o trabalho e encontrar o que é estrategicamente importante para o negócio. DDD é, resumidamente, sobre modelar uma Linguagem Ubíqua em um Contexto Delimitado (Vernon, 2016).

Essas ferramentas são os pilares do DDD. Times que adotam DDD conversam em uma Linguagem Ubíqua, que, além de falada tanto por desenvolvedores quanto por especialistas de domínio, é implementada no código do software (por isso é ubíqua). Para limitar e definir claramente o vocabulário dessa Linguagem, são usados os Contextos, que são barreiras semânticas. Dentro de um Contexto, cada termo tem um significado específico, entendido por todos os membros do time.

Os Contextos são o reconhecimento que o domínio do negócio é, além de grande e complexo, melhor gerenciado ao dividí-lo. A recomendação de manifestar cada Contexto como um time, um repositório e um banco de dados próprios (Vernon, 2016) alinha perfeitamente com a organização em times de produto, além de ser um caminho natural para uma arquitetura em Microserviços (Newman, 2014).

O modelo resultante do design estratégico é informado: o time adquiriu as informações do negócio para dividir o domínio em sub-domínios, encontrando seus Contextos e modelando a Linguagem Ubíqua.

Já o design tático é um catálogo de padrões que ajudam a implementar o modelo em código, com o objetivo de tornar o software um reflexo explícito do modelo. Se meu código é uma representação explícita do modelo que foi criado pelo esforço conjunto de desenvolvedores e especialistas de domínio, esse código documenta e centraliza o conhecimento do negócio. É design cuidadoso.

Melhoria contínua na raiz do design

Organizações e relações entre times são sistemas complexos. Desenvolvimento de software é uma atividade difícil. Dado esses desafios, traçarmos estratégias para executar essas atividades de design (organizacional, time e código) afim de transformarmos a organização.

Porém, uma transformação organizacional depende de pessoas. São elas que aprendem e mudam a organização (Soares, 2017). Em organizações de software, é muito comum haver uma sobrecarga de atividades transformacionais, com a adoção de múltiplos processos ocorrendo em paralelo.

Além de aumentar o risco de falhas na adoção e entendimento dos processos, essa sobrecarga causa problemas de moral no time. A cada nova falha, o time se sente mais desmotivado, por que, mesmo com suas melhores intenções e esforços, o novo processo não funcionou. Uma espessa névoa de indiferença e ressentimento toma conta do lugar.

Definir a criação de times totalmente DevOps como objetivo é um ótimo ponto de partida. DevOps, como conjunto de práticas, tem entre seus princípios a visualização do fluxo. A mentalidade Lean e o Método Kanban estão integrados no DevOps (Debois et al, 2016) e como já citado, a criação de uma cultura de melhoria contínua.

O Método Kanban é projetado para minimizar o impacto inicial das mudanças e para reduzir a resistência de adoção de mudança. Adotar o Kanban deve mudar a cultura da sua organização e ajudá-la a amadurecer. Se a adoção for feita corretamente, a organização irá se transformar em uma que adota mudança rapidamente e se torna boa em implementar mudanças e melhorias de processos. (Anderson, 2010)

Então não importa a estratégia, minimizar o impacto inicial e reduzir a resistência às mudanças é primordial para a implantação de uma cultura de melhoria contínua.

Design é inevitável

Questionamentos se design é necessário ou acessível perdem o ponto: design é inevitável. A alternativa para bom design é design ruim, e não a ausência de design. Douglas Martin. (Vernon, 2016)

Sendo design inevitável, cabe a nós definir o design da organização, dos times e do código. Na ausência de alternativa, melhor fazer design informado e cuidadoso. O que estamos esperando para começar?

Referências


  1. A ideia é que o time deve ter um tamanho que possibilite ser alimentado por duas pizzas. Acredito, pelo menos por enquanto, que não é um plano da Amazon de aumentar a procura por pizzas ao abrir o apetite de leitores desavisados.