3 pontos por GN⁺ 2024-12-16 | 1 comentários | Compartilhar no WhatsApp
  • No desenvolvimento de software, é difícil sair diretamente de um documento de design para um PR limpo, e como as premissas costumam se abalar durante a codificação real, explorar o design com código descartável pode ser mais rápido
  • Propõe-se um fluxo em que protótipos ou provas de conceito são criados em um draft PR que não será mesclado, recebe-se revisão cedo para alinhar a direção da abordagem e depois isso fica registrado como histórico das ideias de design
  • A premissa desse método é a maturidade organizacional para descartar sem apego a primeira solução, e a postura de implementar o mesmo problema de 2 a 3 maneiras diferentes é vista como um sinal de senioridade
  • O PR se torna uma documentação fácil de descobrir que registra a intenção de implementação e as discussões de um determinado momento, enquanto documentos de design, se não forem atualizados com frequência, tendem a virar uma “undead documentation” desalinhada da realidade
  • Documentos de design ainda continuam necessários para organizar feedback de vários stakeholders, servir como documento North Star de longo prazo, lidar com ideias iniciais ainda difíceis de codificar ou em organizações onde há risco de o protótipo ser implantado como está

Explorando o design com Throwaway PR

  • O fluxo ideal de desenvolvimento se parece com escrever um documento de design, mesclar pequenos PRs em sequência para lançar a funcionalidade e manter o histórico do Git limpo
  • Na prática, muitas vezes é só depois de começar a codificar que as premissas do documento de design vacilam, e que se torna necessário reavaliar em que ordem fazer o lançamento
  • Por isso, pode ser mais eficiente primeiro criar um grande experimento em código e, com base no resultado, montar o plano real
  • Procedimento proposto

    • Implementar um protótipo ou prova de conceito em um draft PR sem intenção de mesclá-lo
    • Receber cedo o olhar de outras pessoas sobre grandes refatorações ou abordagens de funcionalidade para obter alinhamento de direção
    • Documentar a abordagem dentro do draft PR para que ele permaneça como registro histórico das ideias de design
    • Estar preparado para descartar todo o draft PR o mais cedo possível
    • A partir do draft PR, extrair gradualmente os PRs realmente prontos para implantação, separando-os em PRs limpos de entrega ao longo de cerca de uma semana
    • Ao dividir cada PR em etapas, preencher gradualmente as lacunas de testes e robustez
  • Condições que esse método exige da equipe

    • A condição mais importante é a maturidade para conseguir descartar a própria primeira ideia codificada
    • A tranquilidade para codificar o mesmo problema de 2 a 3 maneiras diferentes pode ser vista como um importante sinal de senioridade
    • Entregar valor não está na quantidade de linhas de código que entraram em produção, mas no conhecimento adquirido pela organização
    • Se houver alinhamento cedo nas partes importantes, a prototipagem depois não termina como simples desperdício
    • É preciso ter familiaridade suficiente para conectar rapidamente as partes centrais da base de código, e espera-se esse nível de conforto de pessoas mais sêniores
    • Esse método pode ser executado não só individualmente, mas também em nível de equipe

Documentação em PRs e o papel real dos documentos de design

  • O PR é uma das formas de documentação úteis para desenvolvedores
    • É um dos primeiros lugares a procurar quando se quer entender por que uma determinada implementação ficou daquele jeito
    • Ele não afirma refletir o estado atual, mas permanece como um artefato histórico que registra o estado de um determinado momento
  • Documentos de design, se não forem mantidos atualizados com frequência, tendem facilmente a se tornar uma undead documentation que reflete uma realidade antiga
  • Protótipos combinam com a ideia de “mostrar em vez de falar”, e ao promover mudanças o código pode ser mais eficaz do que documentos
  • No entanto, em organizações sem disciplina, há o risco de o protótipo ser recebido não como uma “pergunta”, mas como a “resposta”
    • A intenção original está mais próxima de “devemos fazer isto ou fazer outra coisa?”
    • Se a organização interpretar isso como “devemos fazer isto”, surge o problema
  • Casos em que documentos de design ainda fazem sentido

    • São úteis quando é preciso organizar e guardar feedback de vários stakeholders, gestores e equipes externas
    • Só com o GitHub pode ser difícil conduzir esse tipo de colaboração
    • Se a ideia for conceitual e de longo prazo demais para codificar de imediato, algum tipo de documento North Star pode ajudar
    • Também são úteis quando expressar a ideia por escrito é mais eficiente do que um primeiro rascunho de código, ou quando o onboarding na base de código ainda não é suficiente e se quer deixar um rascunho para feedback
    • Se a empresa empurra direto para produção sem a disciplina de descartar a primeira solução, o protótipo pode se cristalizar como a própria “solução”
    • Em organizações onde pessoas júnior têm dificuldade para contestar a implementação da ideia de um desenvolvedor sênior, pode ser necessário um artefato mais suave para permitir questionamentos com mais segurança
  • Casos em que documentos de design são usados por maus motivos

    • Podem virar um meio de atrasar o processo em equipes com pouca disciplina ou pouca experiência
    • Mesmo quando usados com objetivo de documentação, normalmente envelhecem rápido
    • É difícil responder antecipadamente a todas as perguntas de design, e os problemas reais muitas vezes só aparecem depois que o código é escrito
    • Se a equipe puder ter disciplina suficiente, aprender hackeando pode ser mais eficiente do que “fazer design”

1 comentários

 
GN⁺ 2024-12-16
Opiniões do Hacker News
  • Isso se chama prototipagem; é uma parte valiosa do processo de design, e algumas pessoas também chamam de “pathfinding”
    Tudo isso serve como entrada para o design, mas um design de tamanho adequado ainda é necessário. Caso contrário, você está apenas construindo do jeito que der na hora. É preciso definir qual é o problema que se está tentando resolver e qual é a solução. Às vezes, um documento de 1 página sem revisão formal basta; às vezes, é necessário um documento de várias páginas com semanas de revisão e ciclos de feedback
    Não se esqueça: “algumas semanas de programação podem economizar algumas horas de planejamento” ;)

    • O design precisa necessariamente ser compreendido, mas isso não significa que precise ser um documento ou um artefato permanente. Se for necessário um registro permanente, um PR também pode ser um meio perfeitamente bom
      Na verdade, o oposto foi muito mais frequentemente verdadeiro. As pessoas planejam e planejam, até que o plano deixa de ser apenas inútil e passa a prejudicar ativamente a produtividade
    • Isso está mais para uma falsa dicotomia. Design e protótipo são ambos necessários
      Algumas semanas de programação podem economizar algumas horas de planejamento, mas algumas semanas de planejamento também podem ser desperdiçadas. No papel, é fácil escrever coisas que não fazem sentido ou são impossíveis. Por exemplo, algo como “pintar uma frota de unicórnios em uma cor meio triste”
      Idealmente, design e protótipo deveriam evoluir juntos, avançando em espiral como a dupla hélice do DNA, com a iteração de um lado impulsionando a próxima iteração do outro. A grande vantagem de pender para o lado de construir protótipos é que, ao fim de uma rodada, sobra um software que realmente faz alguma coisa. Ao fim de uma rodada de design, na prática não sobra muita coisa
    • Não há motivo para não fazer os dois. Acho melhor escrever primeiro a teoria, mostrar com um protótipo se aquilo funciona ou não, e então escrever o documento de design de verdade
      E, mesmo até a fase de implementação, a descartabilidade do código deve continuar sendo priorizada. Quanto mais fácil for apagar, melhor
    • Exato: prototipagem e pathfinding são totalmente aceitáveis e, na maioria das vezes, necessários
      Mas engenharia de software sem documentos de design ou qualquer tipo de especificação, por mais concisos que sejam, não é engenharia; está mais para construir uma cabana na árvore
      Quanto maiores e mais importantes forem os projetos, mais rapidamente os problemas e a dívida técnica começarão a aparecer
    • “Algumas semanas de planejamento também podem economizar algumas horas de programação” :)
  • Escrever é realmente útil para explorar o espaço do problema
    Muitas vezes achei que entendia bem o problema, mas, quando comecei a colocá-lo por escrito, surgiram perguntas novas e importantes. Normalmente, essas coisas ficam mais visíveis de uma perspectiva mais abstrata ou podem não aparecer nos primeiros marcos de lançamento
    Isso me lembra um mentor que tive no início da carreira. Ele havia projetado, depois do fato, uma configuração active/active para um gateway de pagamentos e, ao abrir o Lucidchart, disse: “este diagrama representa 6 meses da minha vida”
    Nem sempre é necessário ou útil, mas, quando é necessário, alguns dias de planejamento podem economizar semanas de programação

    • Tive um chefe com formação em matemática que, como os matemáticos da TV ou do cinema, desenhava no quadro branco o fluxo do começo ao fim
      Ele conseguia prever com muita antecedência onde surgiriam problemas, então os projetos sempre corriam de forma tranquila. Quando aparecia um problema ou uma incerteza, ele modelava apenas aquela parte e depois voltava ao quadro branco para continuar
      Como analogia, era como planejar uma viagem de carro com um mapa. Hoje em dia, documentos de design marcam apenas a estrada e já saem dirigindo; já o mapa no quadro branco desse chefe “planejava demais”: onde abastecer, horários de funcionamento das atrações turísticas, documentos para cruzar fronteiras, orçamento total, kit de emergência, Plano A e Plano B
      Era extremamente tedioso, mas muito melhor do que código descartável. Agora, não planejar em excesso me parece preguiça
      Claro que a frase “todo mundo tem um plano até levar um soco” é verdadeira, mas isso se aplica a guerra, política e negociações, não a programação
    • Concordo que escrever é útil. Mas acho que programar tem o mesmo efeito. Pela minha experiência, na exploração, os dois precisam andar juntos
      No fim, um bom PR também contém bastante texto e produz o mesmo efeito. Acho que um PR em rascunho bem documentado é melhor do que uma proposta de design pura. Isso porque, se você só escreve, acaba esquecendo restrições importantes que só vêm à mente quando estão no código
    • “Escrever é a forma que a natureza encontrou de mostrar como seus pensamentos são frágeis”
      -- Dick Guindon
  • O maior problema que tive com documentos de design é que ninguém os lê. Mesmo quando o empregador exige
    O maior problema que tive com prototipagem é que as pessoas olham para aquilo como “código de lançamento” e forçam você a usá-lo como código final
    Por isso, uma abordagem mista funcionou melhor. Gasto bastante tempo com planejamento e documentação, mas basicamente faço isso para mim mesmo, e escrevo código de protótipo com qualidade de lançamento para que ele possa ser usado no produto final mais tarde, se for apropriado

    • O motivo pelo qual as pessoas não querem ler um documento de design médio é que o engenheiro de software médio não tem habilidade de escrita suficiente para expressar conceitos de forma clara e concisa
      O documento de design vira um amontoado de anotações brutas que ninguém além do autor entende direito, e as pessoas passam a temer ler esse tipo de anotação
      Mas, se você disser ao autor do documento de design que aquilo é como um trabalho final da escola que será avaliado, a escrita pode melhorar bastante depois de algumas reescritas. O sintoma é o mesmo da prototipagem. As pessoas escrevem documentos de design com qualidade de rascunho e esperam que, por mágica, eles se transformem em bons textos adequados a um público mais amplo. Assim como o código de protótipo precisa ser refatorado algumas vezes, documentos de design também precisam de algumas rodadas de edição
  • Para evitar a renovação do contrato, era preciso criar e lançar algo até o prazo final, e esse contrato custaria milhões de dólares. Mas ficou claro que, com os recursos e a abordagem planejados, não seria possível terminar a tempo
    Então recebi aprovação para criar rapidamente uma versão temporária, parcial e não ideal, e graças a isso conseguimos decolar dentro do prazo
    Isso nos permitiu voar por um tempo enquanto outras pessoas concluíam a versão permanente e correta daquela parte da asa
    Na prática, durante o voo também descobrimos requisitos que tinham ficado de fora do projeto original. Isso atrasou o lançamento em produção da versão correta, mas consegui acrescentá-los rapidamente à minha versão hackeada e manter o voo
    Minha versão hackeada também serve como ferramenta de suporte à produção. Quando a versão permanente tem um bug e precisa parar, ela também vira uma rota alternativa. É um hack parcial e incompleto, mas tem vantagens
    Algumas pessoas reclamaram porque a linguagem usada era menos comum. Mas é preciso lembrar que, com os recursos e a abordagem existentes, nem teríamos conseguido decolar
    Para cumprir o prazo, teria sido necessário ter mais desenvolvedores, ou desenvolvedores mais rápidos, na linguagem preferida. Se alguém da equipe atual, inclusive eu, tivesse disponibilidade e capacidade de ser tão produtivo na linguagem preferida quanto eu fui com meu hack em uma linguagem menos popular, essa pessoa teria sido designada para criar a solução permanente a tempo. Essa opção não existia
    De todo modo, se já existe uma ferramenta de suporte à produção, ela também pode ser um lugar onde funcionalidades protótipo fiquem por um tempo

    • Que linguagem era?
  • Mais um texto de opinião, sem dados e nem sequer exemplos concretos
    Sei que todo engenheiro de software tem opiniões fortes, mas este é um argumento fraco. Se você acha que seu trabalho é escrever muito código para ver o que está certo, em breve será substituído pelo GPT. Ele consegue fazer isso mais rápido e mais barato. A parte difícil sempre é chegar a um consenso sobre o que deve ser construído, e você não consegue escapar desse problema codificando

    • Concordo muito. Não sei se “documento de design” é o termo certo; eu chamo de análise técnica, mas escrever um documento que conecte as necessidades de negócio e de produto aos detalhes de implementação é muito útil para fazer com que todos tenham o mesmo entendimento sobre requisitos e entregáveis
      Se os requisitos estiverem claros e também estiver claro para todos o que vou entregar, isso não é necessário. Dá para ir direto para a prototipagem. Mas, em projetos sérios, esse caso é raro. Sempre há incógnitas desconhecidas que precisam ser extraídas dos stakeholders, e a análise técnica é uma boa forma de fazer isso
    • Esse é exatamente o meu ponto. Acho que “mostrar, não falar” gera um consenso melhor
      Há limites para o que se consegue com retângulos e linhas pontilhadas. Quando você está distante do código real, esquece as restrições reais. As coisas que de fato desaceleram o trabalho não aparecem no Google Docs. Pela minha experiência, apontar para um PR em rascunho e dizer “é isto que estou pensando” leva mais longe
      E sim, é 100% opinião. É um blog pessoal, não um artigo revisado por pares :) Não tem problema estar errado
    • Código descartável é melhor do que documentos de design porque é um exemplo concreto
      Se não houver algo tangível como código para ancorar a conversa, discussões sobre designs abstratos tendem a virar debates sem conclusão do tipo “a corda da minha imaginação é mais longa do que a corda da sua imaginação”
    • É mais provável que alguém com essa crença avance muito mais rápido com LLMs do que que uma LLM substitua esse trabalho por completo
    • Às vezes, os “dados” desse tipo de texto podem ser décadas de experiência pessoal
  • Na minha experiência, o feedback sobre código e o feedback sobre design são de tipos enormemente diferentes
    Um documento de design incentiva perguntas de “por quê”, que fazem todos pensarem no espaço do problema. Por exemplo, permite comentários como “por que você está propondo um servidor web em Rust se a empresa ainda não tem ninguém proficiente em Rust?”
    Esse tipo de pergunta sutil fica muito mais difícil de levantar depois que o protótipo começa a funcionar. É fácil virar “por que a experiência da equipe importa? Está rodando tão bem! Se não bloquearem, dá para lapidar o protótipo e colocá-lo em produção em uma semana!”

    • Isso não é necessariamente ruim. Muitas perguntas de “por quê” são, na verdade, discussões de bicicletário improdutivas
      Especialmente quando se revisa apenas o design, e não código funcionando
  • Imaginamos que o trabalho de software siga um fluxo limpo e organizado
    Escrevemos um documento de design, criamos pequenas mudanças incrementais para lançar a funcionalidade em um PR, e o histórico do Git fica limpo e ordenado. Parece um avanço constante
    Quem imagina isso? Professores que dão aulas de engenharia de software?
    Isso me lembra pessoas que acham que prosa, ensaios, histórias, romances etc. são escritos fazendo primeiro um esboço e depois “preenchendo” esse esboço com prosa. Como se, durante o processo, não houvesse nenhuma descoberta que exigisse reescrever ou reorganizar o documento. Ninguém escreve assim. O primeiro rascunho é sempre péssimo, e quase todo bom texto é resultado de grandes revisões
    Escrever código é muito mais parecido com escrever texto do que com construir uma casa ou uma ponte

    • Sempre vejo muito valor em depurar código recém-escrito
      Seguir a nova lógica linha por linha e observar variáveis e memória ajuda muito a melhorar o código. Descubro coisas como “ah, esta variável local não é necessária”, “aqui eu deveria adicionar uma variável temporária para facilitar a depuração”, “se a coleção iterada estiver vazia, este código fica estranho”
      Não importa minha idade nem quanto código eu já tenha escrito: ao depurar código recém-escrito, sempre descubro algo novo. Dá para comparar com um escritor relendo um rascunho depois de escrevê-lo, ou lendo-o em voz alta para si mesmo ou para outra pessoa
  • Gosto muito desse processo de registrar decisões de design em uma thread de comentários em andamento, em vez de tentar formalizá-las em um único documento
    Eu uso issues do GitHub assim, mas funcionalmente é o mesmo que usar um PR. Um PR é, na prática, uma issue do GitHub com um branch de código anexado
    Escrevi mais sobre meu método aqui: https://simonwillison.net/2022/Jan/12/how-i-build-a-feature/...

    • Então como você comunica o consenso mais recente sobre cada issue? Por exemplo, para uma pessoa recém-chegada que não quer vasculhar meses de comunicação, ou para um membro da equipe que acompanhou a thread o tempo todo, mas não consegue encontrar facilmente onde a equipe chegou a um consenso sobre um ponto específico?
      Em outras palavras, como você resume essa thread em uma documentação final?
  • Não acho que os dois sejam mutuamente exclusivos
    Um documento de design é um conceito mais amplo, e o objetivo é comunicação
    Às vezes é preciso transmitir de formas que não sejam código. Diagramas, imagens, texto etc. são necessários

    • Concordo
      Para alguém que não é o autor ou não está muito familiarizado com o código, é muito difícil entender as mudanças de relance. São necessárias explicações e documentação de alto nível para que o leitor crie rapidamente o modelo mental correto para entender a mudança dentro do contexto
      Se você consegue olhar para um diff de 1000 linhas e dizer exatamente o que ele faz e, mais importante, quais impactos terá a montante e a jusante, então ou está mentindo, ou trabalha em um ambiente tão perfeitamente fechado e verificável que eu realmente teria inveja
  • Documentos de design ajudam a reduzir o número de protótipos para 2 ou 3 entre as opções possíveis. São especialmente úteis ao explorar a adição de algo totalmente novo
    Sinto que mostrar é melhor do que falar, mas alguém recém-chegado entende mais facilmente por meio de um documento de design do que pelo código