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!
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!
Respostas:
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.
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.
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.
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.
Para responder sua pergunta, precisamos de dois elementos:
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.
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.
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.