Programação Estruturada (PE) é um padrão ou paradigma de programação da engenharia de softwares, com ênfase em sequência, decisão e, iteração (sub-rotinas, laços de repetição, condicionais e, estruturas em bloco),[1][2] criado no final de 1950 junto às linguagens ALGOL 58 e ALGOL 60,[3]
Este paradigma é normalmente formado por código em um único bloco[2] e foi impulsionado pelas vantagens práticas que o paradigma oferece, e também pelo 'Predefinição:Ill' (de 1966, também chamado de teorema de Böhm-Jacopini) e a carta aberta de Dijkstra 'Go To Statement Considered Harmful' (de 1968). De fato, muitas linguagens não possuem GOTOs para desincentivar a programação não-estruturada (nota: Donald Knuth advogou o GOTO em algumas circunstâncias[4].
A PE foi o paradigma dominante na escrita de software até a programação orientada a objetos (POO). Enquanto a PE fia-se em estruturas de controle de alto nível (em oposição ao uso de GOTOs), concepções top-down e refinamento por passos, a POO se baseia no conceito de objetos que possuem atributos (dados) e métodos (procedimentos).
Apesar de ter sido sucedida pela POO, a PE ainda é muito influente pois grande parte das pessoas ainda aprende programação através dela. Para a resolução de problemas simples e diretos, a programação estruturada é bastante eficiente (talvez mais eficiente que a POO). Além disso, por exigir formas de pensar relativamente complexas, a POO até hoje ainda não é bem compreendida ou usada pela maioria.
Diversas linguagens relevantes hoje (e.g. Cobol, PHP, Perl e Go) ainda utilizam o paradigma estruturado, embora possuam suporte para a orientação ao objeto e para outros paradigmas de programação.
Estrutura do paradigma
É formada por três estruturas:[2]
- Sequência: a tarefa é executada logo após a outra;
- Decisão: a tarefa é executada após um teste lógico, e;
- Iteração: a partir do teste lógico, um trecho do código pode ser repetido finitas vezes.
Elementos básicos da teoria
Estruturas de controle
Na PE, os programas são vistos como compostos das seguintes 'estruturas de controle' (ECs) [5]:
- Sequência: de instruções ou sub-rotinas executadas em sequência (
a=4; b=4*5
) - Seleção/condicional: instruções são executadas ou não conforme o estado do programa (if, else, elif/elseif, endif)
- iteração/repetição: instruções são executados até que o programa atinja um determinado estado (for, while, repeat, do..until)
- recursão: instruções executadas com chamadas auto-referenciadas até que certas condições sejam satisfeitas. Exemplo:
function fatorial(x){
if(x > 1){
return x*fatorial(x-1);
}
}
Há a utilização de 'sub-rotinas' em que as ECs são agrupadas e utilizadas através de um única instrução (são as funções, métodos, subprogramas, procedimentos). Blocos permitem que uma sequência de instruções seja tratada como uma única instrução.
Refinamento por passos
Uma ideia central na PE é o refinamento por passos, em que o programa é desenvolvido de maneira top-down, por exemplo:
- comece com o programa principal
- use as ECs de iteração e seleção
- escreva as chamadas para as rotinas (r1, r2, etc) quando necessário. Diz-se 'postule r1, r2'.
- Implemente r1, r2, ..., com chamadas para outras rotinas conforme conveniente.
- Continue implementando as rotinas até que não sejam necessários procedimentos adicionais.
Na prática, é usual iniciar a programação não exatamente do topo, até porque é comum que haja vários topos[6], mas isso depende da complexidade e modularidade do software.
Desvios
Dentre os desvios mais comuns da programação estruturada, há múltiplos pontos:
- De saída:
- terminação antecipada: return em uma função, break or continue em um laço de interação, ou um exit em algum programa. Na programação estruturada, a rigor, há um só ponto de saída da rotina sendo executada.
- Manejo de exceção: clausulas como (try.. except) do Python ou (try.. catch) do C++, também implicam em múltiplos pontos de saída da rotina.
- De entrada: útil e.g. para geradores, streaming, máquinas de estado.
Conceito-chave: GOTO
Seja um programa uma sequência de instruções a serem seguidas (e.g. por um computador). Considere um ponteiro que indica a instrução a ser executada na próxima oportunidade. Um GOTO é um reposicionamento arbitrário deste ponteiro. Embora seja um comando poderoso, o uso de GOTOs é considerado, em geral, má prática, havendo quem o defenda em algumas situações.[4]
Na programação imperativa, que possui ênfase na modificação de valores em endereços de memória (i.e. instruções de atribuição), o uso de GOTOs é abundante. Em muitos contextos, pode-se assumir que 'programação estruturada' é sinônimo de programação sem GOTO (sem pulos, sem redirecionamentos arbitrários do ponteiro da sequência de instruções em execução). Estes foram os dois primeiros paradigmas dominantes na programação de computadores. A imperativa desde o início da programação até os anos 1970. A estruturada até o final década de 1990, e então deu lugar à POO.
Críticas usuais à PE
Dentre as críticas à PE, constam[5]:
- PE é orientada para a resolução de um problema em particular.
- Um escopo mais amplo é muitas vezes conveniente.
- PE é realizada pela decomposição gradual da funcionalidade.
- As estruturas advindas de funcionalidade/ação/controle não são as partes mais estáveis de um programa.
- Foco em estruturas de dados ao invés de estruturas de controle é uma alternativa.
- Sistemas reais não possuem um único topo.[6]
- Pode ser apropriado considerar alternativas à abordagem top-down.
Veja também a POO, paradigma que foi estabelecido depois de décadas de PE.
PE vs POO
Entres os paradigmas PE e POO, não existe certo e errado. A POO tende a dar melhores resultados em programas maiores com reuso de partes/sub-rotinas dos programas. Ambos os paradigmas possuem vantagens e desvantagens. A melhor prática é evitar extremismo (moldes rígidos): há casos em que é melhor priorizar a POO ou a PE, e mesmo quando uma estratégia é evidentemente melhor, o purismo tende a gerar software menos organizado ao custo de mais trabalho.
Tópicos avançados
- Diagrama Nassi-Shneiderman: uma representação gráfica (estructograma) para PE, desenvolvida em 1972.
- Carta de estrutura (structure chart): um diagrama usado na PE para organizar os módulos em árvore.
Referências
- ↑ «Programação estruturada». Faculdade de Engenharia Elétrica e de Computação - UNICAMP. Consultado em 22 de novembro de 2016
- ↑ 2,0 2,1 2,2 «Fábrica de Software » Programação Estruturada Versus Programação Orientada a Objetos» (em português). Senac Mato Grosso. Consultado em 1 de novembro de 2019
- ↑ Clark, Leslie B. Wilson, Robert G.; Robert, Clark (2000). Comparative programming languages 3rd ed. Harlow, England: Addison-Wesley. p. 20. ISBN 9780201710120. Consultado em 25 de novembro de 2015
- ↑ 4,0 4,1 Knuth, Donald E. (1 de dezembro de 1974). «Structured Programming with go to Statements». ACM Computing Surveys (CSUR). 6 (4): 261–301. ISSN 0360-0300. doi:10.1145/356635.356640
- ↑ 5,0 5,1 http://people.cs.aau.dk/~normark/oop-csharp/html/notes/theme-index.html
- ↑ 6,0 6,1 Bertrand Meyer (2009). Touch of Class: Learning to Program Well with Objects and Contracts. [S.l.]: Springer Science & Business Media. ISBN 978-3-540-92144-8