web-dev-qa-db-fra.com

OOP vs programmation fonctionnelle vs procédure

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

Des exemples d'architecture appréciés!

Tous sont 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 exploitent.

Dans un style orienté objet, les données ont tendance à comporter un ensemble de fonctions.

Dans un style fonctionnel, les données et les fonctions tendent à avoir davantage en commun (comme dans LISP et Scheme) tout en offrant plus de flexibilité quant à la manière dont les fonctions sont réellement utilisées. Les algorithmes ont également tendance à être définis en termes de récursivité et de composition plutôt que de boucles et d'itérations.

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 (même si cela est fortement déconseillé), et même dans un langage procédural tel que 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 de vos 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 logique de les composer en tant qu’objets si c’est le paradigme natif de votre langage - ou bien, cela pourrait tout aussi bien s’écrire comme une abstraction fonctionnelle de monades, est le paradigme natif de langues comme Haskell ou ML.

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

121
greyfade

Je pense que les bibliothèques, outils, exemples et communautés disponibles vont totalement à l'encontre du paradigme actuel. Par exemple, ML (ou autre) pourrait être la programmation ultime tout usage langage mais si vous ne pouvez pas obtenir de bonnes bibliothèques pour ce que vous faites, vous êtes foutus.

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

Auparavant, les bibliothèques standard de différentes langues étaient assez petites et facilement répliquées - C, C++, Assembler, ML, LISP, etc., étaient livrées avec les bases, mais avaient tendance à se dégrader quand il s'agissait de normaliser les choses comme les communications réseau, le cryptage, les graphiques, les formats de fichiers de données (y compris XML), même les structures de données de base telles que les arbres équilibrés et les tables de hachage ont été omis!

Les langages modernes tels que Python, PHP, Ruby et Java disposent désormais d'une bibliothèque standard bien plus convenable et disposent de nombreuses bonnes bibliothèques tierces que vous pouvez facilement utiliser, notamment grâce à l'adoption d'espaces de noms pour conserver les bibliothèques. de collision entre eux, et la récupération de place pour normaliser les schémas de gestion de la mémoire des bibliothèques.

22
Dobes

Ces paradigmes ne doivent pas nécessairement s’exclure mutuellement. Si vous regardez python, il supporte 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, dans les langages fonctionnels (du moins en Haskell, le seul que j’ai étudié), il n’ya pas d’énoncé! les fonctions ne sont autorisées qu'une seule expression à l'intérieur de celles-ci !! 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 quelques lignes de code.

Dans un langage procédural tel que le langage C, la seule manière de transmettre des fonctions consiste à utiliser des pointeurs de fonction, ce qui seul ne permet pas 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 contenant du code de procédure, mais vous pouvez la transmettre comme un langage fonctionnel.

Même chose pour la programmation orientée objet. Un langage comme Java ne vous permet pas d'écrire des procédures/fonctions en dehors d'une classe. La seule façon de transmettre une fonction consiste à l'envelopper dans un objet qui l'implémente, puis à le transmettre.

En Python, vous n'avez pas cette restriction.

20
hasen

Pour l'interface graphique, je dirais que le paradigme orienté objet convient parfaitement. La fenêtre est un objet, les zones de texte sont des objets et le bouton OK en est un aussi. D'autre part, des tâches telles que String Processing peuvent être effectuées avec beaucoup moins de frais généraux et donc plus simples avec un simple paradigme procédural.

Je ne pense pas que ce soit une question de langue non plus. Vous pouvez écrire de manière fonctionnelle, procédurale ou orientée objet dans presque tous les langages populaires, bien que cela puisse demander un effort supplémentaire.

14
panschk

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 affichée sur le article sur l'architecture logicielle sur Wikipeida. Et vous pouvez facilement les rechercher sur le Web.

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

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

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

6
GabrielC

Je pense qu'ils ne sont souvent pas "opposés", mais vous pouvez les combiner. Je pense aussi que souvent, les mots que vous mentionnez ne sont que des mots à la mode. Peu de gens savent réellement ce que "orienté objet" signifie, même s'ils en sont les plus fervents évangélistes.

2
Svante

Un de mes amis est en train d’écrire une application graphique en utilisant NVIDIA CUDA . L’application s’intègre très bien dans le paradigme OOP et le problème peut être décomposé proprement en modules. Cependant, pour utiliser CUDA, vous devez utiliser C, qui ne supporte pas 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 s'attend à ce que chaque enfant C du parent P ait un certain remplacement pour la fonction F. Vous pouvez faire en sorte que les enfants enregistrent leurs remplacements, qui seront stockés et appelés si nécessaire.

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

Cela peut être intéressant, mais il n’est pas facile de trouver une solution fiable et à l’avenir. 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. L'implémentation héritage multiple est encore plus difficile, voire presque impossible.

b) Vous pouvez utiliser une politique de dénomination cohérente et utiliser la méthode diviser pour régner pour créer un programme. Il n'aura pas d'héritage, mais comme vos fonctions sont petites, faciles à comprendre et systématiquement formatées, vous n'en avez pas besoin. La quantité de code dont vous avez besoin pour écrire augmente, il est très difficile de rester concentré et de ne pas succomber à des solutions faciles (bidouilles). 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 à approcher b. J'ai écrit une solution possible en utilisant l'approche a, et je vais être honnête, l'utilisation de ce code ne me semblait pas naturelle.

1
sneg