POO vs programmation fonctionnelle vs procédurale [fermé]


237

Quelles sont les différences entre ces paradigmes de programmation et sont-ils mieux adaptés à des problèmes particuliers ou des cas d'utilisation favorisent-ils les uns les autres?

Exemples d'architecture appréciés!


Ce n'est pas une réponse complète, mais j'écris un peu sur la façon dont "fonctionnel" affecte / contraste le style "OO" (dans le contexte de F #) ici: lorgonblog.spaces.live.com/blog/cns!701679AD17B6D310!511. entrée
Brian

Vous pourriez envisager de lire ceci! Il existe de nombreux exemples de moments où utiliser quelle fourmi quelles sont les principales différences, avantages / inconvénients, etc.
Nikita Ignatov



Oncle Bob a tweeté à ce sujet. Et aussi ici .
jaco0646

Réponses:


129

Ils sont tous bons à leur manière - Ce sont simplement des approches différentes des mêmes problèmes.

Dans un style purement procédural, les données ont tendance à être fortement découplées des fonctions qui les opèrent.

Dans un style orienté objet, les données ont tendance à emporter avec elles une collection de fonctions.

Dans un style fonctionnel, les données et les fonctions ont tendance à avoir plus en commun les unes avec les autres (comme dans Lisp et Scheme) tout en offrant plus de flexibilité en termes d'utilisation des fonctions. Les algorithmes ont également tendance à être définis en termes de récursivité et de composition plutôt qu'en boucles et en itération.

Bien sûr, la langue elle-même n'influence que le style préféré. Même dans un langage purement fonctionnel comme Haskell, vous pouvez écrire dans un style procédural (bien que cela soit fortement déconseillé), et même dans un langage procédural comme C, vous pouvez programmer dans un style orienté objet (comme dans GTK + et API EFL).

Pour être clair, «l'avantage» de chaque paradigme réside simplement dans la modélisation de vos algorithmes et structures de données. Si, par exemple, votre algorithme implique des listes et des arbres, un algorithme fonctionnel peut être le plus judicieux. Ou, si, par exemple, vos données sont très structurées, il peut être plus judicieux de les composer comme des objets si tel est le paradigme natif de votre langue - ou, elles pourraient tout aussi bien être écrites comme une abstraction fonctionnelle de monades, ce qui est le paradigme natif de langues comme Haskell ou ML.

Le choix de celui que vous utilisez est simplement ce qui a le plus de sens pour votre projet et les abstractions que votre langage prend en charge.


5
Ce que vous avez dit ne semble pas refléter ce que vous avez écrit. Vous dites qu'ils n'ont pas de «pour et contre», puis vous dites que ce sont des approches différentes. Pourquoi choisir une approche plutôt qu'une autre, en fonction d'une situation donnée? forces et faiblesses, avantages et inconvénients, peu importe comment vous les appelez, ils existent! Je ne dis pas que l'un est intrinsèquement meilleur, et vous non plus. Je crois que c'est ce que vous essayez vraiment de dire. sauf si vous croyez vraiment qu'une approche choisie n'a pas de points positifs et négatifs, par rapport à une autre approche.
JM Becker

1
@TechZilla: Je suis d'accord que ma formulation était médiocre, mais ce que je voulais dire, c'est qu'il n'y a pas vraiment de liste de fonctionnalités sur lesquelles vous pouvez pointer et dire que la langue X est meilleure que Y sans qualifier que la langue X est mieux adaptée à l'écriture de l'algorithme U et de la langue Y pourrait être mieux adapté à l'écriture de l'algorithme V, tandis que les deux peuvent facilement être implémentés dans les deux langues.
greyfade

2
La différence entre la procédure et la fonctionnalité n'est pas claire pour moi. J'apprends Scheme / Rackett au Collège, mais je ne vois vraiment pas la grande différence entre cela et C ou PHP procédural, pourriez-vous donner un exemple?
Leonel

7
@Leonel: La plus grande différence que la plupart des gens citeront est que dans les langages procéduraux, vous pouvez utiliser une boucle for, mais les langages fonctionnels, ça n'existe pas - à la place, vous utilisez des appels récursifs aux fonctions pour effectuer la même tâche. Les langages fonctionnels font également des fonctions des objets de première classe - vous pouvez les faire passer comme vous le feriez pour un nombre - mais vous ne pouvez pas le faire en C (et le support de PHP pour cela est cassé).
greyfade

2
@tastro: Quand un paradigme a plus de sens que l'autre. C'est vraiment tout. Parfois, il est plus logique de modéliser votre code en tant que composition de fonctions, et parfois, il est plus logique de modéliser vos données en tant qu'objets. Il existe de nombreuses façons d'exprimer des algorithmes et des structures de données. La POO et la fonctionnalité sont deux de ces choses.
greyfade

25

Je pense que les bibliothèques, outils, exemples et communautés disponibles l'emportent complètement sur le paradigme de nos jours. Par exemple, ML (ou autre) pourrait être le langage de programmation polyvalent ultime mais si vous ne pouvez pas obtenir de bonnes bibliothèques pour ce que vous faites, vous êtes foutu.

Par exemple, si vous créez un jeu vidéo, il y a d'autres bons exemples de code et SDK en C ++, donc vous êtes probablement mieux avec ça. Pour une petite application Web, il existe d'excellents cadres Python, PHP et Ruby qui vous permettront de démarrer et de fonctionner très rapidement. Java est un excellent choix pour les grands projets en raison de la vérification à la compilation et des bibliothèques et plates-formes d'entreprise.

Auparavant, les bibliothèques standard pour les différents langages étaient assez petites et facilement répliquées - C, C ++, Assembler, ML, LISP, etc. comme les communications réseau, le chiffrement, les graphiques, les formats de fichiers de données (y compris XML), même les structures de données de base comme les arbres équilibrés et les tables de hachage ont été omises!

Les langages modernes comme Python, PHP, Ruby et Java sont désormais livrés avec une bibliothèque standard beaucoup plus décente et ont de nombreuses bonnes bibliothèques tierces que vous pouvez facilement utiliser, grâce en grande partie à leur adoption d'espaces de noms pour empêcher les bibliothèques d'entrer en collision les unes avec les autres, et garbage collection pour standardiser les schémas de gestion de la mémoire des bibliothèques.


5
Python, ruby, ... n'ont pas de bibliothèques "standard" comme C ou LISP, car ce sont des langages d'implémentation uniques. Python est ce que dit Guido, il n'y a pas de norme. Toute implémentation particulière C ou LISP (ou autre) de nos jours est livrée avec un large ensemble de bibliothèques au-delà des bibliothèques standard.
Dan Andreatta

8
La question portait sur les différences entre la programmation orientée objet, fonctionnelle et procédurale. Bien que les langues mentionnées dans ces réponses se prêtent certainement à l'une de ces approches, la réponse ne fait mention d'aucun de ces concepts ... Que "les bibliothèques disponibles [...] [l'emportent] sur le paradigme" soient ou non ", cela ne répond pas à la question posée, évitant ainsi ce qui est une question tout à fait valable.
rinogo

1
Rant lié d' ircmaxell
rinogo

20

Ces paradigmes ne doivent pas être mutuellement exclusifs. Si vous regardez python, il prend en charge les fonctions et les classes, mais en même temps, tout est un objet, y compris les fonctions. Vous pouvez mélanger et faire correspondre le style fonctionnel / oop / procédural en un seul morceau de code.

Ce que je veux dire, c'est que dans les langages fonctionnels (du moins dans Haskell, le seul que j'ai étudié), il n'y a pas de déclarations! les fonctions ne sont autorisées qu'une seule expression à l'intérieur !! MAIS, les fonctions sont des citoyens de première classe, vous pouvez les transmettre en tant que paramètres, avec un tas d'autres capacités. Ils peuvent faire des choses puissantes avec peu de lignes de code.

Dans un langage procédural comme C, la seule façon de transmettre des fonctions est d'utiliser des pointeurs de fonction, et cela ne permet pas à lui seul de nombreuses tâches puissantes.

En python, une fonction est un citoyen de première classe, mais elle peut contenir un nombre arbitraire d'instructions. Vous pouvez donc avoir une fonction qui contient du code procédural, mais vous pouvez la faire circuler tout comme les langages fonctionnels.

Il en va de même pour la POO. Un langage comme Java ne vous permet pas d'écrire des procédures / fonctions en dehors d'une classe. La seule façon de passer une fonction est de l'envelopper dans un objet qui implémente cette fonction, puis de le passer.

En Python, vous n'avez pas cette restriction.


Je pense que vous vouliez dire "ces paradigmes ne doivent pas être mutuellement exclusifs". Les 3 d'entre eux sont orthogonaux en ce que vous pouvez idéalement en utiliser un, 2 ou 3 dans un seul programme (si votre langue le permet).
Joe Pineda

Oui, je suppose que mutuellement exclusif est un meilleur terme pour cela! merci
hasen

14

Pour l'interface graphique, je dirais que le paradigme orienté objet est très bien adapté. La fenêtre est un objet, les zones de texte sont des objets et le bouton OK en est un également. D'un autre côté, des choses comme le traitement des chaînes peuvent être effectuées avec beaucoup moins de frais généraux et donc plus simples avec un paradigme procédural simple.

Je ne pense pas que ce soit une question de langue non plus. Vous pouvez écrire des informations fonctionnelles, procédurales ou orientées objet dans presque tous les langages populaires, bien que cela puisse être un effort supplémentaire dans certains.


17
Tenté de voter pour avoir perpétué l'idée fausse selon laquelle "widget Object = GUI", mais je m'abstiendrai. La POO fonctionne aussi bien pour représenter des concepts abstraits, tels que "UserAccount" ou "PendingSale", que pour les éléments d'interface visibles comme "Window" et "Button".
Dave Sherohman

5
J'ai écrit qu'une fenêtre peut être un objet. Comment tirez-vous la conclusion que chaque objet est une fenêtre à partir de là? C'était juste un exemple. Bien entendu, la POO peut également être utilisée pour modéliser des entités abstraites et leur relation. Quoi qu'il en soit, merci de ne pas voter en aval. Je n'ai pas beaucoup de points de toute façon: D
panschk

6
-1. La POO n'a rien à voir avec les interfaces graphiques. Idéalement, la meilleure méthode pour concevoir un guis est d'utiliser un fichier texte externe (par exemple HTML). Alors que des choses comme le traitement de chaînes sont en réalité bien mieux faites avec des objets. (pensez aux cordes en do) !!
hasen

1
Je ne sais pas, j'ai peut-être l'habitude de programmer avec des objets pour le réaliser. Mais comment feriez-vous des choses interactives comme changer la valeur dans TextBox X lorsque la valeur de TextBox Y a été modifiée sans utiliser d'objets? D'accord, vous pouvez simplement utiliser des variables globales pour tout ...
panschk

1
Le traitement des chaînes est incroyablement fait en perl (100 fois mieux qu'en Java, C ++ ou C #) mais la fonctionnalité de chaîne du langage n'est absolument PAS orientée objet. La gestion des chaînes de C était terrible, mais alors C n'est pas le seul langage procédural (ni le meilleur).
Joe Pineda

6

Pour répondre à votre question, nous avons besoin de deux éléments:

  1. Compréhension des caractéristiques des différents styles / modèles d'architecture.
  2. Compréhension des caractéristiques des différents paradigmes de programmation.

Une liste des styles / modèles d'architecture logicielle est présentée dans l' article sur l' architecture logicielle sur Wikipeida. Et vous pouvez les rechercher facilement sur le Web.

En bref et général, la procédure est bonne pour un modèle qui suit une procédure, la POO est bonne pour la conception et la fonctionnalité est bonne pour la programmation de haut niveau.

Je pense que vous devriez essayer de lire l'histoire de chaque paradigme et voir pourquoi les gens le créent et vous pouvez les comprendre facilement.

Après les avoir compris, vous pouvez lier les éléments des styles / modèles d'architecture aux paradigmes de programmation.


2

Je pense qu'ils ne sont souvent pas «contre», mais vous pouvez les combiner. Je pense aussi que souvent, les mots que vous mentionnez ne sont que des mots à la mode. Il y a peu de gens qui savent réellement ce que signifie "orienté objet", même s'ils en sont les évangélistes les plus féroces.


1

Un de mes amis écrit une application graphique en utilisant NVIDIA CUDA . L'application s'intègre très bien avec le paradigme OOP et le problème peut être décomposé en modules de manière ordonnée. Cependant, pour utiliser CUDA, vous devez utiliser C, qui ne prend pas en charge l' héritage . Par conséquent, vous devez être intelligent.

a) Vous concevez un système intelligent qui imitera l'héritage dans une certaine mesure. Ça peut être fait!

i) Vous pouvez utiliser un système de hook , qui attend de chaque enfant C du parent P qu'il ait un certain remplacement pour la fonction F. Vous pouvez demander aux enfants d'enregistrer leurs remplacements, qui seront stockés et appelés en cas de besoin.

ii) Vous pouvez utiliser struct fonction d' alignement de la mémoire pour convertir les enfants en parents.

Cela peut être soigné, mais il n'est pas facile de trouver une solution fiable et pérenne. Vous passerez beaucoup de temps à concevoir le système et rien ne garantit que vous ne rencontrerez pas de problèmes à mi-chemin du projet. Exécution en de l'héritage multiple est encore plus difficile, voire presque impossible.

b) Vous pouvez utiliser une politique de dénomination cohérente et utiliser l' approche diviser pour régner pour créer un programme. Il n'aura aucun héritage mais comme vos fonctions sont petites, faciles à comprendre et formatées de manière cohérente, vous n'en avez pas besoin. La quantité de code que vous devez écrire augmente, il est très difficile de rester concentré et de ne pas succomber à des solutions faciles (hacks). Cependant, cette méthode de codage ninja est la méthode de codage C. Rester en équilibre entre la liberté de bas niveau et l'écriture d'un bon code. Un bon moyen d'y parvenir est d'écrire des prototypes en utilisant un langage fonctionnel. Par exemple, Haskell est extrêmement bon pour les algorithmes de prototypage.

J'ai tendance à m'approcher b. J'ai écrit une solution possible en utilisant l'approche a, et je vais être honnête, cela ne semblait pas naturel d'utiliser ce code.


Les premiers copmpilers c ++ n'étaient rien de plus que des pré-processeurs qui généraient du code C. En tant que tel, TOUTES les fonctionnalités de c ++, y compris l'héritage multiple, peuvent être implémentées en utilisant C. idée invalide).
Chris Becke

2
@Chris Becke, votre réponse est trop philosophique. D'une part, C a plusieurs normes (au fil des ans), à peine aucune d'entre elles complètement adoptée par les compilateurs C et encore moins c ++. Dire que C ++ est un sur-ensemble de C car il utilise la syntaxe C ne signifie pas grand-chose car vous ne pouvez même pas écrire de code pour un compilateur C qui compile dans un autre compilateur C sans effort significatif. De plus, il y a des fonctionnalités de langage (systèmes de type, support OOD) offertes dans d'autres langues qui seraient impossibles à implémenter en C sans utiliser C pour concevoir un nouveau langage (c'est exactement pourquoi il y a de 'nouveaux langages')
Sprague

Tu sais. Je ne vois plus du tout la pertinence de mon commentaire sur ce post. : P
Chris Becke

Cuda prend en charge C ++ depuis un certain temps maintenant.
Aryeh Leib Taurog
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.