POO vs Programação Funcional vs Procedimental [fechado]


237

Quais são as diferenças entre esses paradigmas de programação e eles são mais adequados para problemas específicos ou quaisquer casos de uso favorecem um sobre os outros?

Exemplos de arquitetura apreciados!


Esta não é uma resposta completa, mas escrevo um pouco sobre como "funcional" afeta / contrasta o estilo "OO" (no contexto de F #) aqui: lorgonblog.spaces.live.com/blog/cns!701679AD17B6D310!511. entrada
Brian

Você pode ler isso! Há muitos exemplos de quando usar cada formiga que é as principais diferenças, vantagens / desvantagens etc
Nikita Ignatov



Tio Bob twittou sobre isso. E aqui também .
jaco0646 16/03

Respostas:


129

Todos eles são bons à sua maneira - são simplesmente abordagens diferentes para os mesmos problemas.

Em um estilo puramente processual, os dados tendem a ser altamente dissociados das funções que operam nele.

Em um estilo orientado a objetos, os dados tendem a levar consigo uma coleção de funções.

Em um estilo funcional, dados e funções tendem a ter mais em comum entre si (como em Lisp e Scheme), oferecendo mais flexibilidade em termos de como as funções são realmente usadas. Os algoritmos também tendem a ser definidos em termos de recursão e composição, em vez de loops e iteração.

Obviamente, a própria linguagem influencia apenas qual estilo é preferido. Mesmo em uma linguagem totalmente funcional como Haskell, você pode escrever em um estilo processual (embora isso seja altamente desencorajado), e mesmo em uma linguagem processual como C, você pode programar em um estilo orientado a objetos (como no GTK + e APIs de EFL).

Para ser claro, a "vantagem" de cada paradigma está simplesmente na modelagem de seus algoritmos e estruturas de dados. Se, por exemplo, seu algoritmo envolve listas e árvores, um algoritmo funcional pode ser o mais sensato. Ou, se, por exemplo, seus dados são altamente estruturados, pode fazer mais sentido compor como objetos se esse for o paradigma nativo da sua linguagem - ou, poderia ser tão facilmente escrito como uma abstração funcional de mônadas, que é o paradigma nativo de idiomas como Haskell ou ML.

A escolha de qual você usa é simplesmente o que faz mais sentido para o seu projeto e as abstrações suportadas pelo seu idioma.


5
O que você disse não parece refletir o que você escreveu. Você diz que eles não têm "prós e contras" e depois diz como são abordagens diferentes. Por que alguém escolheria uma abordagem em detrimento de outra, com base em qualquer situação? pontos fortes e fracos, prós e contras, como você os chama, eles existem! Não estou dizendo que um seja inerentemente melhor, e você também não. Eu acredito que é isso que você realmente estava tentando dizer. a menos que você realmente acredite que qualquer abordagem escolhida não tenha pontos positivos e negativos, em relação a outra abordagem.
JM Becker

1
@TechZilla: Eu concordo que minhas palavras eram ruins, mas o que eu quis dizer é que não há realmente uma lista de recursos que você possa apontar e dizer que a linguagem X é melhor que Y sem qualificar que a linguagem X é mais adequada para escrever o algoritmo U e a linguagem Y pode ser mais adequado para escrever o algoritmo V, enquanto ambos podem ser facilmente implementados em qualquer idioma.
greyfade

2
A diferença entre processual e funcional não está clara para mim. Estou aprendendo Scheme / Rackett na faculdade, mas realmente não vejo a grande diferença entre ele e C ou PHP processual, você poderia dar um exemplo?
Leonel

7
@ Leonel: A maior diferença que a maioria das pessoas citará é que, em linguagens procedurais, você pode usar um loop for, mas linguagens funcionais não existem - em vez disso, você usa chamadas recursivas para funções para executar a mesma tarefa. As linguagens funcionais também tornam as funções objetos de primeira classe - você pode distribuí-las como faria com um número - mas não pode fazer isso em C (e o suporte do PHP para isso é quebrado).
greyfade

2
@tastro: Quando um paradigma faz mais sentido que o outro. Isso é realmente tudo. Às vezes, faz mais sentido modelar seu código como a composição de funções e, às vezes, faz mais sentido modelar seus dados como objetos. Existem muitas maneiras de expressar algoritmos e estruturas de dados. OOP e funcional são duas dessas coisas.
Greyfade

25

Acho que as bibliotecas, ferramentas, exemplos e comunidades disponíveis superam completamente o paradigma nos dias de hoje. Por exemplo, ML (ou qualquer outra coisa) pode ser a melhor linguagem de programação para todos os fins , mas se você não consegue obter boas bibliotecas para o que está fazendo, está ferrado.

Por exemplo, se você está criando um videogame, há mais bons exemplos de código e SDKs em C ++, então provavelmente você está melhor com isso. Para um aplicativo Web pequeno, existem ótimas estruturas Python, PHP e Ruby que o farão funcionar rapidamente. Java é uma ótima opção para projetos maiores, devido à verificação em tempo de compilação e às bibliotecas e plataformas corporativas.

Costumava ser o caso de as bibliotecas padrão para diferentes linguagens serem muito pequenas e facilmente replicáveis ​​- C, C ++, Assembler, ML, LISP, etc. como comunicações de rede, criptografia, gráficos, formatos de arquivo de dados (incluindo XML), até estruturas de dados básicas, como árvores balanceadas e tabelas de hash, foram deixadas de fora!

Linguagens modernas como Python, PHP, Ruby e Java agora vêm com uma biblioteca padrão muito mais decente e têm muitas boas bibliotecas de terceiros que você pode usar facilmente, graças em grande parte à adoção de espaços de nomes para impedir que as bibliotecas colidam umas com as outras, e coleta de lixo para padronizar os esquemas de gerenciamento de memória das bibliotecas.


5
Python, ruby, ... não possuem bibliotecas "padrão" como C ou LISP, pois são linguagens de implementação únicas. Python é o que Guido diz, não há padrão. Atualmente, qualquer implementação específica em C ou LISP (ou qualquer outra) vem com um grande conjunto de bibliotecas além das padrão.
Dan Andreatta

8
A questão era sobre as diferenças entre programação orientada a objetos, funcional e processual. Enquanto os idiomas mencionados nessas respostas certamente se prestam a uma dessas abordagens, a resposta não menciona nenhum desses conceitos ... Independentemente de "as bibliotecas disponíveis [...] [superarem] o paradigma", isso não responde à pergunta em questão, evitando assim o que é uma pergunta completamente válida.
Rinogo 25/10

1
rant relacionado da ircmaxell
rinogo 26/10/13

20

Esses paradigmas não precisam ser mutuamente exclusivos. Se você observar o python, ele suporta funções e classes, mas, ao mesmo tempo, tudo é um objeto, incluindo funções. Você pode combinar e combinar o estilo funcional / oop / processual em um único pedaço de código.

O que quero dizer é que, nas linguagens funcionais (pelo menos em Haskell, a única que estudei), não há declarações! funções são permitidas apenas uma expressão dentro delas !! MAS, as funções são cidadãos de primeira classe, você pode passá-las como parâmetros, juntamente com várias outras habilidades. Eles podem fazer coisas poderosas com poucas linhas de código.

Enquanto estiver em uma linguagem processual como C, a única maneira de transmitir funções é usando ponteiros de função, e isso por si só não permite muitas tarefas poderosas.

Em python, uma função é um cidadão de primeira classe, mas pode conter um número arbitrário de instruções. Portanto, você pode ter uma função que contém código processual, mas pode distribuí-la exatamente como as linguagens funcionais.

O mesmo vale para OOP. Uma linguagem como Java não permite que você escreva procedimentos / funções fora de uma classe. A única maneira de transmitir uma função é envolvê-la em um objeto que implementa essa função e, em seguida, passar esse objeto.

No Python, você não tem essa restrição.


Acredito que você quis dizer "esses paradigmas não precisam ser mutuamente exclusivos". Os 3 são ortogonais, de maneira que idealmente você poderia usar um, 2 ou os 3 em um único programa (se o seu idioma permitir).
18711 Joe Pineda

Sim, eu acho que mutuamente exclusivo é um termo melhor para isso! graças
Hasen

14

Para a GUI, eu diria que o Paradigma Orientado a Objetos é muito adequado. A janela é um objeto, as caixas de texto são objetos e o botão OK também. Por outro lado, coisas como o Processamento de cordas podem ser feitas com muito menos custos indiretos e, portanto, mais diretas com um simples paradigma processual.

Também não acho que seja uma questão de linguagem. Você pode escrever funcional, procedural ou orientado a objetos em quase qualquer linguagem popular, embora possa haver algum esforço adicional em algumas.


17
Tentou diminuir o voto por perpetuar o equívoco de que "Objeto = widget da GUI", mas vou me abster. OOP funciona tão bem para representar conceitos abstratos, como "UserAccount" ou "PendingSale", quanto para elementos visíveis da interface como "Window" e "Button".
21430 Dave Sherohman

5
Eu escrevi que uma janela pode ser um objeto. Como você tira a conclusão de que todo objeto é uma janela a partir daí? Foi só um exemplo. É claro que o POO também pode ser usado para modelar entidades abstratas e seu relacionamento. De qualquer forma, obrigado por não votar. Eu não tenho muitos pontos de qualquer maneira: D
panschk

6
-1. OOP não tem nada a ver com GUI. Idealmente, o melhor método para projetar guis é usar um arquivo de texto externo (por exemplo, HTML). Enquanto coisas como o processamento de strings são realmente muito melhores com objetos. (pense em strings em C) !!
hasen

1
Eu não sei, talvez eu esteja acostumado a programar com objetos para realizá-lo. Mas como você faria algumas coisas interativas, como alterar o valor no TextBox X quando o valor do TextBox Y foi alterado sem o uso de objetos? Ok, você poderia simplesmente usar vars globais para tudo ...
panschk

1
O processamento de strings é incrivelmente feito em perl (100x melhor que em Java, C ++ ou C #), mas a funcionalidade de strings da linguagem NÃO é absolutamente orientada a objetos. O manuseio de cordas de C foi terrível, mas C não é a única linguagem processual (nem a melhor).
18711 Joe Pineda

6

Para responder sua pergunta, precisamos de dois elementos:

  1. Compreensão das características dos diferentes estilos / padrões de arquitetura.
  2. Compreensão das características dos diferentes paradigmas de programação.

Uma lista de estilos / padrões de arquitetura de software é mostrada no artigo de arquitetura de software no Wikipeida. E você pode pesquisar sobre eles facilmente na web.

Em resumo, o Procedural é bom para um modelo que segue um procedimento, OOP é bom para o design e Funcional é bom para a programação de alto nível.

Acho que você deveria tentar ler a história de cada paradigma e ver por que as pessoas a criam e você pode entendê-las facilmente.

Depois de entender os dois, você pode vincular os itens de estilos / padrões de arquitetura a paradigmas de programação.


2

Eu acho que eles geralmente não são "versus", mas você pode combiná-los. Eu também acho que, muitas vezes, as palavras que você menciona são apenas chavões. Existem poucas pessoas que realmente sabem o que significa "orientação a objetos", mesmo que sejam os evangelistas mais ferozes disso.


1

Um dos meus amigos está escrevendo um aplicativo gráfico usando o NVIDIA CUDA . O aplicativo se encaixa muito bem no paradigma OOP e o problema pode ser decomposto em módulos perfeitamente. No entanto, para usar o CUDA, você precisa usar C, que não suporta herança . Portanto, você precisa ser inteligente.

a) Você cria um sistema inteligente que simula a herança até certo ponto. Pode ser feito!

i) Você pode usar um sistema de gancho , que espera que todo filho C do pai P tenha uma certa substituição para a função F. Você pode fazer com que os filhos registrem suas substituições, que serão armazenadas e chamadas quando necessário.

ii) Você pode usar o recurso de alinhamento de memória struct para transmitir filhos aos pais.

Isso pode ser legal, mas não é fácil encontrar uma solução confiável e à prova de futuro. Você gastará muito tempo projetando o sistema e não há garantia de que não encontrará problemas na metade do projeto. Implementar herança múltipla é ainda mais difícil, se não quase impossível.

b) Você pode usar uma política de nomeação consistente e usar a abordagem de dividir e conquistar para criar um programa. Ele não terá nenhuma herança, mas como suas funções são pequenas, fáceis de entender e formatadas de forma consistente, você não precisa disso. A quantidade de código que você precisa escrever aumenta, é muito difícil manter o foco e não sucumbir a soluções fáceis (hacks). No entanto, essa maneira ninja de codificação é a maneira C de codificação. Manter o equilíbrio entre liberdade de baixo nível e escrever um bom código. Uma boa maneira de conseguir isso é escrever protótipos usando uma linguagem funcional. Por exemplo, Haskell é extremamente bom para algoritmos de prototipagem.

Eu tendem a me aproximar b. Eu escrevi uma solução possível usando a abordagem a e, para ser sincero, parecia muito natural usar esse código.


Os primeiros copmpilers de c ++ nada mais eram do que pré-processadores que geravam código C. Como tal, TODOS os recursos do c ++ - incluindo herança múltipla, podem ser implementados usando C. (emular o tratamento de exceções em c ++ em C exigiria algum tipo de suporte à plataforma para exceções, mas as implementações em c ++ exigem isso também, por isso não acho que seja o básico). ideia inválida).
Chris Becke #

2
@ Chris Becke, sua resposta é muito filosófica. Por um lado, C possui vários padrões (ao longo dos anos), quase nenhum deles completamente adotado pelos compiladores C, muito menos pelo c ++. Dizer que C ++ é um superconjunto de C porque usa a sintaxe C não significa muito, porque você não pode nem escrever código para um compilador C que compila em outro compilador C sem esforço significativo. Além disso, existem recursos de idiomas (sistemas de tipos, suporte a OOD) oferecidos em outros idiomas que seriam impossíveis de implementar em C sem usar C para criar um novo idioma (e é exatamente por isso que existem 'novos idiomas')
Sprague

Você sabe. Não consigo mais ver a relevância que meu comentário tem para este post. : P
Chris Becke

O Cuda suporta C ++ há algum tempo.
Aryeh Leib Taurog
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.