Programação estruturada
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 'teorema do programa estruturado [en]' (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
[editar | editar código-fonte]É 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
[editar | editar código-fonte]Estruturas de controle
[editar | editar código-fonte]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
[editar | editar código-fonte]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
[editar | editar código-fonte]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
[editar | editar código-fonte]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
[editar | editar código-fonte]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
[editar | editar código-fonte]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
[editar | editar código-fonte]- 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
- ↑ a b c «Fábrica de Software » Programação Estruturada Versus Programação Orientada a Objetos». 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
- ↑ a b 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
- ↑ a b http://people.cs.aau.dk/~normark/oop-csharp/html/notes/theme-index.html
- ↑ a b 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