web-dev-qa-db-fra.com

La programmation procédurale présente-t-elle des avantages par rapport à la POO?

[Edit:] Plus tôt, j’avais posé cette question sous la forme d’une question peut-être mal formulée sur le moment où utiliser OOP par rapport à l’utilisation de la programmation procédurale - certaines réponses impliquaient que je demandais de l’aide pour comprendre OOP. Au contraire, j’ai beaucoup utilisé OOP mais je veux savoir quand utiliser une approche procédurale. À en juger par les réponses, j’en déduis qu’il existe un consensus assez fort sur le fait que OOP est généralement une meilleure approche globale, mais qu’un langage procédural doit être utilisé si la OOP architecture n'offrent aucun avantage en matière de réutilisation à long terme.

Cependant, mon expérience en tant que programmeur Java a été différente. J'ai vu un programme Java massif que j'ai architecturé réécrit par un gourou de Perl en 1/10 du code que j'avais écrit et apparemment aussi robuste que mon modèle de OOP perfection. Mon architecture a vu beaucoup de réutilisation et pourtant une approche procédurale plus concise avait produit une solution supérieure.

Alors, au risque de me répéter, je me demande dans quelles situations devrais-je choisir une approche procédurale par rapport à une approche orientée objet. Comment identifieriez-vous à l’avance une situation dans laquelle une architectureOOP risque d’être trop lourde et une approche procédurale plus concise et efficace?.

Quelqu'un peut-il suggérer des exemples de ces scénarios?

Quel est un bon moyen d'identifier à l'avance un projet qui serait mieux servi par une approche de programmation procédurale?

35
Patrick O Connell

Je suggérerais d'utiliser l'approche la plus concise et normalisée que vous pouvez trouver pour tout problème donné. Votre collègue qui a utilisé Perl a démontré qu'un bon développeur connaissant bien un outil donné pouvait obtenir d'excellents résultats, quelle que soit la méthodologie utilisée. Plutôt que de comparer vos projets Java versus Perl comme un bon exemple du débat procédure-contre-OOP, je souhaiterais une confrontation entre Perl et un langage aussi concis que Ruby, qui présente également les avantages suivants: de l'orientation de l'objet. Maintenant, c'est quelque chose que j'aimerais voir. Je pense que Ruby viendrait en tête mais je ne suis pas intéressé à provoquer une guerre des flammes de langage ici - je veux seulement dire que vous choisissez l'outil approprié pour le travail - quelle que soit l'approche qui permet d'accomplir la tâche de la manière la plus efficace et la plus robuste manière possible. Java est peut-être robuste en raison de son orientation objet, mais comme vous et votre collègue, ainsi que de nombreux autres convertis en langages dynamiques tels que Ruby et Python, trouvez qu'il existe de nos jours des solutions beaucoup plus efficaces, qu'elles soient procédurales ou non orientées processus.

12
Serx

J'aime Glass ' les règles de 3 en matière de réutilisation (ce qui semble être ce qui vous intéresse).

1) Il est 3 fois plus difficile de construire des composants réutilisables que des composants à usage unique
2) Un composant réutilisable doit être testé dans trois applications différentes avant d'être suffisamment général pour être accepté dans une bibliothèque de réutilisation.

De cela, je pense que vous pouvez extrapoler ces corollaires

a) Si vous n'avez pas le budget trois fois plus de temps qu'il vous faudrait pour créer un composant à usage unique, peut-être devriez-vous vous retenir de le réutiliser. (En supposant que difficulté = temps)
b) Si vous n’avez pas trois endroits où vous utiliseriez le composant que vous construisez, vous devriez peut-être attendre pour construire le composant réutilisable.

Je pense toujours que OOP est utile pour construire le composant à usage unique, car vous pouvez toujours le reformater pour le réutiliser ultérieurement. (Vous pouvez également refactoriser de PP à OOP mais je pense que OOP présente suffisamment d'avantages en termes d'organisation et d'encapsulation pour commencer par là)

43
Jason Punyon

Vous avez vous-même répondu à cette question: les grands projets ont simplement besoin de OOP pour éviter de devenir trop compliqués.

De mon point de vue, le plus gros avantage de OOP est l'organisation du code. Cela inclut les principes de DRY et de l'encapsulation.

14
mafu

La réutilisabilité (ou son absence) n'est liée à aucun paradigme de programmation spécifique. Utilisez une programmation orientée objet, procédurale, fonctionnelle ou toute autre programmation selon vos besoins. L'organisation et la réutilisabilité proviennent de ce que vous faites, pas de l'outil.

14
Joonas Pulakka

Ceux qui soutiennent religieusement OOP ne disposent d'aucun fait pour justifier leur soutien, comme nous le voyons également dans ces commentaires. Ils sont formés (ou blanchis) dans les universités pour utiliser et féliciter OOP et OOP et c’est pourquoi ils la soutiennent si aveuglément. Ont-ils réellement travaillé dans PP? Hormis la protection du code contre les programmeurs négligents dans un environnement d'équipe, OOP n'offre pas grand chose. Travaillant personnellement à la fois dans PP et OOP pendant des années, j'estime que PP est simple, simple et plus efficace, et je suis d'accord avec les sages suivants femmes:

(Référence: http://en.wikipedia.org/wiki/Object-oriented_programming ):

Un certain nombre de chercheurs et de programmeurs bien connus ont critiqué la POO. Voici une liste incomplète:

  • Luca Cardelli a écrit un article intitulé « Mauvaises propriétés d’ingénierie des langues orientées objet ».

  • Richard Stallman écrivait en 1995: «Ajouter OOP à Emacs n'est pas clairement une amélioration. J'ai utilisé OOP lorsque je travaillais sur les systèmes de fenêtres LISP, et je ne partage pas le point de vue habituel selon lequel il s'agit d'une méthode de programmation supérieure. "

  • Une étude de Potok et al. n'a montré aucune différence significative de productivité entre OOP et approches procédurales.

  • Christopher J. Date a déclaré que la comparaison critique de OOP avec d'autres technologies, en particulier relationnelles, est difficile en raison de l'absence d'une définition convenue et rigoureuse de la POO. Une base théorique sur OOP est proposée, qui utilise OOP comme une sorte de système de types personnalisable prenant en charge le SGBDR.

  • Alexander Stepanov a suggéré que OOP fournit un point de vue mathématiquement limité et l'a qualifié de "presque autant de canular que d'intelligence artificielle" (faisant éventuellement référence aux projets d'intelligence artificielle et au marketing des années 1980 parfois considérés comme trop zélés en rétrospective).

  • Paul Graham a suggéré que le but deOOP soit d'agir comme un "mécanisme de rassemblement" qui empêche les programmeurs médiocres des organisations médiocres de "faire trop de dégâts". Cela se fait au détriment de ralentir les programmeurs productifs qui savent comment utiliser des techniques plus puissantes et plus compactes.

  • Joe Armstrong, le principal inventeur d’Erlang, aurait déclaré: «Le problème avec les langages orientés objet est qu’ils ont tout cet environnement implicite qu’ils portent avec eux. Vous vouliez une banane, mais vous avez eu un gorille tenant la banane et toute la jungle. ”

  • Richard Mansfield, auteur et ancien rédacteur en chef de COMPUTE! magazine, déclare que «comme d’innombrables autres modes à la mode intellectuelle (« pertinence », communisme,« modernisme », etc., l’histoire en est jonchée), OOP sera avec nous jusqu’à ce que la réalité s’affirme finalement lui-même. Toutefois, compte tenu de la manière dont OOP envahit actuellement les universités et les lieux de travail, OOP pourrait bien se révéler être une illusion durable. Des générations entières de programmeurs endoctrinés continuent de sortir de l’académie, attachées à OOP et rien que OOP pour le reste de leur vie. "Et est également cité comme disant" OOP est à écrire un programme, c’est ce que la sécurité dans un aéroport implique de voler ».

8
Zeeshan A Zakaria

Je pense que le principe DRY (ne vous répétez pas) associé à un peu d'agilité est une bonne approche. Construisez votre programme de manière incrémentielle en commençant par la méthode la plus simple qui fonctionne, puis ajoutez des fonctionnalités une par une et re-factorisez votre code si nécessaire.

Si vous vous retrouvez à écrire encore et encore les mêmes lignes de code - peut-être avec des données différentes - il est temps de penser à des abstractions qui peuvent aider à séparer les éléments qui changent des éléments qui restent identiques.

Créez des tests unitaires approfondis pour chaque itération afin de pouvoir les reformater en toute confiance.

C'est une erreur de passer trop de temps à essayer de prévoir quelles parties de votre code doivent être réutilisables. Cela deviendra bientôt évident dès que le système commencera à prendre de l'ampleur.

Pour les projets plus importants comportant plusieurs équipes de développement simultanées, vous devez disposer d'une sorte de plan architectural pour guider le développement, mais si vous travaillez seul ou en petite équipe coopérative, l'architecture émergera naturellement si vous vous en tenez à la DRY principe.

Un autre avantage de cette approche est que quoi que vous fassiez est basé sur une expérience du monde réel. Mon analogie préférée - il faut jouer avec les briques avant de pouvoir imaginer comment le bâtiment pourrait être construit.

6
Noel Walters

Si le projet est si petit qu'il serait contenu dans une classe et ne sera pas utilisé pendant très longtemps, je considérerais d'utiliser des fonctions. Alternativement, si la langue que vous utilisez ne prend pas en charge OO (par exemple, c).

4
Nick Van Brunt

Je pense que vous devriez utiliser un style procédural lorsque vous avez un problème très bien spécifié , la spécification ne changera pas et que vous voulez un très rapide programme en cours pour cela. Dans ce cas, vous pouvez échanger la maintenabilité contre les performances.

C'est généralement le cas lorsque vous écrivez un moteur de jeu ou un programme de simulation scientifique . Si votre programme calcule quelque chose de plus de millions de fois par seconde, il devrait être optimisé à la limite.

Vous pouvez utiliser des algorithmes très efficaces, mais ce ne sera pas assez rapide avant d'optimiser l'utilisation du cache. Cela peut être un gros gain de performance que vos données soient mises en cache. Cela signifie que le processeur n'a pas besoin d'extraire des octets dans la RAM, il les connaît. Pour ce faire, vous devriez essayer de stocker vos données les unes à côté des autres, votre exécutable et votre taille de données devraient être minimes, et essayez d'utiliser le moins de pointeurs possible (utilisez des tableaux de taille fixe globaux statiques, dans la mesure de vos moyens).

Si vous utilisez des pointeurs, vous sautez en permanence dans la mémoire et votre processeur doit recharger le cache à chaque fois. Le code OOP est plein de pointeurs: chaque objet est stocké par son adresse mémoire. Vous appelez new partout, ce qui répartit vos objets dans toute la mémoire, ce qui rend l'optimisation du cache presque impossible (à moins que vous ne disposiez d'un allocateur ou d'un garbage collector qui garde les choses proches les unes des autres). Vous appelez des rappels et des fonctions virtuelles. Le compilateur ne peut généralement pas intégrer les fonctions virtuelles et un appel de fonction virtuelle est relativement lent (sautez vers le VMT, obtenez l'adresse de la fonction virtuelle, appelez-la [cela implique de pousser les paramètres et les variables locales sur la pile, d'exécuter la fonction puis tout éclater]). Cela compte beaucoup quand vous avez une boucle allant de 0 à 1000000 25 fois par seconde. En utilisant un style procédural, il n'y a pas de fonction virtuelle et l'optimizar peut tout intégrer dans ces boucles dynamiques.

4
Calmarius

Les deux concepts ne sont pas mutuellement exclusifs, il est très probable que vous utilisiez PP conjointement avec OOP, je ne vois pas comment les séparer.

3
Otávio Décio

Je pense que la pertinence de OOP dépend plus du sujet dans lequel vous travaillez que de la taille du projet. Il existe certains domaines (CAO, modélisation de simulation, etc.) où OOP correspond naturellement aux concepts impliqués. Cependant, il y a beaucoup d'autres domaines où la cartographie finit par être maladroite et incongrue. Beaucoup de gens qui utilisent OOP pour tout semblent passer beaucoup de temps à essayer de fourrer des piquets carrés dans des trous ronds.

La programmation orientée procédure, la programmation fonctionnelle, etc. font office de POO. Regardez le problème que vous essayez de résoudre, puis choisissez un paradigme de programmation vous permettant d'écrire le programme le plus simple possible pour le résoudre.

3
Chris Upchurch

Une partie de votre réponse dépend de la langue que vous utilisez. Je sais qu'en Python, il est assez simple de déplacer un code de procédure dans une classe ou un objet plus formel.

Une de mes heuristiques est basée sur l'état de la situation. Si la procédure pollue l'espace de noms ou risque d'affecter l'état global (de manière incorrecte ou imprévisible), il est probablement judicieux d'encapsuler cette fonction dans un objet ou une classe.

2
Gregg Lind

Les programmes procéduraux peuvent être plus simples pour un certain type de programme. Généralement, il s’agit de programmes courts ressemblant à des scripts.

2
Jason Baker

Considérez ce scénario: Votre code n'est pas OO. Vous avez des structures de données et de nombreuses fonctions dans votre programme qui agissent sur les structures de données. Chaque fonction prend une structure de données en tant que paramètre et agit différemment selon le champ "type_données" de la structure de données.

Si tout fonctionne et ne va pas être changé, qui se soucie de savoir si c'est OO ou pas? Ça marche. C'est fait. Si vous pouvez arriver à ce point plus rapidement en écrivant de procédure, alors peut-être que c'est la voie à suivre.

Mais êtes-vous sûr que cela ne va pas changer? Disons que vous êtes susceptible d'ajouter de nouveaux types de structures de données. Chaque fois que vous ajoutez un nouveau type de structure de données sur lequel vous souhaitez que ces fonctions soient opérées, vous devez vous assurer de trouver et de modifier chacune de ces fonctions afin d'ajouter un nouveau cas "else if" afin de rechercher et d'ajouter le comportement souhaité. affecter le nouveau type de structure de données. La douleur de ceci augmente avec la taille et la complexité du programme. Plus cela est probable, mieux vous utiliserez l'approche OO.

Et - êtes-vous sûr que cela fonctionne sans bugs? Une logique de commutation plus complexe crée plus de complexité lors du test de chaque unité de code. Avec les appels de méthodes polymorphes, le langage gère la logique de commutation pour vous et chaque méthode peut être plus simple et plus simple à tester.

2
Anon

Un des objectifs de OOP était de faciliter la réutilisation, mais ce n’est pas le seul objectif. Les motifs de conception sont la clé pour apprendre à utiliser efficacement les objets.

Nous sommes tous habitués à l'idée d'algorithmes qui nous indiquent comment combiner différentes procédures et structures de données pour effectuer des tâches courantes. Inversement, consultez Modèles de conception du groupe de quatre pour trouver des idées sur la manière de combiner des objets pour effectuer des tâches courantes.

Avant d’apprendre sur les motifs de conception, je ne savais pas trop comment utiliser efficacement des objets autrement que comme super-structure.

Rappelez-vous que la mise en œuvre d'interfaces est tout aussi importante, sinon plus, que l'héritage. À l'époque, C++ était un exemple de programmation orientée objet et l'utilisation des interfaces est masquée par rapport à l'héritage (fonctions virtuelles, etc.). C++ Legacy signifiait que l’accent était mis davantage sur la réutilisation du comportement dans les divers tutoriels et aperçus généraux. Depuis lors, Java, C # et d’autres langages ont fait évoluer l’interface.

Les interfaces sont idéales pour définir précisément comment deux objets interagissent avec chacun. Il ne s'agit pas de réutiliser le comportement. Il se trouve que la plupart de nos logiciels traitent de l’interaction des différentes parties. Donc, utiliser une interface procure un gain de productivité bien plus important que d'essayer de créer des composants réutilisables.

N'oubliez pas que, comme beaucoup d'autres idées de programmation, les objets sont un outil. Vous devrez utiliser votre meilleur jugement pour évaluer leur efficacité pour votre projet. Pour mon logiciel de CAO/FAO pour les machines à couper les métaux, il y a d'importantes fonctions mathématiques qui ne sont pas placées dans les objets car elles n'ont aucune raison d'être dans les objets. Au lieu de cela, ils sont exposés depuis la bibliothèque et utilisés par l'objet qui en a besoin. Ensuite, certaines fonctions mathématiques ont été orientées objet, leur structure conduisant naturellement à cette configuration. (Prendre une liste de points et la transformer en plusieurs types de chemins de coupe). Encore une fois utilisez votre meilleur jugement.

2
RS Conley

"Le problème avec les langages orientés objet, c'est qu'ils ont tout cet environnement implicite qu'ils transportent avec eux. Vous vouliez une banane, mais ce que vous avez c'est un gorille tenant la banane et la jungle entière." - Joe Armstrong

Tu veux la jungle?

1
Jakob

Si vous "pensez" lorsque vous programmez, alors je ne suis pas sûr qu'il soit logique de demander "quand devrais-je revenir à la programmation procédurale?" Cela revient à demander aux programmeurs Java ce qu’ils ne peuvent pas faire aussi car Java requiert des classes. (Idem langages .NET).

Si vous devez faire un effort pour dépasser vos réflexions procédurales, alors je vous conseillerais de demander comment vous pouvez surmonter cela (si vous le souhaitez); sinon restez avec procédural. Si vous faites autant d'efforts pour passer en mode POO, votre code OOP ne fonctionnera probablement pas très bien de toute façon (jusqu'à ce que vous alliez plus loin dans la courbe d'apprentissage.)

1
dkretz

Je crois que Grady Booch a dit une fois que vous commencez vraiment à bénéficier beaucoup de OOP à plus de 10000 lignes de code.

Cependant, j'irais toujours de la même manière. Même pour 200 lignes. C'est une approche supérieure à long terme et les frais généraux ne sont qu'une excuse surestimée. Toutes les grandes choses commencent modestement.

1
Ivan Krechetov

Je commence toujours à concevoir de haut en bas et dans les parties supérieures, il est beaucoup plus facile de penser en termes deOOP. Mais lorsque vient le temps de coder certaines petites pièces spécifiques, vous êtes beaucoup plus productif avec une simple programmation de procédures. OOP est cool dans la conception et la mise en forme du projet, de sorte que le paradigme divide-et-impera puisse être appliqué. Mais vous ne pouvez pas l'appliquer dans tous les aspects de votre code, comme s'il s'agissait d'une religion :)

1
Emiliano

Mes deux centimes...

Avantages de la programmation procédurale

  • Conception simple (preuve de concept rapide, bataille avec des exigences extrêmement dynamiques)
  • Communications simples entre projets
  • Naturel quand l'ordre temporel compte
  • Moins de frais généraux lors de l'exécution

Plus le code procédural est bon, plus il est proche de fonctionnel. Et les avantages de FP sont bien connus.

0
SerG

Vous pouvez écrire un mauvais logiciel dans les deux concepts. Néanmoins, les logiciels complexes sont beaucoup plus faciles à écrire, à comprendre et à maintenir dans les langues OO que dans les procédures. J'ai écrit des applications hautement complexes ERP en langage procédural (Oracle PL/SQL), puis suis passé à OOP (C #). C'était et c'est toujours une bouffée d'air frais.

0
Milivoj Milani

La plupart des études ont montré que le code OO est plus concis que le code procédural. Si vous examinez les projets qui réécrivent le code C existant en C++ (ce que je ne conseille pas nécessairement, BTW), vous constaterez généralement des réductions de la taille du code comprises entre 50 et 75%.

La réponse est donc: utilisez toujours OO!

0
anon

IMHO, les avantages à long terme de OOP l'emportent sur le gain de temps à court terme.

Comme indiqué par AZ, utiliser OOP de manière procédurale (ce que je fais assez souvent) est une bonne solution (pour les projets plus petits). Plus le projet est volumineux, plus vous devriez employer OOP.

0
bitstream