O desenvolvimento de programas
O desenvolvimento de programas é frequentemente confundido com a actividade de programar numa determinada linguagem de programação. Nada poderia estar mais longe da verdade. Existe todo um trabalho preparatório de definição exacta do que se pretende fazer e de desenho da solução para o problema em questão. Se este trabalho preparatório for bem feito, a tarefa de programação em si torna-se bastante mais simples.
Assim como se despende bastante tempo na fase de análise e desenho da solução, também é necessário despender tempo na fase de testes e na finalização da documentação, até o programa estar completo.
Quanto mais complexo for o problema, a solução e o programa, mais complexo será o seu desenvolvimento. E também será maior a equipa de trabalho envolvida.
As metodologias para o desenvolvimento de programas e software são objecto de estudo em engenharia de programação ou engenharia de software, em que existe uma separação clara entre programa e sistema computacional ou software.
Uma das metodologias mais utilizadas no desenvolvimento de programas é baseada no modelo em cascata, no qual temos em geral cinco fases:
- Análise do problema
- Desenvolvimento da solução
- Programação da solução
- Verificação e testes
- Manutenção Em todas estas fases deve ser produzida documentação a descrever as decisões tomadas e de suporte às fases seguintes.
Nota-se que esta é apenas uma das metodologias, muitas outras foram propostas. E no desenvolvimento de software devemos ter sempre em mente a lei de Murphy.
Análise do problema
Durante a fase de análise, o programador ou analista estuda o problema (junto com o cliente) para determinar exactamente o que tem de ser feito, ainda antes de saber como se vai fazer.
Ainda que esta fase seja de extrema importância, é muitas vezes ignorada levando a programas mal concebidos que não respondem ao que era necessário ser feito.
A interacção entre o programador e o cliente é de extrema importância, conduzida num processo contínuo de compreensão mútua em que a comunicação ao nível técnico nem sempre é fácil.
O resultado desta fase é a produção do documento de análise de requisitos, especificando o que faz o programa, alternativas de desenvolvimento, riscos inerentes ao desenvolvimento, plano faseado de desenvolvimento, estimativas de custo, etc.
Desenvolvimento da solução
Nesta fase determina-se como se vai fazer e é a fase mais criativa, em que se desenvolve uma solução ou algoritmo para o problema.
O desenvolvimento da solução ou algoritmo é feita ainda sem considerar uma linguagem de programação em particular. Normalmente utiliza-se pseudocódigo e/ou linguagem natural, mas de forma rigorosa e tão formal quanto possível.
A ideia chave é a abstracção e recorres-se a desenvolvimento top-down e refinamento por passos. Desta forma é possível controlar a complexidade da solução e obter uma solução modular, o que facilita potencias alterações futuras e é importante para uma boa manutenção do programa.
O resultado desta fase é o documento de concepção, o qual descreve ao pormenor a solução e é em geral dividido em duas partes, concepção global (módulos e organização dos mesmos) e concepção pormenorizada (algoritmos e tipos de dados em cada módulo).
Programação da solução
Após a identificação do problema e o desenho pormenorizado da solução, passamos à fase de programação.
A primeira questão a ter em conta é a escolha da linguagem de programação e bibliotecas relacionadas, promovendo a reutilização de código. Para isso temos de ter em conta as linguagens de programação e bibliotecas disponíveis no sistema que vai ser utilizado, em que é claro que apenas podemos utilizar uma linguagem e as bibliotecas que estejam disponíveis. Por outro lado, temos de ter em conta a natureza do problema e da solução, e.g., existem linguagens/bibliotecas mais adequadas para lidar com cálculos numéricos e outras mais adequadas para manipulação simbólica.
Uma vez escolhida a linguagem e as bibliotecas úteis, a codificação da solução ou algoritmo é em geral simples.
O resultado é um programa escrito na linguagem escolhida, devidamente comentado, assim como um documento de concepção em que complementa a descrição da solução e algoritmo produzida na fase anterior, incluindo por exemplo as decisões relativas à representação dos tipos de dados.
No final desta fase são também apresentados os resultados dos testes efectuados durante o desenvolvimento para cada módulo, também conhecidos por testes unitários.
A execução de testes unitários permite-nos detectar erros, que teremos de corrigir. Para isso temos de proceder à depuração sintáctica e semântica. A depuração sintáctica é simples na medida em que o processador na linguagem emite avisos a respeito de erros sintácticos. A depuração semântica é em geral mais complexa e recorremos a ferramentas de depuração, que nos permitem por exemplo inspeccionar o valor das variáveis, alterar os seus valores durante a execução do programa ou até mesmo visualizar a execução. Ainda a este nível é comum adoptar uma estratégia bottom-up em que começamos por testar mais simples e que estão na base da solução e, uma vez testados, passamos a testar módulos em níveis mais acima e que dependem apenas de módulos já testados.
Em Python temos várias ferramentas de desenvolvimento que nos ajudam a documentar o código, a testar o código e a depurar o código.
Paralelamente a esta fase, é prática comum produzir-se a documentação de utilização do programa.
Verificação e testes
Nesta fase, para além da verificação dos testes unitários relativos a cada módulo preparados na fase de desenvolvimento, o programa é também sujeito a testes a fim de se verificar se compre todos os requisitos especificados na fase de análise.
Podemos portanto dividir em testes unitários ou de módulo, testes de integração. e testes de aceitação.
Com vista a este fim são desenhados vários testes, em geral por um equipa dedicada apenas a esta tarefa. Em programas e sistemas computacionais mais complexos, é impossível testar todas as combinações de dados e testar exaustivamente uma solução. Tal como Edsger W. Dijkstra observou, os testes apenas podem mostrar a existência de erros, nunca a sua ausência!
Nota-se que existem métodos para desenvolver programas e demonstrar formalmente a correcção semântica dos mesmos. No entanto, dado o custo acrescido no desenvolvimento e experiência exigida aos programadores, a sua aplicabilidade tem-se limitado a programas pequenos ou a sistemas computacionais críticos.
Manutenção
Esta fase decorre depois do programa ter sido finalizado e tem em geral dois objectivos. Adaptação do software a alterações na especificação do software. Correcção de erros detectados durante o funcionamento e utilização do programa.