08 novembro 2008

O valor da simplicidade


Continuando a tradução...
Dois dos maiores gritos de guerra em XP são os slogans “faça a coisa mais simples que poderia possivelmente funcionar”, e “você não vai precisar disso” (conhecido como YAGNI - “You Aren´t Going to Need It”). Ambos são manifestações da prática XP chamada Design Simples.

O modo como YAGNI é normalmente descrita diz que você não deveria adicionar nenhum código hoje que será usado apenas por funcionalidades que serão necessárias amanhã. Diante disso, parece simples. O problema surge com coisas como frameworks, componentes reusáveis, e design flexível. Essas coisas são complicadas de construir. Você paga um custo extra antecipado para construi-los, na esperança de receber de volta mais tarde. Essa idéia de construir flexibilidade antecipadamente é vista como uma parte chave do design de software efetivo.

Todavia, o conselho de XP é que você não construa componentes e frameworks flexíveis para o primeiro caso que necessite deles. Deixe essas estruturas crescerem à medida em que são necessárias. Se preciso hoje de uma classe Dinheiro que trate adição, mas não multiplicação, então eu construo apenas a adição na classe Dinheiro. Mesmo que eu tenha certeza de que vou precisar da multiplicação na iteração seguinte, saiba como fazê-la facilmente, e pense que será realmente rápido fazer, ainda assim vou deixá-la para a próxima iteração.

Uma razão para isso é econômica. Se eu tenho que fazer qualquer trabalho que somente será necessário amanhã, significa que eu perco o esforço das funcionalidades que precisam ser feitas nessa iteração. O plano da release diz o que precisa ser feito para essa iteração, trabalhar em outras coisas para o futuro é contrário ao acordo que os desenvolvedores tem com o cliente. Existe um risco de que as histórias dessa iteração possam não ser concluídas. Mesmo que as histórias dessa iteração não estejam em risco, é o cliente quem deve decidir qual trabalho extra deveria ser feito - e isso pode não incluir a multiplicação.



Esse des-incentivo é composto pela chance de que podemos não ter entendido a funcionalidade direito. Por mais certo que possamos estar sobre como essa funcionalidade deveria funcionar, podemos ainda assim estar errados - especialmente já que não temos os requisitos detalhados ainda. Trabalhar na solução errada cedo é um desperdício ainda maior do que trabalhar na solução certa cedo. E os XPerts normalmente acreditam que somos muito mais propensos a errar do que acertar (e eu concordo com esse sentimento.)

A segunda razão para o design simples é que um design complexo é mais difícil de entender que um design simples. Portanto qualquer modificação do sistema é feita com mais dificuldade pela complexidade adicionada. Isso adiciona um custo durante o período desde que o design mais complicado foi adicionado até quando ele foi necessário.

Agora, esse conselho parece totalmente sem sentido para um monte de gente, e eles estão certos por pensarem assim. Certos, dado que você imagine o mundo usual do desenvolvimento onde as práticas habilitadoras de XP não estão presentes. Entretanto quando, o balanço entre o design planejado e evolutivo é obtido, então YAGNI se torna uma boa prática (e somente então).

Portanto, para sumarizar. Você não quer desperdiçar esforço adicionando nova capacidade que não será usada até uma iteração futura. E mesmo se o custo for zero, você ainda assim não quer adiciona-la porque ela aumenta o custo de modificação, mesmo que não custe nada para colocá-la. Entretanto, você apenas pode se comportar assim quando você está usando XP, ou uma técnica similar que reduza o custo das mudanças.


01 novembro 2008

As práticas habilitadoras de XP

Continuando a série... ( a propósito, há alguma tradução melhor para "enabling practices" ? )

XP é controversa em muitos sentidos, mas uma das bandeiras vermelhas em XP é que ela advoga design evolutivo ao invés de design planejado. Como sabemos, design evolucitivo não pode funcionar devido ás decisões ad hoc e à entropia de software.

Na raiz do entendimento desse argumento está a curva de mudanças do software. A curva de mudanças diz que, à medida que o projeto decorre, torna-se exponencialmente mais caro fazer mudanças. A curva de mudanças é normalmente expressa em termos de fases "uma mudança feita durante a análise por $1 custaria milhares para consertar em produção". É irônico que a maioria dos projetos ainda trabalhe em um processo ad-hoc que não possui uma fase de análise, mas a exponenciação ainda está lá. A curva de mudanças exponencial significa que o design evolutivo não pode funcionar. Também indica o motivo pelo qual o design planejado precisa ser feito cuidadosamente, porque qualquer erro no design se depara com a mesma exponenciação.


A premissa fundamental a respeito de XP é que é possível nivelar a curva o suficiente para fazer o design evolutivo funcionar. Esse nivelamento é tanto habilitado por XP como explorado por XP. Isso é parte do acoplamento existente entre as práticas de XP: especificamente não se pode fazer aquelas partes de XP que exploram a curva nivelada sem fazer aquelas que habilitam o nivelamento. Essa é uma fonte comum de controvérsia sobre XP. Muitas pessoas criticam a exploração sem entender a habilitação. Frequentemente as críticas surgem da própria experiência dos críticos onde não usaram as práticas habilitadoras que permitam que as praticas exploradoras funcionem. O resultado é que eles se queimam e quando vêem XP eles lembram das chamas.

Existem muitas partes para as práticas habilitadoras. No centro estão as práticas de Testes e Integração Contínua. Sem a segurança provida pelos testes, o resto de XP seria impossível. Integração contínua é necessária para manter a equipe em sincronia, de modo que se possa fazer mudanças sem aborrecimentos para integra-la com os outros. Juntas essas práticas podem ter um grande efeito na curva de mudanças. Me recordei disso mais uma vez aqui na ThoghtWorks. Introduzir testes e integração contínua trouxe melhoras significativas no esforço de desenvolvimento. Certamente o suficiente para questionar a assertiva de XP de que você precisa de todas as práticas para obter uma grande melhoria.



Refactoring possui um efeito similar. Pessoas que refatoram seu código da forma disciplinada sugerida pela XP vêem uma diferença significativa em sua efetividade compara a fazer reestruturações de forma mais frouxa e ad hoc. Essa foi minha experiência quando Kent me ensinou a refatorar corretamente. Afinal, apenas uma mudança forte me motivaria a escrever um livro completo sobre isso.

Jim Highsmith, em seu excelente resumo sobre XP, usa a analogia de um conjunto de escalas. Em uma bandeja está o design planejado, na outra refactoring. Em abordagens mais tradicionais o design planejado domina porque a premissa é que não se pode mudar de idéias depois. À medida em que o custo das mudanças diminui, você passa a poder fazer a maioria do seu design mais tarde como refactoring. O design planejado não some completamente, mas agora existe uma balança de duas abordagens de design para se trabalhar. Pra mim, é como se antes do refactoring eu estivesse fazendo todo o meu design com uma mão só.


Essas práticas habilitadoras de integração contínua, testes e refactoring provêem um novo ambiente que torna plausivel o design evolutivo. Entretanto, uma coisa que ainda não conseguimos visualizar é para onde a balança deve apontar. Tenho certeza de que, tirando a impressão de quem está de fora, XP não é apenas testa, codifica, e refatora. Existe espaco para projetar antes da codificação. Parte dele se faz antes de se existir qualquer código, a maioria ocorre nas iterações antes de codificar uma tarefa em particular. Mas existe uma nova balança entre o design up-front e o refactoring.