JavaRush /Blog Java /Random-FR /Programmation orientée objet (traduction de l'article)
Exidnus
Niveau 38
Санкт-Петербург

Programmation orientée objet (traduction de l'article)

Publié dans le groupe Random-FR
Du traducteur : Malheureusement, je n'ai pas d'expérience significative dans la traduction de l'anglais, même si je lis beaucoup en anglais. Mais il s’est avéré que lire et traduire sont deux choses différentes. De plus, malheureusement, je n'ai pas d'expérience significative en programmation (je viens de créer récemment une simple application Web dans Spring MVC et Hibernate). La traduction s’est donc révélée bien pire qu’elle n’aurait pu l’être. J'ai pris la liberté de corriger légèrement les exemples de codes donnés dans l'article, car ils ne respectent pas les conventions de nommage en Java. Peut-être que cela ne valait pas la peine de traduire les noms de certains modèles (une telle traduction n'apporte pas beaucoup de compréhension), mais j'ai pensé que c'était un moindre mal. Il convient de mentionner séparément « haute cohésion » comme traduction de « haute cohésion ». Je suis d'accord, ce n'est pas la meilleure traduction. Mais une « connectivité forte » correspond à un « couplage élevé » (un autre concept important), et il est peu probable que la « cohérence » convienne ici. Je suis ouvert aux critiques et accepterai avec gratitude les commentaires sur l'article sous quelque forme que ce soit. La programmation orientée objet est un style de programmation dans lequel un programme est composé de composants qui correspondent à des objets du monde réel. Tout objet réel possède certaines propriétés (qui peuvent ou non changer avec le temps) et un comportement (qui peut ou non changer). changer en fonction des autres). Par exemple, un crayon est un objet du monde réel qui possède les propriétés suivantes :
  • Il est rouge (cela ne change pas avec le temps).
  • Il mesure désormais 10 centimètres de long (cela peut changer si le crayon est taillé).
Et il a le comportement suivant :
  • Il laisse une trace s'il est utilisé correctement.
  • La trace peut différer en fonction de la pression (en fonction de facteurs externes).
  • Sa longueur diminue au fur et à mesure de son affûtage (comportement permanent).
Comme dans cet exemple, les objets du monde réel peuvent avoir de nombreuses propriétés, mais lors de l'écriture de programmes, nous ne prenons en compte que les propriétés nécessaires. La programmation orientée objet a ses avantages. Par exemple, cela facilite l’établissement d’une connexion entre un objet du monde réel et un programme de la manière attendue. Cela aide vraiment à mesure que l'application se développe et que de nombreux objets interagissent les uns avec les autres. Cela aide à répartir les responsabilités dans le monde objectif, vous permettant de vous concentrer sur la réflexion sur l'application. Une autre fonctionnalité importante associée à la POO (Programmation Orientée Objet) est la classification des objets. Le monde (réel/virtuel) étant rempli d’objets, il est difficile de les contrôler individuellement. Nous avons besoin d'un moyen de classer ces objets qui nous aidera à associer différents objets et leurs propriétés, comme un crayon noir. Il serait impossible de le distinguer (identique ?) s'il était utilisé dans l'exemple précédent, mais c'est un objet différent. Mais comme ce sont tous deux des crayons, ils appartiennent à la même classe « Crayon ». Alors qu’un stylo, qui ressemble beaucoup à un crayon, appartient à une classe différente. Cependant, le stylo et le crayon sont tous deux des « instruments d’écriture ». La programmation orientée objet repose sur les principes suivants :
Abstraction
L'abstraction est définie comme la qualité de l'interaction avec des idées plutôt qu'avec des événements ou, en d'autres termes, l'absence de qualités représentationnelles . Cela permet aux programmeurs de se concentrer sur ce qu'ils doivent programmer plutôt que sur la manière de programmer . L'abstraction peut être considérée comme un contrat par lequel nous fournissons des fonctionnalités. Les détails de mise en œuvre peuvent être masqués lors de l'utilisation de ce concept. Par exemple, si nous avons besoin d'une classe qui écrit, alors nous devons être sûrs qu'elle dispose d'une méthode « write » abstract class writer { write (); } . Nous avons conçu une classe de haut niveau qui est abstraite, en d'autres termes, elle sait de quelles fonctionnalités nous avons besoin, mais comment les implémenter sort du cadre de cette classe. Cela offre de nombreux avantages :
  • Nous divulguons le minimum d'informations nécessaires à des entités externes, cela nous permet de nous concentrer sur la réflexion sur le programme (cela permet une réflexion ciblée), d'éviter toute confusion et d'éviter de faire des promesses involontaires.
  • Nous laissons place à de futures améliorations qui ne seraient pas possibles si les détails de la mise en œuvre étaient révélés.
Héritage
« Héritage » en anglais courant signifie « acquérir et transmettre ». Ce mot existe dans notre culture depuis très longtemps. Les ancêtres ont acquis des terres grâce à un travail acharné et les ont transmises à leurs enfants, même la nature favorise l'héritage. Toutes les propriétés du corps, telles que la taille, la couleur de la peau/des yeux/des cheveux, etc. dépendent des gènes que nous héritons de nos parents. L'héritage évite de réinventer la roue et accélère le progrès. C'est la même chose en POO. Nous créons une classe parent avec quelques propriétés/comportements de base. Toutes les classes héritant de ce parent contiendront les mêmes propriétés/comportements que leur parent. Cependant, les classes héritées peuvent acquérir plus de propriétés/comportements ou modifier l'implémentation du comportement. class WritingInstrument { colour; write() { } } class Pen (child of parent) { inkcolour; } Dans l'exemple ci-dessus, la classe parent (WritingInstrument) a une propriété « color » et un comportement « write ». Lorsque la classe descendante (handle) est déclarée, la propriété « color » et le comportement « write » n'ont pas besoin d'être déclarés à nouveau. Ils sont présents dans la classe "handle" en raison de l'héritage. Cependant, une classe descendante peut déclarer ses propres propriétés/comportements supplémentaires. Comment pouvons-nous utiliser cela en pratique ? Nous, les développeurs, sommes très paresseux. Nous ne voulons pas imprimer quelque chose encore et encore. L'existence de plusieurs copies du même code est déconseillée en raison des considérations suivantes :
  • Moins il y a de copies de code, plus il est facile à maintenir.
  • S'il n'y a pas beaucoup de copies du code, alors un changement à un endroit devient visible partout.
  • Moins il y a de code, moins il y a d'erreurs.
  • Si un code est utilisé à plusieurs endroits, la généralisation est obtenue.
  • Nous nous concentrons sur l'écriture de code.
  • Nous nous concentrons sur les tests.
L'héritage en Java est obtenu à l'aide des mots-clés "extends" et "implements". class WritingInstrument { } class Pen extends WritingInstrument { }
Polymorphisme
Le mot « polymorphisme » vient de deux mots : « Poly » , c'est-à-dire "plusieurs" / "plus d'un" "morphe" , c'est-à-dire « forme » Littéralement, le mot « polymorphisme » fait référence à la capacité des objets à se comporter de différentes manières selon les conditions. En programmation, le polymorphisme peut être implémenté à plusieurs endroits :
  • Des classes
  • Méthodes
  • Les opérateurs
Tout ce qui précède peut se comporter différemment selon les conditions, voire le contexte, dans lequel ils sont utilisés. Ceci est utile car le client (le programmeur utilisant vos bibliothèques) n'a pas besoin de connaître beaucoup de subtilités et la fonctionnalité souhaitée est implémentée en sélectionnant les informations nécessaires dans le contexte. Class WritingObject { wrire() { // пишем, используя стандартные (по дефолту) цвета } } class Pencil extends WritingObject { write() { // пишем, используя серый цвет, написанный текст можно стереть } } class Pen extends WritingObject { write() { // пишем, используя голубой цвет, написанный текст нельзя стереть } } class Main { main() { WritingObject wr = new WritingObject(); wr.write(); // первый вызов WritingObject wr = new Pen(); wr.write(); // второй вызов WritingObject wr2 = new Pencil(); wr2.write(); // третий вызов } } L'exemple ci-dessus a une implémentation par défaut dans WritingObject, qui est étendue/remplacée par les classes descendantes pen et pen. La méthode write() est appelée trois fois dans la classe Main. Chaque fois, une implémentation différente est appelée en fonction de l'objet sur lequel la méthode est appelée. Dans ce cas, la méthode write() a de nombreux types de comportement car elle est polymorphe.
Encapsulation
L'encapsulation est définie comme la collecte de données/fonctionnalités associées dans une seule unité. Cela aide à faciliter l’accès/la modification des données. Par exemple, si nous devons imprimer toutes les propriétés d'un utilisateur donné, nous disposons des options suivantes : Nous printUserProperties(userName, userId, firstname, lastname, email, phone, … … ….) avons créé une méthode qui prend toutes les propriétés et les imprime les unes après les autres. À mesure que le nombre d'éléments dans la liste augmente, il ne sera plus possible d'identifier les champs corrects, et l'ajout/suppression d'un champ modifiera la signature de la méthode. Par conséquent, nous devons remplacer tous les utilisateurs de cette méthode, même s’ils n’ont pas besoin des champs récemment ajoutés. Pour rendre le code plus lisible et faciliter les modifications futures, nous encapsulons les propriétés dans une classe et la transformons en un objet collectif. class User { userName userId firstname lastname email phone .. .. .. } printUserProperties(user) {} Un objet est un ensemble logiciel de variables et de méthodes associées. Vous pouvez représenter des objets du monde réel à l'aide d'objets de programme. Vous pouvez imaginer de vrais chiens dans un programme d'animation, ou un vrai vélo comme objet logiciel à l'intérieur d'un vélo d'exercice. En POO, une classe est un modèle extensible (program-code-template) permettant de créer des objets, de leur fournir un état initial (variables) et d'implémenter un comportement (fonctions, méthodes). L'acronyme SOLID a été inventé par Michael Feather pour désigner les « cinq premiers principes » nommés par Robert C. Martin au début des années 2000. L'objectif de ces principes, lorsqu'ils sont mis en œuvre ensemble, est d'augmenter la probabilité que le programmeur crée un système facile à maintenir et à étendre. Les principes SOLID sont des lignes directrices en matière de développement de programmes qui sont nécessaires pour supprimer le code « pourri » via une refactorisation, ce qui permet au code de devenir facilement lisible et extensible. Cela fait partie de la stratégie de programmation agile et adaptative.
Principe de responsabilité unique
En POO, le principe de responsabilité unique stipule que chaque classe doit être responsable d'une partie des fonctionnalités fournies par le programme et que cette responsabilité doit être entièrement encapsulée par cette classe. Toutes ses fonctionnalités doivent être étroitement liées à cette responsabilité.
Principe ouvert/fermé
En POO, le principe ouvert/fermé stipule que « les entités logicielles (classes, modules, méthodes, etc.) doivent être ouvertes à l'extension mais fermées au changement ». Autrement dit, l’entité doit permettre d’étendre son comportement sans changer le code source.
Principe de substitution de Liskov
La substituabilité est un principe en POO. Il stipule que si S dans un programme informatique est un sous-type de T, alors les objets de type T doivent être tels qu'ils puissent être remplacés par des objets de type S (c'est-à-dire que les objets de type S peuvent être remplacés par des objets de type T) sans changer. toutes les propriétés requises des programmes (précision, achèvement des tâches, etc.).
Principe de séparation des interfaces
Le principe de séparation des interfaces stipule que le programmeur client ne doit pas être obligé de dépendre de méthodes qu'il n'utilise pas. Selon ce principe, il est nécessaire de diviser les grandes interfaces en interfaces plus petites et plus spécifiques afin que le programmeur client ne connaisse que les méthodes qui l'intéressent. L’objectif du principe de découplage d’interface est de maintenir le système découplé, ce qui facilitera la refactorisation, les modifications et le redéploiement.
Principe d'inversion de dépendance
En POO, le principe d'inversion de dépendances désigne une forme spécifique de déconnexion entre les modules du programme. En suivant ce principe, les relations de dépendance standard établies à partir des modules de haut niveau formant l'architecture d'application (définition des politiques) jusqu'aux modules de bas niveau dépendants sont inversées (inversées), de sorte que les modules de haut niveau modifiés deviennent indépendants des détails d'implémentation de modules de bas niveau. Ce principe stipule :
  • Les modules de haut niveau ne doivent pas dépendre des modules de bas niveau. Les deux types de modules doivent dépendre d'abstractions.
  • Les abstractions ne doivent pas dépendre des détails de mise en œuvre. Les détails doivent dépendre des abstractions.
Ce principe inverse la manière dont les gens envisagent la conception orientée objet en affirmant que les objets de haut et de bas niveau devraient dépendre des mêmes abstractions.

Principes GRASP

Les modèles logiciels d'attribution de responsabilités générales (GRASP) fournissent des lignes directrices pour l'attribution de responsabilités aux classes et aux objets dans la conception orientée objet.
Manette
Le modèle Controller attribue la responsabilité de l’interaction avec les événements système à des classes non-GUI qui représentent l’ensemble du système ou un scénario de cas d’utilisation. Manette:
  • Il s'agit d'un objet qui n'interagit pas directement avec l'utilisateur et qui est chargé de recevoir et de répondre aux événements système.
  • Doit être utilisé pour traiter tous les événements système d’un (ou de plusieurs) cas d’utilisation interdépendants.
  • C'est le premier objet derrière l'interface graphique qui contrôle les opérations du système.
  • Il n'est pas obligé de faire le travail lui-même, sa tâche est de contrôler le flux des événements.
Créateur
La tâche de la classe créatrice est de créer et de lancer des objets pour une utilisation ultérieure. Il connaît les paramètres d'initialisation, ainsi que l'objet qui sera créé. Parfois, la classe Creator crée activement des objets et les place dans le cache, et fournit une instance lorsque cela est nécessaire.
Haute cohésion
Une cohésion élevée est un modèle d'évaluation dont le but est de conserver les objets dans un état tel qu'ils visent à accomplir une tâche claire, sont faciles à contrôler et à comprendre. Le couplage élevé est généralement utilisé pour prendre en charge le couplage faible. Une cohérence élevée signifie que les responsabilités d'un élément donné sont clairement définies (fortement liées et hautement ciblées). La division d'un programme en classes et sous-systèmes est un exemple d'actions qui augmentent la cohésion des propriétés du système. En revanche, un couplage lâche est une situation dans laquelle un élément a trop de tâches non liées. Les éléments faiblement couplés ont tendance à être difficiles à comprendre, réutilisables, difficiles à entretenir et difficiles à modifier.
Indirection
Le modèle Roundabout maintient un couplage lâche (et une réutilisabilité) entre deux éléments en attribuant la responsabilité de l'interaction entre eux à un objet intermédiaire. Un exemple est l'introduction d'un contrôleur pour servir d'intermédiaire entre les données (modèle) et leur affichage (vue) dans le modèle Model-View-Controller (MVC).
Expert en informations
L'expert en information (également expert ou principe d'expert) est un principe utilisé pour déterminer à qui déléguer la responsabilité. Les responsabilités incluent les méthodes, les champs calculés, etc. Lorsqu'on utilise ce principe lors de l'attribution des responsabilités, l'approche principale est la séquence d'actions suivante : analyser la responsabilité, identifier les informations nécessaires pour l'accomplir et enfin établir où se trouvent ces informations. L’utilisation du principe Information Expert conduit à attribuer la responsabilité à la classe qui dispose du plus d’informations pour l’exécuter.
Couplage faible
Le couplage lâche est un modèle d'évaluation qui spécifie comment attribuer les responsabilités : un couplage lâche entre les classes, changer l'une devrait avoir un impact minimal sur l'autre, maximisant la réutilisabilité.
Polymorphisme
Selon le polymorphisme, la variation de comportement basée sur le type est attribuée aux types pour lesquels cette variation se produit. Ceci est réalisé en utilisant des opérations polymorphes.
Variantes protégées
Le modèle Protected Changes protège les éléments des modifications apportées à d'autres éléments (objets, systèmes, sous-systèmes) en enveloppant le foyer d'instabilité dans une interface et en utilisant le polymorphisme pour créer différentes implémentations de cette interface.
Fabrication pure
La construction pure implique une classe qui ne représente pas un concept dans le domaine du problème et est conçue spécifiquement pour obtenir un couplage lâche, un couplage élevé et donc un potentiel de réutilisation maximal (la solution proposée par le modèle Information Expert n'y parvient pas). Une telle classe est généralement appelée « Service » dans la conception pilotée par domaine.

Critique

Les recherches menées par Potok et ses collègues n'ont montré aucune différence significative entre les approches POO et procédurales.
Une comparaison critique de la POO avec d'autres technologies, en particulier les technologies relationnelles, est difficile en raison de l'absence d'une définition de la POO rigoureuse et largement acceptée (Christopher J. Date)
Par rapport à d'autres langages (dialectes LISP, langages fonctionnels, etc.), les langages POO n'ont pas d'avantage unique et imposent une complexité inutile. (Laurence Krubner)
Je trouve la programmation orientée objet techniquement fragile. Il tente de décomposer le monde en parties en termes d'interfaces qui varient au sein d'un même type. Pour résoudre des problèmes réels, vous avez besoin d’algèbres multi-triées – des familles d’interfaces qui s’étendent sur de nombreux types. Je trouve la programmation orientée objet philosophiquement malsaine. Il affirme que tout est objet. Même si cela est vrai, ce n’est pas très intéressant : dire que tout est objet, c’est ne rien dire du tout. (Alexandre Stepanov)
La popularité de la POO parmi les grandes entreprises est due à « des groupes importants (et en constante évolution) de programmeurs médiocres ». La discipline imposée par la POO empêche le programmeur de faire « trop de mal ». (Paul Graham)
La programmation orientée objet donne la priorité aux noms. Pourquoi prendre des mesures aussi extrêmes et mettre une partie du discours sur un piédestal ? Pourquoi un concept prime-t-il sur un autre ? Il est impossible que la POO rende soudainement les verbes moins importants dans notre réflexion. C'est une perspective étrangement biaisée. (Steve Yegge)
Rick Hickey, le créateur de Clojure, a décrit les systèmes d'objets comme des modèles extrêmement simplifiés du monde réel. Il a souligné l'incapacité de la POO à modéliser correctement le temps, ce qui crée d'énormes problèmes lorsque le multithreading devient courant dans les programmes. Eric S. Raymond, programmeur Unix et défenseur des logiciels open source, a critiqué l'affirmation selon laquelle la POO est « la solution unique » et a écrit que la POO encourage les programmes multicouches, ce qui entrave la transparence. En guise d’approche opposée, Raymond a donné l’exemple d’Unix et C.

Liens

Par Margaret Rouse @ WhatIs.com Wikipédia ! ( version russe ) l'héritage est un polymorphisme SOLIDE (conception orientée objet) ( version russe ) Principe de responsabilité uniqueArguments contre OOPS ( version russe ) Qu'est-ce que OOPS (sans le battage médiatique) Traduction : Varygin D.V.
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION