|
Publicité ' | ||||||||||||||||||||||||
|
|
#1 |
|
Expert Confirmé Sénior
![]() ![]() Développeur d'applications Inscription : novembre 2005 Messages : 2 568 ![]() |
Bonjour,
Les bonnes pratiques nous ont poussé à séparer nos applications en différentes couches au nom de la séparation des responsabilités. La plupart d'entre nous ont identifié :
Et entre deux la fameuse couche service qui sert de ciment entre les 2 choses. Si ces concepts de séparation sont facilement compris et acceptés, leur mise en pratique diffère fortement et c'est rien de le dire. De mon côté, j'ai tendance à penser cette couche de service comme une API de haut niveau destinée à l'UI, offrant des méthodes simples permettant de procurer un lot de données, insérer des enregistrements, exécuter des tâches métier sous forme de transactions. En contrepartie, les objets échangés entre la couche Ui et la couche Service sont plutôt simples car le plus souvent destinés à l'affichage, en fait ce sont souvent que de simples conteneurs de données avec assez peu de méthodes et de savoir-faire interne. Mon approche, cependant, est je le sais, fortement critiquée notamment par Martin Fowler qui considère que c'est un antipattern du point de vue OOP http://www.martinfowler.com/bliki/An...mainModel.html et que la logique devrait se situer dans des objets métier qui contiendraient ainsi les données et les méthodes pour travailler dessus conformément à la programmation orientée objet. Donc ce qui est prôné plutôt que mon approche non OO procédural d'un autre temps est donc de passer entre l'UI et le service des entités intelligentes incorporant toute la logique métier. Sur le fond je suis d'accord... Pourtant j'ai l'impression que dès qu'on a une source de données relationnelle derrière, ça coince. Pourquoi cela coincerait en fait? Et bien car dans des applications assez poussées, modéliser une simple commande de matériel en objet indépendant nécessiterait que vous ayez accès, par exemple, aux stocks, aux pays, aux conditions de livraison du client afin d'avoir tous les éléments pour implémenter une méthode aussi simple que MaCommande.AjouteProduit( Produit p). Alors que faites-vous? Vous chargez 250mo de données en mémoire depuis votre base SQL ou vous utilisez outrageusement le lazy loading pour que votre objet puisse se procurer ces informations à la demande? Je suis d'accord ça marcherait certainement sur une petite application de gestion toute bête, mais au bout d'un moment comment pourrez-vous concilier la versatilité de votre objet métier qui doit soi-disant *modéliser les interactions* et les performances? Et si vous devez modifier 1500 commandes pour marquer un retard de livraison, vous allez charger 1500 graphes pour appeler la méthode setLivraison()? En fait j'ai un peu l'impression que cette histoire de 100% objet est un mythe, un cas d'école qui n'est réalisable que dans les applications triviales. Est-ce qu'on peut vraiment concevoir ses objets métiers en faisant abstraction du système de stockage comme on semble nous vendre dans les recueils de bonnes pratiques? Qu'en pensez-vous? |
|
|
20
|
|
|
#2 |
|
Membre Expert
![]() Inscription : avril 2004 Messages : 1 246 ![]() |
J'en pense qu'il existe des "vues". Et que c'est également modélisable en poo.
|
|
|
00
|
|
|
#3 |
|
Membre Expert
![]() Inscription : août 2006 Messages : 1 147 ![]() |
|
|
|
00
|
|
|
#4 |
|
Expert Confirmé Sénior
![]() ![]() Développeur d'applications Inscription : novembre 2005 Messages : 2 568 ![]() |
|
|
|
00
|
|
|
#5 |
|
Membre actif
![]() Inscription : mars 2011 Messages : 91 ![]() |
C'est toujours possible mais la question est de savoir si cela est nécessaire, voir si c'est souhaitable.
La force du langage impératif, c'est que l'on peut comprendre "intuitivement" la manière dont sera exécuté le code sur la machine. Le langage objet, du fait de son niveau d'abstraction, pose un flou à ce niveau. Vu qu'en POO la méthode est liée à l'instance de l'objet la donnée devient donc active en initiant l'action, plutôt que passive en étant passé en paramètres à celle ci. L'avantage est que cela évite d'utiliser la mauvaise fonction sur la mauvaise donné. L’inconvénient est que tout ce qui est sécurité induit de la complexité. Que seul les bonnes méthodes puissent être utiliser avec la bonne instance est une sécurité. Cette complexité n'est pas au service de la fonctionnalité mais au service du développeur. L'instance devrait gérer la partie fonctionnelle du code. En plus de cela, elle gère les erreurs du développeurs et les erreurs d'exceptions qu'il s'agisse de l'infra ou de l'algo. Il vient ensuite la question de la refactorisation ou non du code. Il faut cependant savoir que la refactorisation n'élimine pas la complexité mais la déporte. L'avantage est que l'on peut se consacrer un temps à l’implémentation de la fonctionnalité et faire le reste dans un autre temps. L’inconvénient est qu'il faut architecturer l'ensemble et il y a autant d'architecture que d'architecte. Il y a à nouveau ajout de complexité. Bref beaucoup de complexité, donc beaucoup de bug potentiel et des pertes au niveau des perfs. La POO a été vendu comme étant plus facilement réutilisable. La POO n'est en fait qu'une façon de représenter le code. Ce paradigme se prête bien pour la représentation d’entités distinctes et indépendantes. Il n'est pas pertinent pour la représentation d'ensembles d'objets, de relations entre les objets, de procédure de traitement d'objets bref tout ce qui sort de l'objet. Les soit disant "best practices" sont de l'ordre de la masturbation intellectuelle. Le but est de faire du code qui marche comme prévu si possible et qui puisse être aisément modifiable si ce n'est pas le cas. Il ne s'agit pas de faire du pure objet avec des accesseurs systématiques obligatoirement en get/set. Les bonnes pratiques sont surtout des règles de bon sens. Il faut également insister sur les cas ou ces bonnes pratiques sont effectivement des bonnes pratiques. Par exemple: La restriction d'accès a une ressource c'est bien bonne chose sauf quand plusieurs objets doivent communiquer par celle ci. L'injection de dépendance est une mauvaise chose, sauf quand il s'agit d'améliorer la cohérence au sien d'un module. etc... Ces règles sont valables peut importe le type de langage. |
|
|
32
|
|
|
#6 | ||||
|
Expert Confirmé Sénior
![]() Inscription : janvier 2007 Messages : 9 594 ![]() |
Citation:
Je pense que ce qui pêche dans le modèle "couche de service" est qu'elle est identifiée comme UNE couche, alors qu'en fait c'est une série de couches.. (voir le modèle ISO) De même, la couche "persistence" confond la donnée avec le moyen avec lequel on l'obtient (BD, flat file, ou calcul). Il suffit de lire la partie "conception" de ce forum pour s'apercevoir des débats sans fins (et des problèmes) liés à l'attribution (ou non) d'une "méthode" dans telle ou telle section.. Citation:
Je pense simplement que cette vision tout OO est une aberration de principe : Pour reprendre un exemple que j'ai déjà cité dans un autre débat, il ne vient à l'idée de personne de penser qu'une lettre "possède" une méthode "se poster".. Si maintenant on prend un humain, le nombre d'actions est tellement gigantesque et imprévisible - non dénombrable - que l'action "poster" en est effectivement une, mais que l'on connaît a posteriori et non a priori Aussi, voir plus bas Citation:
Citation:
Physicien à la base, il m'est logique de penser un logiciel (qui est une suite de fonctionalités appliquées sur des objets) comme étant une suite de fonctionalités. Une personne lambda pensera de la même manière face à un problème.. Alors pour les personnes ayant été "élevées" dans l'objet, il est difficile de concevoir autre chose, mais le fond du problème est , je pense, dû à une approche américaine de concevoir les choses : les américains en général pensent pratique, et donc commencent par identifier un élément, et généralisent à partir de cet élement : c'est une approche "bottom-up". Dans cette approche, il est donc logique que les parties "basses" aient des détails, quitte à ce qu'ils soient dupliqués plus on généralise. Les européens, et les scientifiques en général, fonctionnent de manière "top-down", c'est à dire que le but est d'établir une théorie permettant de décrire les éléments successifs par raffinements successifs, en partant d'un schéma unique : la Relativité Générale englobe la mécanique classique , qui en est un cas particulier, la sémantique est une théorie du langage qui s'applique à toutes les langues, l'ethnologie s'applique à toutes les civilisations, etc.. Or, dans le domaine du logiciel, le Cahier des Charges, lorsqu'il est fourni, décrit des fonctionalités, et accessoirement les données sur lesquelles on travaille. Un logiciel est donc logiquement plus orienté fonctionalités que données.. En fait, il me semble que l'impact de l'OO provient de l'importance des grandes banques et sociétés de services oeuvrant dans le domaine des banques, qui ont toujours manipulé des BDD relationnelles, où les relations entre les données étaient le schéma de base, occultant même l'architecture globale.. et dont les "penseurs" n'avaient pas l'esprit scientifique...
__________________
"Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle". Consultant indépendant. Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie. C, Fortran, XWindow/Motif, Java Je ne réponds pas aux MP techniques |
||||
|
|
13
|
|
|
#7 | |||||||
|
Expert Confirmé Sénior
![]() ![]() Développeur d'applications Inscription : novembre 2005 Messages : 2 568 ![]() |
Merci pour ces réponses bien développées.
Citation:
Code :
J'ai beau avoir été élevé dans l'OO ou être tombé dans la marmite, ça ne me paraît pas non plus le rôle d'une lettre de savoir comment se poster. Pour moi, une lettre pourrait avoir une méthode permettant d'ajouter des paragraphes, de spécifier une signature. Mais essayons d'écarter le côté très discutable de la validité de l'exemple en terme d'OOP pour se concentrer sur la façon dont ceci pourrait s'implémenter : Plutôt qu'avoir une méthode d'action dans l'objet, j'aurai intuitivement plus l'intention de créer une classe ServicePostal ayant une méthode de ce genre : voire carrément : Code :
1) Vérification de l'adresse de destination 2) Calcul du coût d'expédition, validation du timbre 3) Enregistrement du pli Pas la peine de venir me dire que la poste ça ne fonctionne pas comme ça, ce n'est pas le point. Le fait est de dire que les actions ci-dessus vont forcément avoir besoin de données externes que notre lettre devra se procurer pour effectuer ce travail. Du coup notre objet lettre devra disposer de AnnuaireAdresses, Tarifs etc... On obtient rapidement une certaine quantité de dépendances, et notre méthode Lettre.Poste() dépasse passablement sa juridiction. Il me semble plus facile d'imaginer une lettre comme un conteneur de données, avec quelques méthodes basiques d'édition et éventuellement une validation de premier niveau, et de confier la logique à un service extérieur qui possède l'intelligence métier ainsi que le pouvoir de charger des données comme par exemples les tarifs, de les mettre en cache si nécessaire etc... En plus cela délimite bien les responsabilités de chaque couche. La lettre est un objet d'édition simple, il peut être sérializé sans risque et édité à distance dans une GUI quelconque, il n'a pas accès aux données et son comportement est délimité et maîtrisé. Cela éviterait d'avoir une lettre très lourde, capable de charger elle-mêmes les tarifs à la demande et tout ça. Cependant d'autres diront qu'on peut éviter le couplage en créant une méthode de ce genre Code :
Donc dans le cas de l'objet lettre qui se poste toute seule, un moment donné, les services nécessaires à son travail devront être 1) Soit fournis directement à la méthode (Avantage : l'objet reste serializable et fonctionne 100% détaché) 2) Soit fournis au constructeur (Avantage : automatisable par IOC, mais non fonctionnel en détaché). Ou alors, on opte pour garder la classe Lettre simple et conne comme je le disais au tout début et on confie la responsabilité au service? Finalement peut-on dire qu'opter pour la solution du *fat service* est signe de mauvaise compréhension de "l'object oriented design" comme le prétendent certains bloggers et autres rédacteurs de bouquins ? |
|||||||
|
|
10
|
|
|
#8 | ||
|
Expert Confirmé Sénior
![]() Inscription : janvier 2007 Messages : 9 594 ![]() |
Citation:
Si on reprend la citation que j'ai mentionnée : Citation:
Par contre, il subit des actions externes.. Mais il ne connaît rien... Une pierre peut autant servir à faire un mur qu'à être peinte par un artiste, qu'à être laissée là où elle est, qu'à taper sur son voisin, qu'à servir de cale ou de marche-pied, de projectile, ... Qu'un logiciel manipule des entités ou "objets", et qu'il soit conçu pour pouvoir les manipuler, c'est tout à fait normal et logique. Que par contre ce soit les objets qui définissent le logiciel est absurde.. Si l'on reprend un exemple facilement "objectisable", un logiciel de traitement d'images : chaque image est effectivement un objet, une entité propre sur laquelle vont s'appliquer divers traitements. Que l'on modélise (de manière informatique) ce logiciel comme étant une classe image possédant des méthodes de traitements, outre le fait que, mis à part la lecture et l'écriture (pour cause de format), toutes les méthodes sont partageables par toutes les instances, cela peut s'envisager. On passera cependant à côté de quelques fonctionalités ne rentrant pas dans ce cadre (palettes de couleurs, outils de dessin, d'écrture....). Mais ce style de logiciel est de toutes façons très rare... La majorité manipule des "objets" non fixes, ou dépendants de fonctionalités précédentes... A mon avis donc l"OOD n'est applicable QUE pour un petit nombre de logiciels... Comme pouvant être une facilité de programmation.. Mais la logique et la facilité de pensée, modélisation, et programmation, est souvent plus du côté du "procédural", manipulant des objets, que des objets effectuant des actions... Si l'on reprend même un exemple aussi "objectisable" que le traitement d'images, et si l'on se place dans le boulot d'un photographe, il est plus normal de penser que c'est le photographe qui va chosiir en fonction de la photo qu'il voit si il a besoin de lui appliquer tel ou tel traitement, que d'affubler chaque photo d'une série de méthodes dont la plupart n'ont aucun sens du point de vue du photographe pour cette photo en particulier... Il est aussi facile de modéliser un traitement d'image par une série d'actions appliquées sur des objets que l'inverse. Le fond est à mon avis souligné par mes 2 premières remarques : par définition l'OOD ne devrait être qu'une facilité de programmation pour certains cas et non pas un passe-partout de modélisation globale, pour la simple raison qu'un objet est inerte. Comme ce n'est pas ce qui est compris/propagé dans la plupart des cas, on arrive à des échafaudages encore plus compliqués à saisir (et élaborer !!!) que si l'on avait pris du procédural.. Ma conclusion serait : l'OO oui, l'OOD non D'ailleurs, l'OO est un paradigme de programmation, il n'a jamais été conçu pour être un paradigme de conception... * Note : j'ai fait du traitement d'images en Fortran IV en 1982 : c'était bien de l'OO, puisqu'on manipulait des images ayant des caractéristiques propres (dimensions, origine, orientation..), et que les fonctionalités manipulaient un concept "image", mais ce n'était pas de l'OOD, puisque l'analyse se basait sur les fonctionalités.. Il en va de même pour un langage de commande style shell : le coeur est un gros "switch" qui appelle le programme identifié dans la chaîne qui lui est passée..
__________________
"Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle". Consultant indépendant. Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie. C, Fortran, XWindow/Motif, Java Je ne réponds pas aux MP techniques |
||
|
|
13
|
|
|
#9 |
|
Membre éprouvé
![]() Inscription : janvier 2011 Messages : 156 ![]() |
Excellente question, ça fait du bien pour une fois dans ce forum se de plonger dans un débat vraiment technique et d'en explorer les détails
Je pense que le stéréotype largement répandu selon lequel l'orienté objet a pour but de modéliser des objets du monde réel est en grande partie faux. Faire de l'orienté objet, ce n'est pas prendre un terme métier, en faire une classe et essayer de fourrer des méthodes dedans pour faire tourner notre appli. Ca l'est parfois, mais c'est aussi bien souvent inventer de nouveaux concepts abstraits qui vont constituer le langage de notre application. Des Stratégies, des Fabriques, des Spécifications, des Ordonnanceurs, des Coordinateurs, des Mappeurs, des Adapteurs... On peut les appeler Service si on veut. Mais on peut aussi faire preuve d'un peu d'imagination et de richesse de vocabulaire. Et en général, plus un objet a un nom spécifique, moins on sera tenté d'en faire un fourre-tout ( ce qui a souvent tendance à être le cas avec les "Services"). A cet égard, l'exemple de la lettre qui se poste elle-même est un homme de paille, un argument fallacieux : c'est effectivement assez absurde d'y mettre la méthode Envoyer(). En revanche, pourquoi pas une classe CentreDeTri, DispatcheurCourrier ou que sais-je ? C'est certes un peu plus abstrait et moins décalqué du métier qu'une classe Chaise ou une classe Personne, mais c'est aussi de l'OO et ce n'est pas forcément un Service au sens gros bouzin procédural du terme. Deuxième argument qui me parait assez discutable : les exemples pris pour illustrer le bien fondé d'un Anemic Domain Model sont souvent des comportements coordinateurs qui exécutent une séquence d'actions appelant beaucoup d'objets tiers. Ces comportements existent et doivent être assurés, il ne s'agit pas de le nier. Mais il faut aussi penser à tous les autres types de comportements qui peuvent être encapsulés dans une classe :
Attention, un modèle du domaine riche (par opposition à anémique) n'empêche absolument pas d'avoir des services du moment qu'ils ont des responsabilités limitées et ne deviennent pas obèses. Dans Domain Driven Design, méthode citée par Fowler dans l'article que tu mets en lien et que certains considèrent comme "object oriented done right", Eric Evans identifie même 3 types de services :
Cela n'empêche absolument pas cette vision de promouvoir aussi des objets du domaine riches (comprendre : données + comportement), à chaque fois que c'est possible. Pour résumer, je ne pense pas que l'opposition entre approche procédurale et approche orientée objet se situe au niveau de la "pureté métier" des structures utilisées. C'est un faux débat. L'orienté objet, c'est avant tout l'encapsulation de données et comportement à l'intérieur de petites unités de code dont on peut gérer finement les interdépendances grâce à l'inversion de contrôle. Le procédural, c'est l'exécution en séquence de routines et sous-routines, généralement de taille plus large, peu réutilisables, et opérant souvent sur des données (variables) partagées par toute l'application. Donc oui, je prends ta classe ServicePostal, et oui, c'est de l'OO, du moment qu'elle ne fait pas le café, le ménage et le repassage et ne chipe pas des responsabilités à de "vrais" objets métier |
|
|
30
|
|
|
#10 | |||
|
Expert Confirmé Sénior
![]() Inscription : janvier 2007 Messages : 9 594 ![]() |
Citation:
Citation:
Citation:
Le procédural n'agit pas "en séquence" comme tu sembles le croire, ni avec des fonctions plus "larges", ni en opérant sur des données valables à travers toute l'application... Il est simplement structuré en termes de fonctionalités... Chaque fonctionalité ou sous-fonctionalité peut avoir son propre type d'objet, et en général le découpage peut-être très fin en termes de taille (il suffit de voir les specs du cycle en V..) Comme le disait la citation que j'ai faite, il n'y a pas vraiment de différence entre les 2, à part l'optique (et donc la modélisation) que l'on se fait.. C'est un faux problème la taille du code, la réutilisabilité, etc, ..qui serait au détriment du procédural.. N'importe quel gros soft en procédural n'est ni plus complexe ni plus long ni moins maintenable que le même en OO. Le choix est un choix philosophique..
__________________
"Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle". Consultant indépendant. Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie. C, Fortran, XWindow/Motif, Java Je ne réponds pas aux MP techniques |
|||
|
|
21
|
|
|
#11 | ||||
|
Membre actif
![]() Inscription : mars 2011 Messages : 91 ![]() |
Citation:
L'aspect donné est mis en avant mais le gros du travail du développeur porte sur la partie traitement. Quand je crée des classes pour un usage perso, je le fais dans une optique de simplification de lecture au niveau architecturale et non au niveau métier. Par exemple, mes méthodes pour l'objet Lettre se limiteraient à des accesseurs. Écriture/lecture de de l'adresse sur l'enveloppe, à l'écriture/lecture du message sur les feuilles de papier, présence ou non d'un timbre, etc. Des méthodes privées serviraient à calculer des propriétés cachées, comme le calcul du nombre de feuilles en fonction du nombre de caractère. La validation de l'adresse seraient faite par un objet CentreDeTri via une méthode recevoirCourrier() qui prend l'objet Lettre en paramètre. En fait, cette classe serait conçue pour accepter tout objets qui possède les accesseurs permettant de lire une adresse et le la valeur d'un timbre. La contrôle de la validité de l'adresse serait le boulot de cette classe ainsi l'objet CentreDeTri peut gérer des lettres mais également des colis de natures diverse. L'avantage est que l'objet lettre pourra également être passé à une classe objet Messager ou via une méthode PrendreCourier() ou la présence de timbre ne sera pas nécessaire et la validation de l'adresse ne répondra pas au même exigences que pour l'objet CentreDeTri. Un prénom connu de l'objet Messager suffirait Crois moi ou pas, ce type d'architecture est de la retranscription bête et méchante de ce que je fais en procédural: création de structure Lettre + passage en paramètre à des fonctions nommée CentreDeTri_prendreCourier(). Les objets CentreDeTri et Messager ne sont même pas instancié (bien que cela soit possible). En objet la fonction ressemblera à CentreDeTri::prendreCourrier(). La belle affaire ! Quand je présente ce genre d'architecture au niveau professionnel, on me regarde avec des yeux rond et on me dit: "ce n'est pas ça de la POO". Citation:
Il m'arrive par exemple d'utiliser un pattern sans nom en POO. Du moins à ma connaissance. Je crée une famille de classes statiques "driver" qui proposent une série de méthodes statiques. Ces méthodes statiques sont passés en paramètre à des classes de la famille "architecture" qui proposent des méthodes standard permettant d’appeler les méthodes "drivers" passé en paramètre via des callback en interne. Cela me permet de changer mes algos de traitement et modifier la gestion de l'infrastructure à la volé sans changer l'architecture globale de mon projet. Ce pattern fait la même chose que une factory, l'injection de dépendance en moins, de la souplesse en plus et le tout pour un ajout en complexité algorithmique de l'ordre de la constante. Un autre exemple de repompage pur et simple de ce que je fais en procédural. Le procédural c'est loin d'être bouzin. Le fait est que la frontière qui sépare la donnée et le code de traitement est ténu. Le procédural est très souple à ce niveau. Tout ceux qui auront trop jouer avec les pointeurs pourront en témoigner et peuvent utiliser cet aspect avantageusement. Citation:
Ce découpage dépend de la vision de l'architecte. Elle ne manque pas de pertinence mais elle est nécessairement influencer par les cas de figures sur lesquels il a travaillé. On ne peut pas en tirer de règle générale. Citation:
En programmation procédurale, les possibilités d'encapsulation, de modularité et la gestion des interdépendances peuvent être poussé à un point que tu n'imagines même pas. La réelle question est: "Faut il couper un cheveux en quatre pour faire créer un modèle 100% OO ?". J'ai tendance à penser que cela n'est pas pertinent. Cela ne se justifie pas forcément au niveau productivité, au niveau de la lisibilité et encore moins au niveau de l'optimisation. Creer un modèle 100% OO, pour créer un modèle 100% OO est de l'ordre de la masturbation intellectuelle. Si l'on voulait réellement faire du pur objet, il devrait y avoir des notations du type: "hello world !"->afficherEcran();. Cela permettrait de créer une méthode afficherEcran() qui procède à tout les contrôles nécessaire pour garantir l'affichage d'une simple chaine et envoyer une exception en cas d'échec. Si on ne le fait pas c'est parce que ça simplifie la gestion des chaines de caractère. Le même raisonnement peut s'appliquer sur des classes de plus haut niveau. |
||||
|
|
00
|
|
|
#12 |
|
Membre confirmé
![]() Jérôme FrossardEnseignant Inscription : décembre 2007 Messages : 73 ![]() |
J'ai tendance à penser que la programmation purement procédurale n'est guère applicable que lorsqu'il s'agit de programme fort simple. Dès lors qu'il s'agit de réaliser des applications d'une certaine complexité, on a besoin d'abstractions --- ces abstractions ne sont d'ailleurs pas l'appanage des informaticiens, si comme ingénieur électricien j'avais du appliquer les équations de Maxwell à chaque fois que je voulais réaliser un amplificateur, je n'aurais sans doute pas réalisé grand-chose --- et dès lors qu'on a besoin d'abstraction pour construire quelque chose on adopte une approche bottom-up, on réalise les abstractions (la pièce de légo -- qui peut d'ailleurs être très spécifique) dont on a besoin pour réaliser le tout, mais chacune de ces abstractions peut exister indépendamment les unes des autres (ce qui permet la réutilisation). Mais à un moment donné on doit, à l'aide de ces abstractions, réaliser un programme et à ce moment là l'approche est naturellement plutôt top-down. De plus, les deux approches ne sont pas appliquée de manière séquentielle, mais imbriquée; on réalise notre programme d'une manière top-down, à un moment donné on se rend compte qu'on a besoin d'une abstraction, on définit alors l'interface de cette abstraction et on suppose qu'on l'a à disposition pour poursuivre la conception.
Ensuite que le language supporte ou non le paradigme orienté objet n'est pas si important, au minimum on pourra toujours réaliser des type de donnée abstraits qui sont tout à fait comparable aux classes d'un langage qui supporte l'OO. Pour ces derniers, il y a bien sûr des trucs bien utilise comme l'héritage d'implémentation, les interfaces, etc... Mais que l'on travail en Pascal, en C, en C++, en Scheme ou en Java, si on réalise un logiciel d'une certaine complexité on arrive presque forcément à de une programmation orientée objet. La pratique a montré que certaines manières de faire sont moins bonnes que d'autres et il est donc intéressant de s'intéresser au patterns et anti-patterns qui ont été identifiés au file du temps. Un domaine où pour moi l'orienté objet n'a rien à faire, c'est celui des bases de données mais c'est un autre débat. |
|
|
11
|
|
|
#13 | ||
|
Expert Confirmé Sénior
![]() Inscription : janvier 2007 Messages : 9 594 ![]() |
Citation:
Citation:
__________________
"Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle". Consultant indépendant. Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie. C, Fortran, XWindow/Motif, Java Je ne réponds pas aux MP techniques |
||
|
|
01
|
|
|
#14 | |||||||
|
Membre éprouvé
![]() Inscription : janvier 2011 Messages : 156 ![]() |
Citation:
Tu cites l'exemple d'un objet Messager et d'un objet CentreDeTri qui tous les deux transmettent un courrier. Dans la version POO, nous sommes d'accord que ces 2 classes pourraient hériter d'une même classe (ou interface) parente qui exposerait une méthode TraiterCourrier() dans son contrat. Un objet tiers qui voudrait simplement envoyer un courrier sans se soucier des détails de l'expédition pourrait juste manipuler un objet du type de la classe parente qu'on lui passerait, et grâce au polymorphisme le bon traitement serait appliqué : par messager ou par centre de tri. On aurait alors une bonne maintenabilité du système puisque pour étendre notre gamme de modes d'expéditions, il suffit de créer une nouvelle classe implémentant le contrat TraiterCourrier() et d'en passer une instance à l'objet qui souhaite envoyer un message. Pas besoin de "casser" le code de la classe appelante ni de la classe de base. Est-ce que la même chose serait possible dans le cas de fonctions statiques CentreDeTri_prendreCourier() et Messager_prendreCourier() et du code "procédural" que tu décris ? Si oui, et je veux bien savoir comment, je considère que c'est de l'orienté objet (ou du fonctionnel, à la limite). Et pour reprendre l'exemple d'origine, si on a un ServiceExpédition et 2 classes dérivées ServiceExpéditionCentreDeTri et ServiceExpéditionMessager, alors oui, c'est de l'orienté objet même s'il y a des solutions plus élégantes que d'utiliser le mot-valise "Service" pour ça. Citation:
Citation:
Citation:
Citation:
Citation:
Citation:
|
|||||||
|
|
00
|
|
|
#15 |
|
Membre confirmé
![]() Jérôme FrossardEnseignant Inscription : décembre 2007 Messages : 73 ![]() |
Dans mon intervention précédente j'étais un peu hors sujet, mais je tiens néanmoins à répondre rapidement aux remarques de souviron34.
Selon l'état de mes connaissance, il n'existe pas de paradigme "full object". Le seul que je connaisse est le paradigme "object oriented". Je pense en outre, qu'il n'est pas possible de concevoir quelque chose de "100% objet" ou "pure objet" parce que le paradigme n'a pas de définition claire. Si on utilise la notion de classe ou de type abstrait, on fait de l'orienté objet. Au file des ans des personne d'autorité ont mis en évidence des patterns et des anti-patterns, il est souvent judicieux d'en tenir compte, ce n'est pas jamais une obligation ni une condition pour que le code puisse être qualifié d'orienté objet. Quand je disais que je n'aime pas l'orienté objet dans les base de données, je voulais dire que je n'aime pas tellement les bases de données orientées objet et leur préfère une base de données relationnelle dans presque tous les cas et à moins qu'on ne considère les relations comme des objets, celles-ci ne sont pas orienté objet. Pour en revenir au débat, selon moi, la couche de persistance ne dois pas forcement manipuler des objets métier. Je pense qu'il est tout à fait acceptable, voir même judicieux de passer par un "machin" intermédiaire qui transforme l'objet métier en un des ces objets "anémique" avant de le passer à la couche de persistance et inversement, qui construit un objet métier à partir d'un objet "anémique" que la persistance nous fourni. Peu importe la façon de faire, on violera l'encapsulation des données pour les sauvegarder, autant encapsuler cette "désencapsulation" dans une partie du code dont c'est l'unique responsabilité. En outre, ces objets soit-disant anémiques peuvent ne pas l'être; une classe n'est pas forcement une abstraction d'un concept métier, mais peut être une abstraction d'un concept "technique", on pourrait ainsi utiliser l'abstraction d'un nuplet pour y stocker les valeur à rendre persistante, on aurait ainsi la possibilité d'énumérer les champs, d'accéder aux champs par le nom, etc. Un tel objet est tout sauf anémique. |
|
|
00
|
|
|
#16 | ||||||
|
Expert Confirmé Sénior
![]() ![]() Développeur d'applications Inscription : novembre 2005 Messages : 2 568 ![]() |
Citation:
Citation:
Pour la validation j'ai dit premier niveau, car il peut être assez difficile lors de l'appel à une méthode setTimbre(Timbre t) ou colleTimbre(Timbre t) de pouvoir lever une erreur parce que le timbre "t" n'est pas suffisant par rapport à l'adresse (besoin adresses, tarifs, conditions d'expédition etc...). Cela dit, la validation immédiate et poussée peut être une exigence client, parce qu'on veut voir l'erreur sauter aux yeux de l'opérateur et pas seulement lui jeter une errorBox à la figure au moment de soumettre la transaction. On peut aussi dans ce cas imaginer un objet destiné à l'édition qui encapsule notre lettre et se sert des services pour assurer un maximum de pré-validation. Cependant, s'il est raisonnablement acceptable de faire la validation plus complexe dans le service qui se charge de l'enregistrement de l'objet saisi plutôt que dans les setteurs de cet objet, j'opterai plutôt pour cela. Citation:
- représente la façade métier (API de haut niveau sur les fonctionnalités du logiciel) - interagit avec la couche d'accès aux données. Citation:
Citation:
Citation:
En plus les entrées et sorties de ton application se font à travers et seulement à travers les services concernés, ce qui donne encore une abstraction convenable pour les éventuelles GUI et te permet aussi de bien contrôler ton accès aux sources de données. |
||||||
|
|
00
|
|
|
#17 | ||||
|
Expert Confirmé Sénior
![]() Inscription : janvier 2007 Messages : 9 594 ![]() |
Citation:
Citation:
Ce qui est décrit et à quoi tu réponds se pratique de manière absolument courante en procédural, sans que ça s'appelle "paradigme fonctionnel". Je crois qu'il y a eu une méconnaissance profonde de ce qui se faisait, et que des idées de recherche ont percé, portées par des formations et formateus n'ayant pas eu une vraie connaissance de ce qui se faisait... Il suffit de regarder le code de X11 : en C, écrit au début des années 80, fonctionnant totalement objet et avec ce que tu as l'air de nommer "fonctionel"... Citation:
Citation:
![]() Entièrement d'accord... Mais ça rejoint le second point... Fondamentalement je crois qu'il y a une méconnaissance profonde de l'antérieur, et une "théorisation" poussée qui veut mettre dans des cases ...
__________________
"Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle". Consultant indépendant. Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie. C, Fortran, XWindow/Motif, Java Je ne réponds pas aux MP techniques |
||||
|
|
00
|
|
|
#18 | |
|
Expert Confirmé Sénior
![]() Inscription : janvier 2007 Messages : 9 594 ![]() |
Juste un commentaire à propos de ce que _skip a relevé :
Citation:
Le but d'un bon soft c'est primo de bien fonctionner, et secondo d'être facile à maintenir.. A partir du moment où ces 2 conditions sont remplies, peu importe comment il a été fait ou sur quel paradigme il se base... Les gens qui te font ces remarques ne sont pas des "professionels", à mon sens, mais des gens avec des oeillères..
__________________
"Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle". Consultant indépendant. Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie. C, Fortran, XWindow/Motif, Java Je ne réponds pas aux MP techniques |
|
|
|
30
|
|
|
#19 | |
|
Membre confirmé
![]() Jérôme FrossardEnseignant Inscription : décembre 2007 Messages : 73 ![]() |
Citation:
|
|
|
|
10
|
|
|
#20 | |
|
Membre confirmé
![]() Jérôme FrossardEnseignant Inscription : décembre 2007 Messages : 73 ![]() |
Citation:
En outre, si les fonctions d'ordre supérieures sont nécessaires pour les langages fonctionnels, elles n'en sont pas l'apanage et sont effectivement monnaie courante dans les langages impératifs. Ce qui change peut-être c'est que dans la plupart des langage impératifs, les fonctions ne sont pas "first citizens" comme ils disent outre atlantique. |
|
|
|
00
|
Copyright © 2000-2013 - www.developpez.com