Artigo original em: https://www.sbc.org.br/horizontes/doku.php?id=v02n03:16
Por que é difícil desenvolver bom software?
Procurando saber o que ajuda e o que atrapalha
Muitos artigos, teses e dissertações começam com um comentário de que muito software não é confiável, ou então que seu desenvolvimento foi muito mais caro do que o esperado. Segue-se uma proposta para a melhoria desse panorama. A pergunta é se essa proposta realmente contribui para uma melhoria. Neste pequeno artigo procuro identificar algumas das causas que contribuem ou que atrapalham o desenvolvimento de software fidedigno, isto é, de software do qual podemos justificavelmente depender. O modelo agrega as causas em seis eixos, a saber: processos, instrumentos, pessoal, especificação, controle da qualidade e medição. O modelo tem por finalidade suscitar discussões, mas não apresentar soluções. Muito pelo contrário, procura apresentar dúvidas, além de ser incompleto.
Motivação
Por que é difícil desenvolver software fidedigno? Por que surgem com uma enorme frequência novas linguagens, novas metodologias, ou novas abordagens? Por que propor novas poções mágicas para enfrentar esse velho problema que nos aflige desde que os computadores surgiram lá nos meados do século XX? Segundo Juristo e Moreno (2001) menos de 20% das asserções feitas em artigos, teses e livros são comprovadas experimentalmente por seus autores[1]. Outros autores, por exemplo, Robert Glass (2003), fazem comentários similares[2].
Que tal procurar identificar as causas? Afinal, uma vez que se aprendeu a programar, as coisas parecem ser tão fáceis. Volta e meia escuta-se ou lê-se algum comentário de que um garoto de menos de 18 anos desenvolve software e consegue com isso ganhar mais do que se tocasse em uma banda de rock.
Que tal procurar identificar as causas? Afinal, uma vez que se aprendeu a programar, as coisas parecem ser tão fáceis. Volta e meia escuta-se ou lê-se algum comentário de que um garoto de menos de 18 anos desenvolve software e consegue com isso ganhar mais do que se tocasse em uma banda de rock.
Possíveis causas
A seguinte figura mostra um diagrama de Ishikawa adaptado, em que são apresentadas possíveis causas que contribuem para que se consiga desenvolver software fidedigno, e outras que atrapalham ao tentar fazer isso. Nesse diagrama agreguei as causas em seis eixos, a saber: Processos, Instrumentos, Pessoal, Especificação, Controle da qualidade e Medição. Imediatamente muitos reclamarão: “mas onde se encontram: arquitetura, projeto, integração, aspectos, agentes, linhas de produto, middleware” e inúmeras outras. Ou então dirão: “o diagrama vale nada, a minha solução mágica não está contemplada”. Na realidade, a forma de registrar arquitetura, projeto etc. é um instrumento. Já a sequenciação desse trabalho é um processo. Finalmente, a habilidade de realizar essas tarefas encontra-se em formação e proficiência entre outras. Ou seja, os eixos estabelecem uma espécie de ponto de vista. É esperado que a maior parte das abordagens favoritas de cada um possa ser particionada em visões e, a seguir, catalogada em uma das causas que atingem estes eixos.
Causas podem favorecer. Estas devemos estimular, na esperança que se passe a desenvolver software mais fidedigno. Óbvio que não adianta enfatizar uma das causas sem se preocupar com as outras. Por exemplo, poderíamos desenvolver a super-ferramenta que leva a software 100% confiável. Pena que a ferramenta será utilizada por humanos, e imediatamente vale o ditado: “Um tolo com uma ferramenta continua sendo um tolo”. Precisa-se ter formação, capacitação e experiência profissional para poder fazer bom uso de uma ferramenta sofisticada. Quanto mais poderosa, em geral maior será a necessidade de proficiência (experiência profissional mais formação). Ou seja, as causas formam um sistema em que se precisa procurar um equilíbrio entre elas para que o objetivo software fidedigno possa vir a ser alcançado.
Outras causas podem atrapalhar. Por exemplo, programas de ensino que não se preocupem com a prática como ocorre no mundo real – isto é fora dos laboratórios de ensino e pesquisa – pouco contribuem com experiência profissional. Muitas vezes também enfatizam excessivamente coisas importantes do ponto de vista científico, mas de pouca utilidade no dia a dia do desenvolvimento. Devemos desestimular as causas que atrapalham. Mas é claro que um profissional de bom calibre necessita conhecer Ciência da Computação e Matemática. O problema está na ênfase. De novo esbarramos no sistema que precisa ser equilibrado. Ou seja, zerar as coisas que atrapalham também não resolve.
A especificação ideal é uma que está completa, correta, e que permite que se formule toda a sorte de testes e experimentos para comprovar a qualidade do software desenvolvido a partir dela. Mas quantas vezes você viu uma que satisfizesse isso? De maneira geral elas são voláteis, no sentido que mudam com freqüência, são imprecisas, incompletas e têm várias outras deficiências. Mas são elas que usamos para desenvolver a maior parte do software disponível hoje.
Não se esqueçam que pontes e prédios caem, máquinas não fazem o que deveriam fazer etc. Ou seja, mesmo nas engenharias convencionais, que têm vários séculos de existência, temos problemas decorrentes da falibilidade humana e da falta de conhecimento dos engenheiros. Muitas vezes o conhecimento falta simplesmente por ainda não se conhecer a teoria embasadora. Depois que Santos Dumont demonstrou que um avião consegue levantar vôo por si só[3], começou a evolução que nos levou aos modernos aviões de grande porte. Antes disso, dizia-se que o mais pesado do que o ar não é capaz de voar. “E as aves?”, perguntaram uns. Resposta: “Elas têm o Espírito Divino da Vida que as faz levitar.”
O diálogo anterior nos leva ao problema da “achologia”. Essa está presente em todas as frases que começam com “eu acho que …”. É um sinal que não se tem certeza, possivelmente por não ser possível tê-la. Mas muitas vezes é decorrência da falta de medição ou de experimentação realizadas com rigor. Engenharia de Software ainda é uma área de conhecimento muito jovem. Ainda não sabemos muita coisa que seria necessária saber para podermos desenvolver software fidedigno e saber que estamos fazendo isso. Como é que se aprende? Fazendo experimentos controlados, medindo propriedades, formulando teorias e comprovando ou desprovando-as através desses experimentos e medições. À medida que se vai colecionando fatos comprovados, começa-se a dispor de um corpus de conhecimento que assegura um melhor desempenho no futuro.
Tycho-Brahe observou cuidadosamente as estrelas e registrou as suas observações. Estas observações permitiram a Kepler formular as leis dos movimentos dos corpos celestes, confirmando as hipóteses de Copérnico e Galileu de que a Terra gira em torno do Sol. Isso, por sua vez, permitiu a Newton formular as leis da gravitação universal. Antes dessas medições achava-se que a Terra era o centro do Universo, não só se achava, mas também matava-se os que não achassem o mesmo. Ou seja, a moderna ciência tornou-se possível em virtude da medição realizada com rigor, mesmo que os instrumentos ainda fossem bastante primitivos. Eis um exemplo a adaptar e seguir.
Queremos desenvolver um software. Produzimos e inspecionamos cuidadosamente especificações verificáveis. Procuramos seguir as melhores práticas ao desenvolver. Testamos sistematicamente este software. Acreditamos que temos um exemplo digno de prêmio de “melhor trabalho”. Afinal, garantem os professores, que o rigor usado leva inevitavelmente a um software perfeito. Entrega-se o software ao usuário. Poucas semanas mais tarde ele volta dizendo: “O software Maravilha falhou. Por favor, conserte.” e mais nada. Por que falhou? Onde falhou? Como é que o software tão cuidadosamente elaborado pôde falhar? Para poder responder a esta pergunta é necessário que o software tenha sido desenvolvido com boa instrumentação embutida nele. Esta será capaz de informar, antes mesmo de o usuário perceber, que o software falhou. Informa também a região do código onde se encontra o defeito causador, e os dados relevantes no ponto de observação da falha. Agora ficou fácil descobrir a causa – o defeito – e removê-la.
Desenvolver software ainda é uma atividade intensiva em mão de obra. Mais do que isso, tende a ser um trabalho colaborativo em que participam pessoas com uma ampla variedade de habilitações. Mas o comentário geral é que não estão sendo formados profissionais em volume e qualidade satisfatórios para as necessidades das empresas. Por que isso? Por que tão poucos querem estudar coisas relacionadas com computação? Será que a imagem que se faz desse tipo de profissional é a de um nerd – uma espécie de alienado, ou melhor, um maluquete. Precisamos realmente ser, ou parecer que somos, nerds? Por que não aprender a trabalhar de forma disciplinada e sistemática, obedecendo a regras de comprovada eficácia? Por que não organizar o trabalho de tal modo que ao final do dia de trabalho cheguemos a um ponto estável? Assim podemos ir para casa, dormir tranquilamente, sem ter pesadelos em que figuram os programas que não funcionam ou que não conseguimos terminar.
Várias coisas podem contribuir para isso. A seguir vai uma lista. Organizar o trabalho segundo um processo, de preferência ágil. Especificar com cuidado e verificar a qualidade das especificações antes de iniciar o desenvolvimento. Assegurar que as especificações sejam verificáveis, isto é, que digam como examinar o software para determinar se implementa as especificações. Utilizar boas práticas. Respeitar padrões e normas de programação. Utilizar ferramentas, para controlar a qualidade dos programas, por exemplo, analisadores estáticos e teste automatizado. Utilizar técnicas formais leves para incorporar instrumentação eficiente e eficaz aos programas, de modo que o software se torne auto-verificável. Medir propriedades relevantes, por exemplo, desempenho e limite da capacidade de processamento. Injetar defeitos – chamados de mutantes – e verificar se os testes são capazes de detectá-los. Isso é uma forma de medir a eficácia dos testes.
Se você leu com cuidado a lista, terá observado que causas provenientes de todos os eixos figuram nela. Isso reforça a observação anterior de que a figura representa um sistema de causas que precisam ser enfatizadas ou desestimuladas, mas isso de uma forma harmoniosa. Veja agora o número de causas.
Com um pouco de imaginação você provavelmente encontrará outras que não foram contempladas. Isso mostra que o problema de desenvolver software fidedigno é intrinsecamente complexo, por depender de um número muito grande de causas interdependentes. Por outro lado, justamente por ser complexo é um desafio interessante de ser vencido. É extremamente gratificante chegar-se ao final do desenvolvimento de um software, sabendo que foi realizado um bom trabalho. Segundo os médicos, quem exercita os neurônios não sofrerá de Alzheimer ou Parkinson. Quem desenvolve software para valer, exercita neurônios. Logo…
Diagrama das causas que favorecem ou atrapalham o desenvolvimento de software fidedigno |
Outras causas podem atrapalhar. Por exemplo, programas de ensino que não se preocupem com a prática como ocorre no mundo real – isto é fora dos laboratórios de ensino e pesquisa – pouco contribuem com experiência profissional. Muitas vezes também enfatizam excessivamente coisas importantes do ponto de vista científico, mas de pouca utilidade no dia a dia do desenvolvimento. Devemos desestimular as causas que atrapalham. Mas é claro que um profissional de bom calibre necessita conhecer Ciência da Computação e Matemática. O problema está na ênfase. De novo esbarramos no sistema que precisa ser equilibrado. Ou seja, zerar as coisas que atrapalham também não resolve.
A especificação ideal é uma que está completa, correta, e que permite que se formule toda a sorte de testes e experimentos para comprovar a qualidade do software desenvolvido a partir dela. Mas quantas vezes você viu uma que satisfizesse isso? De maneira geral elas são voláteis, no sentido que mudam com freqüência, são imprecisas, incompletas e têm várias outras deficiências. Mas são elas que usamos para desenvolver a maior parte do software disponível hoje.
Não se esqueçam que pontes e prédios caem, máquinas não fazem o que deveriam fazer etc. Ou seja, mesmo nas engenharias convencionais, que têm vários séculos de existência, temos problemas decorrentes da falibilidade humana e da falta de conhecimento dos engenheiros. Muitas vezes o conhecimento falta simplesmente por ainda não se conhecer a teoria embasadora. Depois que Santos Dumont demonstrou que um avião consegue levantar vôo por si só[3], começou a evolução que nos levou aos modernos aviões de grande porte. Antes disso, dizia-se que o mais pesado do que o ar não é capaz de voar. “E as aves?”, perguntaram uns. Resposta: “Elas têm o Espírito Divino da Vida que as faz levitar.”
O diálogo anterior nos leva ao problema da “achologia”. Essa está presente em todas as frases que começam com “eu acho que …”. É um sinal que não se tem certeza, possivelmente por não ser possível tê-la. Mas muitas vezes é decorrência da falta de medição ou de experimentação realizadas com rigor. Engenharia de Software ainda é uma área de conhecimento muito jovem. Ainda não sabemos muita coisa que seria necessária saber para podermos desenvolver software fidedigno e saber que estamos fazendo isso. Como é que se aprende? Fazendo experimentos controlados, medindo propriedades, formulando teorias e comprovando ou desprovando-as através desses experimentos e medições. À medida que se vai colecionando fatos comprovados, começa-se a dispor de um corpus de conhecimento que assegura um melhor desempenho no futuro.
Tycho-Brahe observou cuidadosamente as estrelas e registrou as suas observações. Estas observações permitiram a Kepler formular as leis dos movimentos dos corpos celestes, confirmando as hipóteses de Copérnico e Galileu de que a Terra gira em torno do Sol. Isso, por sua vez, permitiu a Newton formular as leis da gravitação universal. Antes dessas medições achava-se que a Terra era o centro do Universo, não só se achava, mas também matava-se os que não achassem o mesmo. Ou seja, a moderna ciência tornou-se possível em virtude da medição realizada com rigor, mesmo que os instrumentos ainda fossem bastante primitivos. Eis um exemplo a adaptar e seguir.
Queremos desenvolver um software. Produzimos e inspecionamos cuidadosamente especificações verificáveis. Procuramos seguir as melhores práticas ao desenvolver. Testamos sistematicamente este software. Acreditamos que temos um exemplo digno de prêmio de “melhor trabalho”. Afinal, garantem os professores, que o rigor usado leva inevitavelmente a um software perfeito. Entrega-se o software ao usuário. Poucas semanas mais tarde ele volta dizendo: “O software Maravilha falhou. Por favor, conserte.” e mais nada. Por que falhou? Onde falhou? Como é que o software tão cuidadosamente elaborado pôde falhar? Para poder responder a esta pergunta é necessário que o software tenha sido desenvolvido com boa instrumentação embutida nele. Esta será capaz de informar, antes mesmo de o usuário perceber, que o software falhou. Informa também a região do código onde se encontra o defeito causador, e os dados relevantes no ponto de observação da falha. Agora ficou fácil descobrir a causa – o defeito – e removê-la.
Desenvolver software ainda é uma atividade intensiva em mão de obra. Mais do que isso, tende a ser um trabalho colaborativo em que participam pessoas com uma ampla variedade de habilitações. Mas o comentário geral é que não estão sendo formados profissionais em volume e qualidade satisfatórios para as necessidades das empresas. Por que isso? Por que tão poucos querem estudar coisas relacionadas com computação? Será que a imagem que se faz desse tipo de profissional é a de um nerd – uma espécie de alienado, ou melhor, um maluquete. Precisamos realmente ser, ou parecer que somos, nerds? Por que não aprender a trabalhar de forma disciplinada e sistemática, obedecendo a regras de comprovada eficácia? Por que não organizar o trabalho de tal modo que ao final do dia de trabalho cheguemos a um ponto estável? Assim podemos ir para casa, dormir tranquilamente, sem ter pesadelos em que figuram os programas que não funcionam ou que não conseguimos terminar.
Várias coisas podem contribuir para isso. A seguir vai uma lista. Organizar o trabalho segundo um processo, de preferência ágil. Especificar com cuidado e verificar a qualidade das especificações antes de iniciar o desenvolvimento. Assegurar que as especificações sejam verificáveis, isto é, que digam como examinar o software para determinar se implementa as especificações. Utilizar boas práticas. Respeitar padrões e normas de programação. Utilizar ferramentas, para controlar a qualidade dos programas, por exemplo, analisadores estáticos e teste automatizado. Utilizar técnicas formais leves para incorporar instrumentação eficiente e eficaz aos programas, de modo que o software se torne auto-verificável. Medir propriedades relevantes, por exemplo, desempenho e limite da capacidade de processamento. Injetar defeitos – chamados de mutantes – e verificar se os testes são capazes de detectá-los. Isso é uma forma de medir a eficácia dos testes.
Se você leu com cuidado a lista, terá observado que causas provenientes de todos os eixos figuram nela. Isso reforça a observação anterior de que a figura representa um sistema de causas que precisam ser enfatizadas ou desestimuladas, mas isso de uma forma harmoniosa. Veja agora o número de causas.
Com um pouco de imaginação você provavelmente encontrará outras que não foram contempladas. Isso mostra que o problema de desenvolver software fidedigno é intrinsecamente complexo, por depender de um número muito grande de causas interdependentes. Por outro lado, justamente por ser complexo é um desafio interessante de ser vencido. É extremamente gratificante chegar-se ao final do desenvolvimento de um software, sabendo que foi realizado um bom trabalho. Segundo os médicos, quem exercita os neurônios não sofrerá de Alzheimer ou Parkinson. Quem desenvolve software para valer, exercita neurônios. Logo…
Concluindo
O artigo procurou mostrar que o desenvolvimento de software fidedigno é intrinsecamente complexo, que requer um volume grande de conhecimento e bastante experiência profissional. Mas que representa um desafio gratificante. O artigo baseia-se num modelo incompleto e que identifica causas que favorecem ou atrapalham o desenvolvimento de software de boa qualidade. O modelo tem por objetivo suscitar discussões e, acima de tudo, deixar claro que muito ainda precisa ser feito para que o desenvolvimento de software se torne uma atividade que leve a sistemas que não falham nas horas mais inoportunas. Em particular, o modelo procura deixar claro que precisamos deixar os “achismos” de lado, e procurar experimentar e medir de modo que possamos fundamentar as nossas afirmações.
Recursos e Referências
[1] Juristo, N.; Moreno, A.M.; (2001) Basics of Software Engineering Experimentation; Dordrecht: Kluwer.
[2] Glass, R.L.; (2003) Facts and Fallacies of Software Engineering; Reading, Massachusetts: Addison-Wesley.
[3] O dos irmãos Wright era catapultado.
[2] Glass, R.L.; (2003) Facts and Fallacies of Software Engineering; Reading, Massachusetts: Addison-Wesley.
[3] O dos irmãos Wright era catapultado.
Nenhum comentário:
Postar um comentário