Ce sera une question très peu technique et douce et je ne suis pas sûr que ce soit la bonne plate-forme. Mais je suis un étudiant débutant en CS, alors j'espère que vous allez le tolérer.
Au cours du premier semestre, nous avons découvert les concepts de la programmation orientée objet tels que l'encapsulation, le masquage des données, la modularité, l'héritage, etc. via Java et UML. (Java est mon premier langage de programmation)
Si je comprends bien, la programmation orientée objet est un moyen de gérer la complexité des logiciels. Mais ses principes ne sont ni nouveaux ni uniques, ils sont en un sens universels pour tous les domaines de l'ingénierie.
Par exemple, une voiture est une structure très complexe dont la complexité est gérée par une hiérarchie de composants modulaires et encapsulés avec des comportements et des interfaces bien définis.
Mais je ne comprends pas la raison de l’introduction d’un nouveau paradigme de programmation. Je pense que tous les principes utilisés pour gérer la complexité peuvent être réalisés par les langages de programmation procéduraux. Par exemple, pour la modularité, nous pouvons simplement diviser le programme en plusieurs petits programmes qui exécutent des tâches bien définies dont le code est contenu dans des fichiers séparés. Ces programmes interagiraient les uns avec les autres grâce à leurs entrées et sorties bien définies. Les fichiers peuvent être protégés (cryptés?) Pour réaliser l’encapsulation. Pour la réutilisation du code, nous pouvons simplement appeler ces fichiers quand ils sont nécessaires dans de nouveaux programmes. Cela ne reflète-t-il pas tout ce qu'est la POO ou manque-t-il quelque chose de très évident?
Je ne demande pas de preuve que la POO gère la complexité. À mon avis, c'est le cas. Mais je pense que tous les principes utilisés pour gérer la complexité, tels que la modularité, l’encapsulation, la dissimulation de données, etc., peuvent être très facilement mis en œuvre par les langages procéduraux. Alors, pourquoi vraiment OOP si nous pouvons gérer la complexité sans elle?
la source
Réponses:
Laissez-moi essayer avec une réponse très basse théorie :)
Ce que vous demandez réellement, c'est: Pourquoi inclure la prise en charge de l'Object Object Orientation (OO) directement dans le langage quand des langages procéduraux peuvent être utilisés pour concevoir et écrire du code OO?
Et la réponse est: avoir un standard pour la façon dont OO est exprimé dans le code source afin de ne pas vous retrouver avec 22 implémentations différentes pour la même abstraction.
Par exemple, disons que je crée un
MagicButton
et unMagicSlider
qui peut être utilisé dans un système d'interface utilisateur. Il me faut un moyen de regrouper les méthodes utilisables avec MagicButton, celles qui ne peuvent être utilisées qu'avec MagicSlider et les méthodes pouvant être utilisées par les deux. Ces objets partagent certaines méthodes car ils sont tous deux des objets gui magiques.Je peux faire le regroupement en nommant des fonctions de manière spéciale
MagicSlider_DoSomething ...
, en incluant les méthodes dans des fichiers spécifiques nommés de manière spécialeMagicSliderMethods.XXX
, ou je pourrais trouver un autre moyen spécial de faire la même chose. S'il n'y a pas de moyen standard dans la langue de le faire, je le ferai différemment de vous et de quiconque. Cela rend le partage de code beaucoup plus difficile.Oui, l'envoi tardif (méthodes virtuelles dans les langages OO) peut être implémenté dans les langages procéduraux, mais il existe de nombreuses façons de l'implémenter. En fonction de l'auteur du code, vous obtiendrez différentes implémentations d'OO dans le même programme.
Pensez au mauvais développeur de maintenance. Cette personne doit gérer différentes abstractions d'objet et différentes manières d'appeler des méthodes virtuelles en fonction de l'auteur du code d'origine.
De plus: le fait d'avoir les abstractions dans le langage permet aux éditeurs de code avancés tels qu'Eclipse de faire beaucoup d'analyses statiques sur le code. Par exemple, Eclipse peut proposer une liste de toutes les méthodes pouvant être utilisées sur un objet, ainsi que l'implémentation automatique de "méthodes TODO" vides. Eclispe sait exactement quelles méthodes votre classe doit implémenter en fonction des classes que vous étendez et des interfaces que vous implémentez. Cela serait presque impossible s’il n’existait pas de norme linguistique pour faire de l’OA.
la source
Aucun de ceux-ci ne sont des concepts de POO. Ils existent tous en dehors de OO, indépendamment de OO et beaucoup ont même été inventés avant OO.
Donc, si vous pensez que c'est ça le but de OO, alors votre conclusion est juste: vous pouvez faire tout cela dans des langages procéduraux, car ils n'ont rien à voir avec OO .
Par exemple, l’un des principaux articles sur la modularité concerne les critères à utiliser pour la décomposition de systèmes en modules . Il n'y a aucune mention de OO là-dedans. (Il a été écrit en 1972, alors que OO était encore un créneau obscur, alors qu’il avait déjà plus de dix ans.)
Bien que l’ abstraction de données soit importante pour l’OA, c’est davantage une conséquence de la principale caractéristique de OO (messagerie) qu’elle est déterminante. En outre, il est très important de se rappeler qu’il existe différents types d’abstraction de données. Les deux types d'abstraction de données les plus couramment utilisés aujourd'hui (si nous ignorons "aucune abstraction", qui est probablement encore plus utilisé que les deux autres combinés), sont les types de données abstraits et les objets . Donc, juste en disant « Hiding information », « Encapsulation » et « Data Abstraction », vous avez rien dit sur OO, puisque OO est seulement une forme d'abstraction de données, et les deux sont en fait fondamentalement différentes:
Soit dit en passant, cela signifie qu'en Java, les classes ne sont pas orientées objet. Deux instances de la même classe peuvent accéder à la représentation et à l'implémentation privée de l'autre. Par conséquent, les instances de classes ne sont pas des objets, elles sont en fait des instances ADT. Java
interface
s, cependant, ne fournir abstraction de données orientée objet. Donc, en d'autres termes: seules les instances d'interfaces sont des objets en Java, les instances de classes ne le sont pas.Fondamentalement, pour les types, vous ne pouvez utiliser que des interfaces. Cela signifie que les types de paramètres de méthodes et de constructeurs, les types de méthodes retournés, les types de champs d'instance, les champs statiques et les champs locaux, l'argument d'un
instanceof
opérateur ou d'un opérateur de conversion et les arguments de type d'un constructeur de type générique doivent toujours être des interfaces. Une classe ne peut être utilisée que directement après l'new
opérateur, nulle part ailleurs.Ce que vous décrivez est OO.
C'est en effet une bonne façon de penser à OO. En fait, c'est à peu près exactement ce que les inventeurs originaux d'OO avaient en tête. (Alan Kay est allé un peu plus loin: il a envisagé de nombreux ordinateurs se transmettant des messages via le réseau.) Ce que vous appelez "programme" est généralement appelé "objet" et au lieu de "appel", nous disons habituellement "envoyer un message" ".
L'orientation des objets est entièrement centrée sur la messagerie (également appelée répartition dynamique ). Le terme "orienté objet" a été inventé par Alan Kay, concepteur principal de Smalltalk, et il le définit ainsi :
Décomposons cela:
En ce qui concerne l'implémentation, la messagerie est un appel de procédure à liaison tardive, et si les appels de procédure sont à liaison tardive, vous ne pouvez pas savoir au moment de la conception comment vous allez appeler, vous ne pouvez donc pas émettre d'hypothèses sur la représentation concrète de l'état. Donc, en réalité, il s’agit de messagerie, la liaison tardive est une implémentation de la messagerie et l’encapsulation en est la conséquence.
Il a ensuite précisé que " la grande idée est la" messagerie " " et regrette de l'avoir appelée "orientée objet" au lieu de "orientée message", car le terme "orienté objet" met l'accent sur l'élément sans importance (objets ) et distrait de ce qui est vraiment important (messagerie):
(Bien sûr, aujourd'hui, la plupart des gens ne se concentrent même pas sur des objets mais sur des classes, ce qui est encore plus faux.)
La messagerie est fondamentale pour OO, à la fois en tant que métaphore et en tant que mécanisme.
Si vous envoyez un message à quelqu'un, vous ne savez pas ce qu'il en fait. La seule chose que vous pouvez observer, c'est leur réponse. Vous ne savez pas s'ils ont traité le message eux-mêmes (c'est-à-dire si l'objet a une méthode), s'ils ont transmis le message à quelqu'un d'autre (délégation / proxy), s'ils l'ont même compris. C’est ce que l’encapsulation est, l’objet OO. Vous ne pouvez même pas distinguer un proxy de la réalité, tant qu'il répond à vos attentes.
Un terme plus "moderne" pour "messagerie" est "envoi de méthode dynamique" ou "appel de méthode virtuelle", mais il perd la métaphore et se concentre sur le mécanisme.
Il y a donc deux façons de regarder la définition d'Alan Kay: si vous la regardez seule, vous remarquerez peut-être que la messagerie est essentiellement un appel de procédure à liaison tardive et que la liaison tardive implique une encapsulation, ce qui permet de conclure que # 1 et # 2 sont en fait redondants, et OO est tout au sujet de la liaison tardive.
Cependant, il a plus tard précisé que l’important était la messagerie, et nous pouvons donc la regarder sous un angle différent: la messagerie est en retard. Maintenant, si la messagerie était la seule chose possible, alors le n ° 3 serait trivialement vrai: s'il n'y a qu'une seule chose, et que cette chose est en retard, toutes les choses sont en retard. Et encore une fois, l’encapsulation découle de la messagerie.
Des points similaires sont également présentés dans le document intitulé Comprendre l'abstraction des données, revisité par William R. Cook, ainsi que dans sa proposition de définitions modernes et simplifiées des termes "objet" et "orienté objet" :
Dans Smalltalk-72, il n'y avait même pas d'objets! Il n'y avait que des flux de message qui a obtenu analysables, réécrite et réacheminés. Les premières méthodes sont venues (méthodes standard pour analyser et rediriger les flux de messages), puis les objets (groupes de méthodes qui partagent un état privé). L'héritage est venu beaucoup plus tard, et les classes n'ont été introduites que comme un moyen de supporter l'héritage. Si le groupe de recherche de Kay était déjà au courant des prototypes, ils n'auraient probablement jamais introduit de cours.
Benjamin Pierce, dans Types et langages de programmation, affirme que la caractéristique qui définit l’objet Orientation est la récursion ouverte .
Donc: selon Alan Kay, OO est tout sur la messagerie. Selon William Cook, OO concerne la répartition dynamique des méthodes (ce qui est en réalité la même chose). Selon Benjamin Pierce, OO est une affaire de récursivité ouverte, ce qui signifie essentiellement que les auto-références sont résolues de manière dynamique (ou du moins que c'est une façon de penser), ou, en d'autres termes, la messagerie.
Comme vous pouvez le constater, la personne qui a inventé le terme "OO" a une vision plutôt métaphysique des objets, Cook a une vision plutôt pragmatique et Pierce une vision mathématique très rigoureuse. Mais l’important est que le philosophe, le pragmatiste et le théoricien soient tous d’accord! La messagerie est le seul pilier de OO. Période.
Notez qu'il n'y a aucune mention d'héritage ici! L'héritage n'est pas essentiel pour OO. En général, la plupart des langages OO ont un moyen de réutiliser une implémentation, mais cela ne doit pas nécessairement être un héritage. Cela pourrait aussi être une forme de délégation, par exemple. En fait, le Traité d’Orlando examine la délégation comme une alternative à l’héritage et explique comment les différentes formes de délégation et d’héritage conduisent à différents points de conception dans l’espace de conception des langages orientés objet. (Notez qu'en réalité, même dans les langages qui supportent l'héritage, comme Java, les gens apprennent à l'éviter, ce qui indique encore une fois que ce n'est pas nécessaire pour OO.)
la source
Lorsque vous dites "très facilement", vous faites une déclaration très audacieuse. La façon dont je l'ai lu est: "Je ne vois pas la difficulté, alors ça ne doit pas être très gros." Lorsque vous le formulez ainsi, il devient clair que vous ne demandez pas "pourquoi avons-nous besoin d'OO", mais "pourquoi les difficultés rencontrées par les autres paradigmes de programmation qui ont conduit à l'invention d'OO ne sont-elles pas immédiatement apparentes? "
Une réponse à cette question est que bon nombre de ces difficultés n'existent pas dans les types de programmes sur lesquels vous travaillez. On ne vous demande pas de mettre à jour du code spaghetti vieux de 40 ans. Vous n'essayez pas d'écrire un nouveau gestionnaire d'affichage pour un système d'exploitation. Vous ne déboguez pas d'applications distribuées multithreads.
Pour beaucoup de types de programmes de jouets que nous, les étudiants CS, sommes chargés d’écrire, nous pourrions aussi bien les écrire en BASIC ou les assembler que Java ou Python. En effet, la complexité inhérente des tâches est si faible, il n'y a qu'un seul développeur, il n'y a pas de problèmes d'interopérabilité hérités, les performances importent peu et le code ne sera probablement exécuté que très peu de fois sur une seule machine.
Imaginez que vous preniez un élève conducteur et lui demandiez de se joindre à une rue animée aux heures de pointe, avec une boîte de vitesses manuelle sans synchro, en montant une colline abrupte. Catastrophe. Pourquoi? Ils sont incapables de gérer le niveau de complexité requis pour respecter simultanément toutes les règles requises par la tâche.
Maintenant, imaginez le même élève, le même véhicule, conduisant à une vitesse de marche dans un parking vide. Ils vont bien parce que leur niveau de compétence est adapté à la tâche. Il n'y a pas de pression, peu de risque, et ils peuvent prendre les sous-tâches individuelles de démarrage, embrayage, changement de vitesse, accélération, direction, une à la fois.
Cet étudiant pourrait demander pourquoi nous avons des transmissions automatiques, si un conducteur qualifié peut faire toutes ces choses en même temps? La réponse est qu’un pilote suffisamment qualifié n’a pas besoin d’un système automatique dans des conditions optimales. Mais nous ne sommes pas tous des pilotes professionnels en pleine forme, et nous souhaitons généralement que les concepteurs de la voiture prennent en charge toute cette complexité.
Un programmeur assez expérimenté et discipliné peut en effet créer un système très complexe fonctionnant en C ou en assembleur. Mais nous ne sommes pas tous Linus Torvalds. Nous ne devrions pas non plus être obligés de créer des logiciels utiles.
Je n'ai personnellement aucun intérêt à devoir réinventer toutes les fonctionnalités d'un langage moderne avant même de pouvoir résoudre le problème. Si je peux tirer parti d'un langage qui inclut des solutions à des problèmes déjà résolus, pourquoi ne le ferais-je pas?
Je vais donc retourner votre question et vous demander si les langages fournissent des fonctionnalités pratiques comme l’encapsulation et le polymorphisme, pourquoi ne devrions-nous pas les utiliser?
la source
Ce que vous décrivez n'est pas de la programmation orientée objet, c'est de l'abstraction. L'abstraction est présente dans tous les modèles de conception modernes, même ceux qui ne sont pas la POO. Et la POO est un type d'abstraction très spécifique.
Tout d’abord, il convient de noter qu’il n’existe pas de définition unique de la programmation orientée objet. Il se peut donc que certaines personnes ne soient pas d’accord avec ce que je qualifie de programmation orientée objet.
Deuxièmement, il est important de rappeler que la programmation orientée objet a été inspirée par les modèles de conception traditionnels. Les similitudes avec la conception des voitures ne sont donc pas une coïncidence.
Cependant, voici comment la POO est plus nuancée que ce que vous avez dit:
Encapsulation: il ne s'agit pas simplement d'avoir une interface définie pour un module (c'est-à-dire une abstraction), il s'agit d'interdire l'accès au-delà de cette interface. En Java, accéder à une variable privée est une erreur de compilation, alors que dans la conception de votre voiture, vous pouvez (dans certains cas) utiliser les choses d’une manière différente de l’interface souhaitée.
Héritage: C'est vraiment ce qui rend la POO unique. Une fois que vous avez défini une interface, vous pouvez créer plusieurs choses pour la mettre en œuvre. Vous pouvez le faire de manière hiérarchique, en modifiant des parties spécifiques de leur implémentation, tout en héritant de toutes les parties précédentes, ce qui réduit considérablement la duplication de code.
Si vous pensez en termes de composants encapsulés d'une voiture, il n'y a pas vraiment d'équivalent à ceci. Il n'y a pas moyen pour moi de passer à la vitesse supérieure en passant à une autre vitesse et en modifiant une partie spécifique de sa mise en œuvre. (Au moins, je ne pense pas, je ne sais pas grand chose des voitures).
Polymorphisme : une fois que vous avez défini une interface, il est impossible de distinguer tout élément utilisant cette interface, du point de vue des opérations disponibles, et vous n'avez pas besoin de savoir quelle implémentation est utilisée pour utiliser une interface. C’est là que le sous-typage et le principe de substitution de Liskov deviennent importants.
Couplage : Un aspect clé de la programmation orientée objet est que nous associons étroitement les choses avec les mêmes opérations et que nous étendions les différentes formes qu’elles peuvent avoir. Les données sont regroupées avec des opérations sur ces données. Cela signifie qu'il est très facile d'ajouter une nouvelle forme de données (une nouvelle implémentation), mais qu'il est très difficile d'ajouter une nouvelle opération à une interface (car vous devez mettre à jour chaque classe qui implémente l'interface). Cela contraste avec les types de données algébriques des langages fonctionnels, où il est très facile d’ajouter une nouvelle opération (vous écrivez simplement une fonction qui traite tous les cas), mais difficile d’ajouter une nouvelle variante (car vous devez ajouter une nouvelle cas à toutes vos fonctions).
la source
Cela dépend de la signification du mot "besoin".
Si "besoin" signifie besoin, non, nous n'en avons pas besoin.
Si "besoin" signifie "procure de solides avantages", alors je dirais "Oui", nous le désirons.
Grande image
Les langages OO lient la fonctionnalité aux données.
Vous pouvez éviter cette liaison et écrire des fonctions qui transmettent des valeurs de données.
Mais alors, vous allez probablement vous retrouver avec des constellations de données qui vont ensemble, et vous allez commencer à transmettre des n-uplets, des enregistrements ou des dictionnaires de données.
Et en réalité, tous les appels de méthode sont: des fonctions partielles sur des ensembles de données liés.
Caractéristique par caractéristique
Caractéristiques de la POO:
Cependant, aucune de ces choses ne se produit aussi facilement qu'avec un langage orienté objet avec un support de première classe de ces fonctionnalités.
Références
Il y a beaucoup de critiques de la programmation orientée objet .
Cependant, des études semblent indiquer que la réutilisation de code via la POO améliore la productivité des programmeurs. Cette découverte est controversée et certains chercheurs affirment qu’ils ne peuvent pas reproduire ces gains de productivité compte tenu de certaines contraintes. (la source)
Conclusion
Nous n'avons pas "besoin" de la POO. Mais dans certains cas, l'utilisateur veut la POO.
Je crois comprendre que les programmeurs matures peuvent être assez productifs dans le style orienté objet. Et lorsque les packages ont des objets de base dotés d'interfaces simples et faciles à comprendre, même les nouveaux programmeurs peuvent devenir très productifs rapidement.
la source
J'essaierai d'être bref.
Le principe de base de OO est la combinaison de données et de comportement dans une seule unité organisationnelle (un objet).
C’est ce qui nous permet de contrôler la complexité et c’était un concept assez novateur lorsqu’il est apparu. Comparez cela aux fichiers d'une part (données pures), aux programmes qui les lisent et les traitent d'autre part (logique pure) et à la sortie (encore des données pures).
Une fois que vous avez réuni ce paquet de données et cette logique, en modélisant une entité réelle, vous pouvez commencer à échanger des messages, créer des classes enfants, séparer les données et les comportements privés des données et comportements publics, implémenter un comportement polymorphe, effectuer toute cette magie propre à OO.
Donc, oui, OO est un gros problème. Et non, ce n'est pas juste un tas de vieux trucs avec un nom de fantaisie.
Tout casser, regarder les éléments, puis dire «ah, ben, il n’ya rien que je n’ai jamais vu», c’est ne pas reconnaître l’assemblée qui détient l’innovation. Le résultat est plus que la somme de ses parties.
la source
Il n'y a pas de définition "officielle" de la programmation orientée objet, et des personnes raisonnables ne sont pas d'accord sur ce qui définit réellement la qualité de OO. Certains disent que la messagerie, d'autres le sous-typage, certains l'héritage, d'autres le groupement de données et de comportements. Cela ne veut pas dire que le terme n'a pas de sens, mais simplement que vous ne devriez pas vous perdre dans des querelles sur ce qu'est le vrai OO.
L'encapsulation et la modularité sont des principes de conception plus fondamentaux et devraient être appliqués à tous les paradigmes de programmation. Les partisans de l'OO ne prétendent pas que ces propriétés ne peuvent être obtenues qu'avec de l'OO, mais seulement que l'OO est particulièrement bien adapté à cet objectif. Bien entendu, les partisans d’autres paradigmes comme la programmation fonctionnelle affirment la même chose pour leur paradigme. Dans la pratique, de nombreuses langues réussies sont multi-paradigmes et le langage OO, fonctionnel, etc., doivent être considérés comme des outils plutôt que comme une "solution unique".
C'est vrai, car à la fin, vous pouvez tout faire dans n'importe quel langage de programmation. Cela pourrait être plus facile dans certaines langues que dans d'autres, car toutes les langues ont des forces et des faiblesses différentes.
la source
Quelque chose que les autres réponses n'ont pas mentionné: l'état.
Vous parlez de OO en tant qu'outil de gestion de la complexité . Quelle est la complexité? C'est un terme flou. Nous avons tous ce sens gestalt de ce que cela signifie, mais il est plus difficile de le cerner. Nous pourrions mesurer la complexité cyclomatique, c'est-à-dire le nombre de chemins d'exécution dans le code, mais j'ignore si c'est ce dont nous parlons lorsque nous utilisons OO pour gérer la complexité.
Je pense que nous parlons de la complexité liée à l’état.
Il y a deux idées principales derrière l’ encapsulation . L'un d'eux, la dissimulation de détails de mise en œuvre , est assez bien couvert dans les autres réponses. Mais un autre cache son état d' exécution . Nous ne marchons pas avec les données internes des objets; nous transmettons des messages (ou des méthodes d’appel si vous préférez les détails d’implémentation au concept, comme l'a souligné Jörg Mittag). Pourquoi?
Les gens ont déjà mentionné que c'est parce que vous ne pouvez pas modifier la structure interne de vos données sans modifier le code, mais vous voulez le faire à un endroit (la méthode d'accès) au lieu de 300.
Mais c'est aussi parce que cela rend le code difficile à raisonner : le code de procédure (que ce soit dans un langage de procédure ou simplement écrit dans ce style) aide peu à imposer des restrictions à la mutation d'état. Tout peut changer à tout moment et de n'importe où. Les fonctions / méthodes d’appel peuvent avoir une action fantasmagorique à distance. Le test automatisé est plus difficile, car le succès des tests est déterminé par la valeur des variables non locales largement utilisées / accessibles.
Les deux autres grands paradigmes de programmation (OO et fonctionnel) offrent des solutions intéressantes, mais presque diamétralement opposées, au problème de la complexité liée à l'état. En programmation fonctionnelle, on essaie de l'éviter complètement: les fonctions sont généralement pures, les opérations sur les structures de données renvoient des copies plutôt que de mettre à jour l'original en place, etc.
OO d'autre part offre des outils pour gérer l' état de gestion (au lieu des outils pour l'éviter). Outre les outils au niveau de la langue tels que les modificateurs d'accès (protégé / public / privé), les accesseurs, les régleurs, etc., il existe également un certain nombre de conventions connexes, telles que la loi de Demeter, qui déconseillent de chercher dans des objets pour accéder à d'autres objets. .
Notez que vous n’avez pas besoin que les objets fassent vraiment cela: vous pouvez avoir une fermeture qui contient des données inaccessibles et renvoie une structure de données de fonctions pour la manipuler. Mais n'est-ce pas un objet? Cela ne correspond-il pas à notre conception de ce qu'est un objet, intuitivement? Et si nous avons ce concept, ne vaut-il pas mieux le reformuler dans le langage plutôt que (comme d’autres réponses l’ont dit) en s’appuyant sur une explosion combinatoire d’applications ad-hoc concurrentes?
la source
Non, mais ils peuvent aider dans de nombreuses situations.
J'ai utilisé principalement un seul langage OO pendant des décennies, mais la plupart de mon code est en fait strictement procédural. Cependant, pour tout ce qui implique une interface graphique, j'utilise la vaste bibliothèque de méthodes et d'objets intégrés OO du langage, car elle simplifie énormément mon code.
Par exemple, une application Windows utilisant l'API Windows de bas niveau d'origine pour afficher un formulaire, un bouton et un champ d'édition nécessite beaucoup de code, alors que l'utilisation des bibliothèques d'objets livrées avec Visual Basic ou C # ou Delphi est identique. programme minuscule et trivial. Ainsi, mon code OO est généralement relativement petit et pour l'interface graphique, alors que le code invoqué par ces objets est généralement beaucoup plus volumineux et ne concerne généralement pas OO (bien qu'il puisse varier en fonction du problème que je tente de résoudre).
J'ai vu des programmes OO trop compliqués, basés sur des règles ésotériques compliquées sur la manière dont les objets étaient implémentés, et auraient pu être beaucoup plus simples s'ils avaient été écrits sans les concepts OO. J'ai également vu le contraire: des systèmes complexes qui exigent d'être réimplémentés et simplifiés à l'aide d'objets.
En acquérant de l'expérience, vous constaterez que différentes situations requièrent différents outils et solutions et qu'une même taille ne convient pas à tous.
la source
En tant que personne impliquée dans un très grand projet entièrement écrit en C, je peux certainement dire que la réponse est clairement un "non".
La modularité est importante. Mais la modularité peut être mise en œuvre dans pratiquement n'importe quelle langue décente. Par exemple, C prend en charge la compilation modulaire, les fichiers d’en-tête et les types de structure. Cela suffit pour 99% des cas. Définissez un module pour chaque nouveau type de données abstrait dont vous avez besoin, puis définissez les fonctions à utiliser pour le type de données. Parfois, vous voulez des performances et ces fonctions sont dans le fichier d'en-tête en tant que fonctions en ligne, d'autres fois, vous utiliserez des fonctions standard. Tout est invisible pour l'utilisateur quel chemin est choisi.
Structures supportent la composition. Par exemple, vous pouvez avoir une table de hachage verrouillée composée d'un verrou mutex et d'une table de hachage normale. Ce n'est pas une programmation orientée objet; aucun sous-classement n'est fait. La composition est un outil beaucoup plus ancien que l’idée de la programmation orientée objet.
Dans les 1% des cas où la modularité au niveau de la compilation n'est pas suffisante et que vous avez besoin de la modularité à l'exécution, il existe un élément appelé pointeurs de fonction. Ils permettent d’avoir des implémentations individuelles d’une interface bien définie. Notez qu'il ne s'agit pas d'une programmation orientée objet dans un langage non orienté objet. C'est définir une interface et ensuite l'implémenter. Par exemple, le sous-classement n'est pas utilisé ici.
Considérez peut-être le projet open source le plus complexe qui existe. À savoir, le noyau Linux. Il est entièrement écrit en langage C. Cela se fait principalement en utilisant les outils de modularité de niveau de compilation standard, y compris la composition, et parfois lorsque la modularité à l'exécution est nécessaire, des pointeurs de fonction sont utilisés pour définir et implémenter une interface.
Si vous essayez de trouver un exemple de programmation orientée objet dans le noyau Linux, je suis certain que trouver cet exemple est très difficile, sauf si vous étendez la programmation orientée objet pour inclure des tâches standard telles que "définir une interface puis l'implémenter".
Notez que même le langage de programmation C prend en charge la programmation orientée objet si vous en avez vraiment besoin. Par exemple, considérons le kit d'outils de l'interface utilisateur graphique GTK. En réalité, il est orienté objet, même s'il est écrit dans un langage non orienté objet. Cela montre donc que l’idée selon laquelle vous avez besoin d’un "langage orienté objet" est profondément erronée. Il n'y a rien qu'un langage orienté objet puisse faire qu'un autre type de langage ne puisse pas faire. De plus, si vous êtes un programmeur expert, vous savez écrire très facilement un code orienté objet dans n’importe quelle langue. Ce n'est pas un fardeau d'utiliser C, par exemple.
Les conclusions sont donc que les langages orientés objet ne sont probablement utiles que pour les programmeurs débutants qui ne comprennent pas comment le concept est réellement implémenté. Cependant, je ne voudrais pas être à proximité d'un projet où les programmeurs sont de tels programmeurs novices.
la source
L’introduction de paradigmes de programmation, y compris des méthodes orientées objet, a pour but de faciliter la création de programmes plus sophistiqués et plus puissants. Dans le numéro d'août 1981 de Byte Magazine, Daniel Ingalls , l'un des principaux créateurs de Smalltalk, définissait "orienté objet" comme impliquant les capacités suivantes:
Ingalls a identifié ces principes comme étant les facteurs déterminants de la conception de SmallTalk-80 développés par Xerox Parc Research. Dans l'article de magazine susmentionné, vous pouvez lire une description détaillée de chacun de ces principes et de la façon dont ils contribuent au paradigme orienté objet selon Ingalls.
Tous ces principes peuvent être appliqués avec n’importe quel langage complet Turing, qu’il s’agisse de la procédure, du langage d’assemblage ou autre. Ce sont des principes de conception, pas une spécification de langage. Un langage orienté objet est destiné à faciliter l'utilisation de ces principes lors de la création de logiciels.
Par exemple, pour reprendre le premier des principes d'Ingall (gestion automatique du stockage), tout le monde peut écrire son propre système de gestion automatique du stockage dans un langage procédural, mais cela demanderait beaucoup de travail. Lorsque vous utilisez un langage tel que SmallTalk ou Java doté d'une gestion de stockage automatique intégrée, le programmeur n'a pas à effectuer autant de travail de gestion de la mémoire. Le compromis est que le programmeur obtient moins de contrôle sur la façon dont la mémoire est utilisée. Donc, il y a un avantage et un inconvénient. L'idée d'un paradigme de conception comme la programmation orientée objet est que les avantages de ce paradigme l'emporteront sur les inconvénients pour au moins certains programmeurs.
la source
Un moyen de gérer la complexité logicielle consiste à séparer complètement la structure des actions souhaitées à l'aide d'un langage spécifique à un domaine . Cela signifie que le niveau de code de programmation est distinct du niveau auquel les résultats souhaités sont configurés - un langage ou un système complètement différent. Lorsque cela est fait correctement, le code conventionnel devient essentiellement une bibliothèque et l'utilisateur ou toute autre personne créant les résultats souhaités associe des éléments à un langage de script ou à un outil de conception visuelle, tel qu'un générateur de rapports.
Pour fonctionner, cela nécessite de tracer une limite stricte autour des opérations qui seront possibles et de la manière dont elles sont reliées (langage de script ou conception visuelle, comme un outil de construction de formulaire). Les métadonnées constituent un moyen important de soustraire la configuration d'exécution aux détails de codage, permettant ainsi à un système de prendre en charge un large éventail de résultats souhaités. Si les limites sont définies et respectées (en n'acceptant pas chaque demande d'extension), vous pouvez avoir un système robuste et durable qui fonctionne pour les utilisateurs, sans qu'ils aient besoin d'être programmeurs pour accomplir ce qu'ils veulent.
Martin Fowler a écrit un livre à ce sujet, et la technique est presque aussi vieille que la programmation elle-même. On pourrait presque dire que tous les langages de programmation sont des langages spécifiques à un domaine. L'idée est donc endémique, négligée car tellement évidente. Mais vous pouvez toujours créer vos propres outils de script ou de conception visuelle pour vous simplifier la vie. Parfois, généraliser un problème le rend beaucoup plus facile à résoudre!
la source
C'est une très bonne question et je pense que les réponses données ici n'ont pas rendu justice, alors je vais y aller et ajouter mes pensées.
L’objectif est: gérer la complexité des logiciels . L'objectif n'est pas "utiliser le langage OO".
Il n’ya pas de «raison» derrière l’introduction d’un nouveau paradigme. C'est quelque chose qui s'est passé naturellement lorsque le codage est devenu plus mature. Il est plus logique d'écrire du code dans lequel nous ajoutons un entraîneur à la fin du train (le train modélisé à l'aide d'une liste chaînée) plutôt que d'ajouter un nouveau nœud à la fin de la liste chaînée.
Codage en termes d'entités du monde réel est tout simplement la manière évidente et correcte au code lorsque nous sommes de codage sur les entités du monde réel.
Un ordinateur peut travailler avec l'ajout d'un nœud à la fin de la liste chaînée aussi facilement que l'ajout d'un coach supplémentaire à la fin du train. Mais pour les humains, il est plus facile de travailler avec le train et l'entraîneur qu'avec la liste chaînée et les nœuds, même si, lorsque nous atteignons un niveau, le train est modélisé au moyen d'une liste chaînée.
Protéger ou chiffrer les fichiers ne peut pas être encapsulé. Le contraire du cryptage est le décryptage. Le contraire de l'encapsulation est Decapsulation, qui consiste à décomposer les structures et les classes dans les langages de programmation pour améliorer les performances. Performances obtenues en réduisant le trafic mémoire et en évitant les vérifications de règles de POO.
Par conséquent, vous pouvez écrire un code à la fois crypté et bien encapsulé, car ces deux concepts sont différents.
L’encapsulation aide à gérer la complexité du fait qu’elle est proche de la réalité.
Par conséquent, programmez dans des objets car il est plus facile pour vous de coder et pour vous et tout le monde plus rapidement de comprendre.
la source
La seule chose à retenir est la suivante: la
POO ne concerne pas les fonctionnalités du langage; il s'agit de la façon dont vous structurez votre code .
La programmation orientée objet est une manière de penser et de concevoir l'architecture de votre code, et cela peut être fait dans à peu près n'importe quelle langue. Cela inclut en particulier les langages de bas niveau non OO, appelés assembleur et C. Vous pouvez effectuer une programmation parfaitement orientée objet dans assembleur, et le noyau Linux, écrit en C, est assez orienté objet à bien des égards. .
Cela dit, les fonctionnalités OO dans une langue réduisent considérablement la quantité de code passe-partout que vous devez écrire pour obtenir les résultats souhaités . Lorsque vous devez définir explicitement une table de fonction virtuelle et la remplir avec les pointeurs de fonction appropriés en C, vous ne faites rien en Java et vous avez terminé. Les langages OO suppriment simplement tout ce qui permet cruel du code source, en le cachant derrière de belles abstractions de niveau de langage (telles que des classes, des méthodes, des membres, des classes de base, des appels implicites de constructeur / destructeur, etc.).
Donc, non, nous n'avons pas besoin des langages OO pour faire de la programmation orientée objet. C'est juste que la POO est tellement plus facile à faire avec un langage OO décent.
la source
La programmation orientée objet est plus que de simples modules + encapsulation. Comme vous le dites, il est possible d’utiliser des modules + encapsulation dans un langage (procédural) non orienté objet. La POO implique plus que cela: elle implique des objets et des méthodes. Donc, non, cela ne capture pas la POO. Voir, par exemple, https://en.wikipedia.org/wiki/Object-oriented_programming ou l'introduction d'un bon manuel à la programmation orientée objet.
la source
La principale raison est qu’au fur et à mesure que le programme se complexifie, vous devez en rendre certaines parties invisibles, sinon la complexité de l’application et le nombre de fonctions rendront votre cerveau dribbler.
Imaginons un système de 100 classes, chacune avec environ 20 opérations pouvant être effectuées sur elles. c'est 2.000 fonctions. Cependant, parmi celles-ci, seules 500 sont peut-être des opérations complètes telles que «Enregistrer» et «Supprimer», tandis que 1500 sont des fonctions internes qui effectuent un peu de maintenance ou jouent un rôle utilitaire. Considérer;
C'est donc
SetName
une fonction que les gens devraient faire à une personne, maisSplitPersonName
une fonction utilitaire utilisée par la personne.Une programmation procédurale simple ne fait aucune distinction entre ces deux opérations. Cela signifie que vos 2 000 fonctionnels se disputent votre attention. Cependant, si nous pouvions marquer ces fonctions comme "disponibles pour tous ceux qui ont une fiche personne" et "utilisées uniquement comme fonction utilitaire dans la fiche personne", notre attention porte désormais sur 500 fonctions "accessibles à tous" et 15 "utilitaires". fonctions pour la classe que vous éditez.
C'est quoi
public
etprivate
faire;la source