quinta-feira, 14 de abril de 2011

Complexidade inerente

Outro dia eu aprendi o termo physics envy - inveja da física - o desejo de se poder reduzir qualquer problema a três leis fundamentais. Me identifiquei imediatamente com isso. Toda vez que me deparo com um programa complicado eu me sinto incomodado e quero achar uma solução mais simples do que aquela.

Às vezes essa solução não existe. O domínio do problema em si pode ser complexo e resistir a todas as tentativas de simplificação. Um bom exemplo é o corpo humano. Faltam décadas, talvez séculos, para que a medicina consiga entender razoavelmente bem como funciona um ser humano. O número de variáveis envolvidas e de interdependências entre elas é descomunal.

Como a medicina lida, hoje, com essa complexidade? Ignorando a complexidade e encontrando variáveis com grande influência sobre o objetivo buscado. Por exemplo, vamos supor que um médico queira reduzir a chance de seus pacientes sofrerem de doenças cardiovasculares. A verdade é que sabe-se muito pouco sobre essas doenças: por que algumas pessoas as tem e outras não, quando elas acontecem, o que as causa. É uma combinação complexa de genética, estilo de vida e psicologia. Ao invés de desistir frente à complexidade, o jeito é procurar variáveis significativas. Por exemplo, percebe-se que a taxa de colesterol parece ter uma relação forte com a incidência dessas doenças. Portanto, uma forma de atacar o problema é fazendo diminuir essa taxa. Não entendemos bem se fazer essa redução artificialmente impacta outras variáveis importantes, mas parece que fazê-lo traz um resultado positivo, então isso é feito. A complexidade do problema é reduzida a poucas variáveis. Ele não é resolvido - afinal de contas, as pessoas continuam tendo doenças cardiovasculares - mas ele é atenuado.

O que isso tem a ver com software? Tudo. Muitas vezes temos de desenvolver sistemas para resolver problemas em domínios que, como o corpo humano, parecem inerentemente complexos. Outras vezes essa complexidade chega de fininho na forma de problemas cuja solução começou simples e elegante, mas com o tempo os requisitos mudam e aparecem os remendos daqui e dali. Mesmo que feitos com todo o cuidado e critério, eles aumentam a complexidade do sistema. Um dia essa complexidade fica tão imensa que ninguém mais consegue entender bem a solução.

O que fazer para reduzir a complexidade dos sistemas? Bom, de modo geral, uma solução ótima para um problema é tão complexa quanto o problema. No entanto, o segredo é fazer como a medicina: procurar um conjunto pequeno de variáveis que possa levar a uma solução sub-ótima, porém muito mais simples. De modo geral, acrescentar variáveis aumenta a complexidade da solução linearmente, mas melhora a qualidade da solução apenas logaritmicamente.


O importante, então, é encontrar o menor conjunto de variáveis que juntas darão um resultado aceitável. Em um sistema que evoluiu e sofreu degradação, isso envolve dar um passo atrás e pensar novamente em qual é o problema que o sistema tenta resolver. Pode ser que variáveis que não eram importantes quando o sistema foi concebido agora sejam, e que algumas das variáveis originais tenham perdido a importância.

Assim, quando você sentir que seu sistema está ficando complicado demais, pare um pouco e pense: qual é o preço de simplificarmos o problema? Estamos dispostos a paga-lo?

Eu tenho inveja dos físicos e pago qualquer preço pra simplificar minha vida.

2 comentários:

  1. seria bem legal bater esse gráfico com dados empíricos do mundo da computação ;-)

    ResponderExcluir
  2. Seria super legal, mas na verdade eu nem sei como medir isso. Alguma sugestão?

    ResponderExcluir