IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Design Patterns Discussion :

N'est-il pas un peu "sale" ?


Sujet :

Design Patterns

  1. #1
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 209
    Points
    23 209
    Par défaut N'est-il pas un peu "sale" ?
    Bonjour,

    Cela fait un petit moment que je m'interroge sur le DP décorateur le trouvant un peu "sale".
    Je n'ai pas vraiment de problèmes avec les autres DPs (à part le visiteur que je préfère éviter quand je peux), mais je bloque un peu pour le DP décorateur.

    Déjà parce que je trouve sa syntaxe un peu lourde surtout si on a plusieurs décorateurs (1) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MaClasse A = new DecorateurA( new DecorateurB( new DecorateurC( new ConcreteClasse ) ) );
    A partir d'un certain nombre de décorateur, cela devient illisible.

    Ensuite, parce que ajouter un décorateur change "l'instance" (2) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Chevalier a = new ConcreteChevalier;
    //....
    Chevalier b = new DecorateurBouclier(a);
    a n'est pas la même chose que b.
    Si on a des références sur a dans le code, si on rajoute un décorateur, soit il faut mettre à jour toute ces références soit on va utiliser a comme un chevalier dans un bout de code et comme un "Chevalier avec bouclier" ailleurs dans le code .

    De plus, le fait de ne pas pouvoir retirer un décorateur me semble pas "génial" (3).


    Je ne comprend donc pas pourquoi on a pas :
    • ConcreteChevalier héritant de/implémentant X ;
    • Decorateur héritant de/implémentant X ;
    • et une classe Chevalier se comportant comme un "proxy".


    Grosso-modo avoir :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Chevalier a = new Chevalier; // en interne créé un ConcreteChevalier
    for( int i = 0; i < NB ; ++i) // exemple
         a.add( decorateurs[i] );
    C'est à dire presque considérer Chevalier comme un "container" de Decorateurs ayant pour dernier élément un ConcreteChevalier.
    Je résous donc les problèmes 1,2 et 3.

    De plus, je trouve que c'est plus intuitif pour un utilisateur.
    Par exemple, quand on débute en Java et qu'on veut utiliser des fichiers, on ne comprend pas trop si on ne connaît pas le DP décorateurs.
    Alors qu'une syntaxe : Fichier( ConcreteFile cf, Filtre f...); me semble bien plus claire (Filtre = Décorateur).

    Pourquoi le DP décorateur est-il donc tel qu'il est ? Est-ce que je passe à côté de quelque chose ?
    En effet, si en Java on les utilise pour les I/O, et qu'on l'a intégré dans les DPs, je pense qu'il y a bien une raison.

  2. #2
    Membre émérite
    Inscrit en
    Janvier 2011
    Messages
    805
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Janvier 2011
    Messages : 805
    Points : 2 917
    Points
    2 917
    Par défaut
    Décorateur est utilisé quand on veut greffer une gamme de comportements optionnels et cumulatifs à une classe de base. Utiliser l'héritage pur serait peu pratique, car on devrait écrire autant de sous-classes que de combinaisons de comportements possibles.

    Le style de code qui découle de l'utilisation de Décorateurs peut paraitre répétitif car il reflète cette cumulativité. Pour autant, on n'est pas obligé de déclarer toutes les variables intermédiaires, on peut avoir :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Chevalier c = new DecorateurEpee( new DecorateurBouclier( new Chevalier()));
    A la base, le pattern Décorateur ne transforme pas un objet au runtime, parce qu'on n'en a pas vraiment besoin. Comme tu le dis, soit la classe cliente a une référence précise vers un objet décoré et n'aura jamais besoin de le re-décorer (90% des cas d'après mon expérience), soit s'il change, on lui repasse une nouvelle instance. Par contre, c'est inexact de dire que l'objet décoré est une instance totalement différente, car il contient une référence à l'objet d'origine, et non une copie de celui-ci.

    Ton système est plus dynamique et, peut-être, plus adapté pour un jeu où l'objet Chevalier va être transformé au cours du temps, acquérant des armes, des pouvoirs, subissant des effets... Mais ce n'est pas un Décorateur. Et il est aussi plus "dangereux", plus complexe et plus difficile à debugger puisqu'on peut ajouter et retirer à loisir des décorations. On peut être confronté à des situations compliquées lorsque plusieurs clients essaient de décorer / dé-décorer le même objet dans le même laps de temps.

  3. #3
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 209
    Points
    23 209
    Par défaut
    Merci pour votre réponse.


    A la base, le pattern Décorateur ne transforme pas un objet au runtime, parce qu'on n'en a pas vraiment besoin. Comme tu le dis, soit la classe cliente a une référence précise vers un objet décoré et n'aura jamais besoin de le re-décorer (90% des cas d'après mon expérience), soit s'il change, on lui repasse une nouvelle instance. Par contre, c'est inexact de dire que l'objet décoré est une instance totalement différente, car il contient une référence à l'objet d'origine, et non une copie de celui-ci.
    Disons que ce n'est pas exactement la même chose, si on a :
    Classe a = new ConcreteClasse();
    Classe b = new Decorateur(a);
    Utiliser a ou b, ce n'est pas la même chose, ce n'est pas le même comportement.
    Avec a, on court-circuite le décorateur.


    Mais ce n'est pas un Décorateur.
    Pourtant, on peut arriver au même résultat, non?

    Et il est aussi plus "dangereux", plus complexe et plus difficile à debugger puisqu'on peut ajouter et retirer à loisir des décorations.
    Rien n'oblige de permettre le retrait d'un décorateur si cela pose problème, si on le permet, c'est une fonctionnalités supplémentaire.
    Pour l'ajout, on peut avoir le même problème avec le DP décorateur je pense.

    On peut être confronté à des situations compliquées lorsque plusieurs clients essaient de décorer / dé-décorer le même objet dans le même laps de temps.
    Là c'est le problème "safe-thread", je pense que c'est un peu HS ici vu que cela est un détail d'implémentation et qu'on peut rendre le tout safe-thread assez aisément.


    Mais oui, je commence à comprendre un peu mieux.
    Par contre, cela veut dire qu'il faut faire attention à bien utiliser le DP Décorateur correctement et faire toute la décoration au même "endroit". Je trouve que c'est relativement dangereux.

  4. #4
    Membre émérite
    Inscrit en
    Janvier 2011
    Messages
    805
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Janvier 2011
    Messages : 805
    Points : 2 917
    Points
    2 917
    Par défaut
    Citation Envoyé par Neckara Voir le message
    Pourtant, on peut arriver au même résultat, non?
    On peut bien sûr arriver au même résultat, mais avec des différences dans l'utilisation et des fonctionnalités en plus dans ce que tu proposes. Personnellement, je trouve la forme monobjet.add(decorateur) moins révélatrice que new Decorateur(monobjet) qui indique bien qu'on va enrober l'objet d'origine avec une nouvelle couche de fonctionnalités, mais c'est un point de vue.

    Citation Envoyé par Neckara Voir le message
    Là c'est le problème "safe-thread", je pense que c'est un peu HS ici vu que cela est un détail d'implémentation et qu'on peut rendre le tout safe-thread assez aisément.
    Je ne parlais pas forcément d'un contexte multi-thread, mais d'un accès partagé à l'objet de manière générale. Avec ta solution, c'est possible que deux clients qui ont une référence au même objet décoré soient tentés de le re-décorer dans leur coin. Puisque si j'ai bien compris, la liste des décorations est une chaine dont le point d'entrée est forcément le dernier ajouté, cela affecte alors l'autre client qui n'a rien demandé à personne. Avec la solution classique, ça ne peut pas arriver. Je ne dis pas que ça se produira tout le temps, mais il y a un risque. On introduit aussi la notion de temporalité, l'ordre de décoration par les différents consommateurs compte : quel objet a ajouté une décoration en dernier ? Quand on tombe dans ce genre de cas, c'est beaucoup plus difficile de raisonner sur ce qui se passe au runtime : on est obligé de debugger et c'est souvent pénible.

    Citation Envoyé par Neckara Voir le message
    Par contre, cela veut dire qu'il faut faire attention à bien utiliser le DP Décorateur correctement et faire toute la décoration au même "endroit". Je trouve que c'est relativement dangereux.
    Pourquoi au même endroit ? Ce n'est pas une obligation. Deux consommateurs peuvent avoir, à des moments différents, besoin du même objet décoré différemment. Le pattern ne l'empêche pas. Et pourquoi dangereux ?

  5. #5
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 209
    Points
    23 209
    Par défaut
    Si l'objet est décoré différemment dans deux consommateurs, c'est très dangereux dans le sens où les comportements vont être indéterminés, si on a des buffers par exemple.

    De plus, un décorateur peut "garantir un certain état", état qui ne sera plus garanti car on le court-circuitera.
    Court-circuiter un décorateur en place me semble "dangereux" non?

    Le fait qu'une décoration affecte toute les instances me semble plus "logique".
    Après, il y a en effet une certaine temporalité, mais cela ne me choque pas tant que cela.

  6. #6
    ego
    ego est déconnecté
    Rédacteur

    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Juillet 2004
    Messages
    1 883
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Architecte de système d'information
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2004
    Messages : 1 883
    Points : 3 510
    Points
    3 510
    Billets dans le blog
    2
    Par défaut
    Je ne comprend pas bien ton problème.
    Un décorateur est un objet X si X décrit les types d'objets que tu veux manipuler.
    On peut décorer le même objet concret x de type X dans 2 contextes différents car on aura des usages différents.
    Ce pattern est vraiment très utilisé.

  7. #7
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 209
    Points
    23 209
    Par défaut
    Si tu décores un même objet x de deux manière différentes dans deux contextes différent, tu risques d'avoir des incohérences dû au fait que derrière tu manipules le même objet.

    Déjà, rien que si un décorateur a un buffer, cela peut poser problème.
    On peut aussi obtenir, via un décorateur un objet dans un état invalide pour un autre décorateur.

    En somme la décoration du contexte 1 va court-circuiter la décoration du contexte 2 et inversement.
    Pour moi, cela est très sale.

    Par exemple ton chevalier décoré d'un MasqueAGaz dans un contexte1 pourrait se retrouver dans un état "intoxiqué" via le contexte2, ce qui n'a absolument aucun sens dans le contexte1.

  8. #8
    ego
    ego est déconnecté
    Rédacteur

    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Juillet 2004
    Messages
    1 883
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Architecte de système d'information
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2004
    Messages : 1 883
    Points : 3 510
    Points
    3 510
    Billets dans le blog
    2
    Par défaut
    Mais en fait tout dépend du pourquoi tu décores.
    On ne passe pad un objet décoré pour un contexte 1 à un contexte 2.
    Et puis ce n'est pas vraiment l'objet décoré que tu manipules, si je puis dire, mais le décorateur qui a une référence vers ton instance concrète. ..et toute la différence est là.

  9. #9
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 209
    Points
    23 209
    Par défaut
    Citation Envoyé par ego Voir le message
    Et puis ce n'est pas vraiment l'objet décoré que tu manipules, si je puis dire, mais le décorateur qui a une référence vers ton instance concrète. ..et toute la différence est là.
    Oui, c'est un peu cela le problème.

    Sauf que si on manipule le décorateur non plus comme "objet décoré" mais comme "décorateur ayant une référence vers l'objet décoré", ce n'est plus vraiment dans l'esprit du DP décorateur.

    Si je caricature, un décorateur, c'est une tunique que tu mets à ton héros et qui modifie son comportement (ex. il ne peut plus courir).
    Là ce qu'on fait, c'est une classe qui permet de manipuler un héros et qui se comporte comme une sorte de "proxy"/"façade".
    Je trouve que la philosophie est différente même si le code peut être similaire, on est plus dans une logique de "décorer" mais "d'utiliser". Sachant que si le décorateur se contente d'ajouter des méthodes, ce n'est plus tout à fait un décorateur.

  10. #10
    ego
    ego est déconnecté
    Rédacteur

    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Juillet 2004
    Messages
    1 883
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Architecte de système d'information
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2004
    Messages : 1 883
    Points : 3 510
    Points
    3 510
    Billets dans le blog
    2
    Par défaut
    Bon bref tu n'es pas emballé par ce pattern. ..pourtant utilisé
    Mais c'est pas grave...

  11. #11
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 209
    Points
    23 209
    Par défaut
    Citation Envoyé par ego Voir le message
    ..pourtant utilisé
    Hey ! Y'a bien des personnes qui utilisent l'API Windows…




    Peut être que j'aurais une illumination un jour, mais j'avoue que je suis pour le moment septique.

  12. #12
    Membre habitué
    Profil pro
    Inscrit en
    Août 2006
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 89
    Points : 170
    Points
    170
    Par défaut
    Bonjour,

    Concernant la question initiale, je pense que Luckyluck34 a indiqué les éléments les plus pertinents.
    J'ajouterais que le DP décorateur permet de supprimer des fonctionnalités à un objet, ce qui n'est pas possible lorsqu'il s'agit d'une liste de fonctionnalités supplémentaires.
    L'autre avantage du DP décorateur est qu'il n'ajoute de traitements QUE sur les objets concernés.
    S'il y a 1000 instances de chevalier, et une seule qui a un décorateur, seule celle-ci aura des traitements supplémentaires.
    Pour les autres, pas de liste à posséder et à parcourir, pas de conditions à vérifier, rien du tout.

    Par contre je ne suis pas sûr de comment vous implémenteriez votre proposition.
    Chaque décorateur a probablement des méthodes qui lui sont propres et non partagées avec les autres décorateurs (et encore moins avec la classe d'origine).
    Pour appeler la méthode decorateurBouclier::rangeBouclier() sur un objet chevalier (pour qu'il se déplace plus rapidement par exemple), comment procédez-vous?

    Personnellement (je peux me tromper!) avec le DP décorateur, je ne vois pas de cas d'utilisation où stocker une référence sur l'objet original (ailleurs que dans le décorateur) serait nécessaire.
    Je conçois un objet décoré comme un objet qui aura ses fonctionnalités modifiées du début à la fin de sa vie. Un peu comme s'il s'agissait d'un héritage.
    Donc s'il y a un besoin sur la suppression d'une décoration, une solution comme celle que vous proposez est plus adéquate, c'est certain.

    Sinon je réagis à votre phrase :
    On peut aussi obtenir, via un décorateur un objet dans un état invalide pour un autre décorateur.
    Si c'est le cas, c'est qu'il y a un problème de conception, ce n'est pas lié au DP lui-même.
    Pour reprendre votre exemple sur le masque à gaz, il y a deux cas :
    1. C'est la classe chevalier possède une propriété "estIntoxiqué".
      C'est donc à la classe chevalier de gérer les différents cas (une propriété "possèdeMasqueAGaz" typiquement)
      et de s'assurer de la cohérence des opérations.
    2. C'est votre décorateur qui implémente cette propriété "estIntoxiqué" (et "possèdeMasqueAGaz" par extension),
      donnant une classe décorateurIntoxicable plutôt que décorateurMasqueAGaz.
      C'est donc ce décorateur qui doit gérer seul cette cohérence masqueAGaz/intoxiqué.
      Il ne transfère jamais le statut "intoxiqué" à la classe chevalier.
      Il indique uniquement une diminution de la santé à intervalle régulier par exemple.

    Selon moi, sur cet exemple, le risque d'obtenir des données invalides est donc uniquement lié à un non respect de l'encapsulation.

    En revanche, je n'ai pas vraiment compris la problématique que vous indiquez concernant les buffers.

  13. #13
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 209
    Points
    23 209
    Par défaut
    Citation Envoyé par tristan_m Voir le message
    Chaque décorateur a probablement des méthodes qui lui sont propres et non partagées avec les autres décorateurs (et encore moins avec la classe d'origine).
    S'il ajoute des méthodes publique, peut-on dire que c'est encore un DP décorateur ?

    Pour appeler la méthode decorateurBouclier::rangeBouclier() sur un objet chevalier (pour qu'il se déplace plus rapidement par exemple), comment procédez-vous?
    Le problème, c'est qu'il faudrait déjà savoir si le chevalier a un "decorateurBouclier" ensuite, il faudrait que tous les décorateurs ajoutés ensuite soient compatibles avec le décorateurBouclier.
    C'est donc assez sale de rajouter des méthodes via des décorateurs non?

    Cela implique deux choses :
    • un ordre pour "empiler" les décorateurs ;
    • un code fermé aux extensions.


    Personnellement (je peux me tromper!) avec le DP décorateur, je ne vois pas de cas d'utilisation où stocker une référence sur l'objet original (ailleurs que dans le décorateur) serait nécessaire.
    Je conçois un objet décoré comme un objet qui aura ses fonctionnalités modifiées du début à la fin de sa vie. Un peu comme s'il s'agissait d'un héritage.
    En effet, par contre, c'est dommage qu'on ne puisse pas garantir que la seule référence soit dans le décorateur grâce à "l'UML"/architecture du DP. Ce qui permet une "mauvaise" utilisation du DP.


    C'est la classe chevalier possède une propriété "estIntoxiqué".
    C'est donc à la classe chevalier de gérer les différents cas (une propriété "possèdeMasqueAGaz" typiquement)
    et de s'assurer de la cohérence des opérations.
    Je ne suis pas d'accord.

    Tu codes une classe chevalier qui peut être intoxiqué.
    Il est hors de question de modifier la classe chevalier quelques mois plus tard pour lui ajouter un "masqueAGaz" qui l'immunise, un ans plus tard un "vaccin" qui réduit l'effet du poison, …
    Là le code est ouvert aux modifications, on a une erreur de conception quelque part.


    C'est votre décorateur qui implémente cette propriété "estIntoxiqué" (et "possèdeMasqueAGaz" par extension),
    donnant une classe décorateurIntoxicable plutôt que décorateurMasqueAGaz.
    C'est donc ce décorateur qui doit gérer seul cette cohérence masqueAGaz/intoxiqué.
    Il ne transfère jamais le statut "intoxiqué" à la classe chevalier.
    Il indique uniquement une diminution de la santé à intervalle régulier par exemple.
    C'est en effet une idée intéressante.
    Sauf que, pour moi, le serpent se mort la queue. on a un chevalierIntoxicable et on le décore avec un chevalierImmunisé.
    Au final, on ne fait que reporter le problème de chevalier vers chevalierIntoxicable.

    En revanche, je n'ai pas vraiment compris la problématique que vous indiquez concernant les buffers.
    Juste que c'est une horreur
    Par exemple faire des lectures/écritures dans un fichier.
    On a r1 qui a un buffer par bloc, r2 qui n'a pas de buffer et qui lisent le même fichier, bonjour les comportements indéterminés .
    La seule solution, c'est de briser l'encapsulation pour comprendre comment fonctionne les buffers pour essayer de voir ce qu'il est possible de faire .

  14. #14
    Membre habitué
    Profil pro
    Inscrit en
    Août 2006
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 89
    Points : 170
    Points
    170
    Par défaut
    Bonjour,

    C'est donc assez sale de rajouter des méthodes via des décorateurs non?
    Vous avez raison, c'est moi qui n'avais pas saisi ce point sur le DP.
    Il ne se prête pas vraiment à l'ajout de méthodes publiques. Merci pour cet éclaircissement
    Le point suivant est d'ailleurs invalidé :
    J'ajouterais que le DP décorateur permet de supprimer des fonctionnalités à un objet, ce qui n'est pas possible lorsqu'il s'agit d'une liste de fonctionnalités supplémentaires.
    Après un peu plus de recherche, stocker la référence ailleurs que dans le décorateur est tout à fait légitime.
    Notamment parce que l'objet original peut posséder des méthodes/propriétés qui ne sont pas disponibles depuis l'interface (et donc pas disponibles depuis les décorateurs non plus).
    Il y a donc la possibilité de contourner la décoration, ce qui peut être difficile à debugguer si ce n'est pas le comportement souhaité.
    Une règle pourrait être de dire que seules les méthodes spécifiques des objets décorés doivent être utilisées lorsque l'objet est appelé directement,
    mais il est difficile/impossible de garantir un telle règle au cours d'un projet (surtout une règle d'une telle complexité).
    Je considère donc également que l'utilisation de ce DP comporte un risque.

    Il est hors de question de modifier la classe chevalier quelques mois plus tard pour lui ajouter un "masqueAGaz" qui l'immunise, un ans plus tard un "vaccin" qui réduit l'effet du poison, …
    Si vous avez ce type de contrainte, par exemple la classe Chevalier est dans une bibliothèque externe dont le code n'est pas accessible,
    la "saleté" ne vient pas du DP, mais du fait de devoir gérer une même responsabilité par différentes classes pour pouvoir contourner cette contrainte.

    Pour ce dernier point, le problème est également présent dans votre proposition :
    Les décorateurs sont susceptibles de s'invalider l'un avec l'autre ET avec les méthodes de l'objet concret qui ne sont pas dans l'interface.
    Ce n'est donc pas un problème lié au DP.

  15. #15
    Membre émérite
    Inscrit en
    Janvier 2011
    Messages
    805
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Janvier 2011
    Messages : 805
    Points : 2 917
    Points
    2 917
    Par défaut
    Citation Envoyé par Neckara Voir le message
    Juste que c'est une horreur
    Par exemple faire des lectures/écritures dans un fichier.
    On a r1 qui a un buffer par bloc, r2 qui n'a pas de buffer et qui lisent le même fichier, bonjour les comportements indéterminés .
    Je ne vois pas très bien ce que le pattern Décorateur a à voir là dedans. En quoi cette pratique serait-elle plus ou moins absurde avec un décorateur (qui au passage n'apporte rien à l'histoire) ? Ce pattern ne peut pas être un prétexte pour faire des choses illogiques. Il est avant tout là pour ajouter du comportement. Deux décorateurs différents autour d'un même objet utilisés dans deux contextes différents ne doivent pas entrer en conflit, ou alors c'est qu'il y aurait eu un problème de toute manière même si l'objet n'avait pas été décoré.

  16. #16
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 209
    Points
    23 209
    Par défaut
    C'est pourtant de cette façon que sont implémentés les flux et leur manipulation en Java si je ne me trompe pas.

    Deux décorateurs différents autour d'un même objet utilisés dans deux contextes différents ne doivent pas entrer en conflit
    Comment peux-tu garantir cela ?

  17. #17
    Membre émérite
    Inscrit en
    Janvier 2011
    Messages
    805
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Janvier 2011
    Messages : 805
    Points : 2 917
    Points
    2 917
    Par défaut
    Citation Envoyé par Neckara Voir le message
    C'est pourtant de cette façon que sont implémentés les flux et leur manipulation en Java si je ne me trompe pas.
    Donc l'API de manipulation de flux en Java est "une horreur", juste parce qu'on peut partir du même flux et le décorer différemment à deux endroits ?

    Citation Envoyé par Neckara Voir le message
    Comment peux-tu garantir cela ?
    En faisant en sorte que le "ou alors" (la deuxième partie de ma phrase) n'arrive pas. C'est à dire en n'utilisant pas de façon dangereuse et illogique un Décorateur qui rajoute le comportement Y. Exactement de la même manière qu'on n'utiliserait pas l'héritage, le pattern Visiteur ou que sais-je pour ajouter ce comportement Y et l'utiliser de façon dangereuse et illogique.

    Au passage, je ne vois pas non plus en quoi ta version "container de décorateurs" résout mieux le problème (si tant est qu'on soit d'accord sur le problème )

  18. #18
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 209
    Points
    23 209
    Par défaut
    Je ne vois pas en quoi ce serait illogique.

    Les DP sont là pour nous éviter de "faire des bêtises" et avoir un code ouvert aux extensions, fermés aux modifications.
    Si on peut utiliser le DP de façon "dangereuse et illogique" facilement sans le faire vraiment exprès, je ne vois plus trop sont intérêt.

    De plus, ce n'est pas vraiment ajouter un comportement mais le modifier ici.

    Au passage, je ne vois pas non plus en quoi ta version "container de décorateurs" résout mieux le problème (si tant est qu'on soit d'accord sur le problème )
    On ne peut pas décorer le même objet de deux manières différentes vu que l'instance concrète est encapsulée dans le "proxy".

    Donc l'API de manipulation de flux en Java est "une horreur", juste parce qu'on peut partir du même flux et le décorer différemment à deux endroits ?
    Disons qu'il est tout d'abord très peu intuitif pour un débutant.

    Mais c'est toi qui a dit:
    Deux décorateurs différents autour d'un même objet utilisés dans deux contextes différents ne doivent pas entrer en conflit

    En faisant en sorte que le "ou alors" (la deuxième partie de ma phrase) n'arrive pas.
    Je ne penses pas que ce soit une condition suffisante, car il n'y a aucun soucis de buffer si on utilise des versions des flux non-décorés.

    EDIT : on se répond depuis plusieurs posts, je pense qu'il faudrait qu'on commence à repréciser de quoi on parle pour éviter toute ambiguïté (en donnant un exemple de code ou que sais-je).

  19. #19
    Membre expérimenté Avatar de yann2
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2004
    Messages
    897
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2004
    Messages : 897
    Points : 1 635
    Points
    1 635
    Par défaut
    Bonjour

    L'exemple que vous donnez n'est pas un bon exemple. Autant, quand on lit un flux, il n'y a pas besoin de savoir si on doit passer par un tampon, chiffrer des données, etc. autant pour un Chevalier vous allez certainement devoir gérer une liste d'équipements. Enfin, je sais bien que vous donnez juste un exemple mais c'est comme si on avait un décorateur FenetreAvecBouton qui décore une Fenetre pour afficher un bouton dans une fenêtre. La fenêtre devrait connaitre ses petiots ^^ je pense que le chevalier devrait connaitre son équipement

    Sinon pour l'alternative que vous donnez, c'est effectivement plus pratique pour gérer le cycle de vie de l'instance Chevalier mais derrière vous utilisez quand même le décorateur, du coup ? Je pense que vous avez juste un soucis de cycle de vie de votre instance qui se révèle par l'application du patron décorateur puisque celui ci implique une création d'une nouvelle instance. Votre poignée (proxy) est maintenant l'objet responsable du cycle de vie du Chevalier et ce n'est pas un mal

    Personnellement, j'utilise le patron décorateur essentiellement sur des API sur lesquelles je n'ai pas le contrôle ou pour faire un simili d'orienté aspect (c'est le cas de l'api des flux en java, d'ailleurs). Mais le meilleur patron de conception est la simplicité (et là, pour le coup, dans l'exemple une simple composition et c'est réglé (bon... avec quand même un modèle objet un peu réfléchi, évidemment))

    Yann

  20. #20
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 209
    Points
    23 209
    Par défaut
    Citation Envoyé par yann2 Voir le message
    c'est comme si on avait un décorateur FenetreAvecBouton qui décore une Fenetre pour afficher un bouton dans une fenêtre. La fenêtre devrait connaitre ses petiots ^^
    Vous allez rire mais c'est exactement un des exemple qu'on nous a donné en cours pour le DP décorateur.

    FenêtreAvecScrollBarre, FenêtreAvecMenu, FenêtreAvecBouton…
    À ce qui parait, ce serait utilisé dans certains logiciels.

    mais derrière vous utilisez quand même le décorateur, du coup ?
    Oui, mais le décorateur sera "derrière" le "proxy".


    Je pense que je vais changer ma question en :
    Quand faut-il utiliser le DP décorateur et comment ? Quand ne faut-il surtout pas l'utiliser et que ne faut-il surtout pas faire avec?
    Car pour le moment, ce n'est pas très clair pour moi.

Discussions similaires

  1. Réponses: 3
    Dernier message: 11/10/2011, 10h17
  2. premier pas... un peu bizarre
    Par gaia-harastra dans le forum PostgreSQL
    Réponses: 4
    Dernier message: 10/01/2006, 10h00

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo