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

C++ Discussion :

API externe et Demeter


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 292
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 292
    Billets dans le blog
    2
    Par défaut API externe et Demeter
    Bonjour,

    une petite question existentielle concernant la loi de Demeter.
    Imaginons que, dans notre programme, nous utilisons un objet défini et implémenté dans une bibliothèque tierce. Disons que cet objet sert à envoyer du texte à un client, nous l’appellerons Sender. Concrètement, nous ne nous préoccupons pas de savoir comme s'y prend Sender; la seule chose qui nous importe c'est que lorsqu'on appelle Sender::send( my_string ) my_string soit bien envoyée au client. Mais tout de même, Sender propose tout un tas de fonctionnalités de "tuning", comme le réglage des time_out, des fonctionnalité concernant le cryptage, etc, et au final, le protocole (ensemble de fonctions membre publiques) de Sender est assez fourni.

    Afin de faciliter l'utilisation de Sender au sein de notre programme, nous décidons de l'encapsuler dans une classe à nous:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class MySender
    {
    public:
      // une fonction qui permet d'envoyer un tableau de string (ce que ne permet pas Sender)
      Send( const std::vector< std::string > & my_strings );
    // ainsi que d'autres fonctionnalités qui ajoutent des traitements avant d'envoyer les chaines de caratères
     
    private:
      Sender the_sender;
    };
    Mais, en plus de ces fonctionnalités, nous voudrions pouvoir utiliser directement toutes les fonctionalités de Sender. La première solution serait de faire en sorte que MySender wrappe le protocole de Sender: pour toutes les fonctions membres publiques de Sender, on implémente la même dans MySender et on appelle the_sender.the_fonction( the_parameters );

    Seulement le protocole de Sender est long, et on a la flemme de tout réécrire. De plus, cela parait un travail inutile puisqu'il suffirait que MySender puisse renvoyer une référence constante sur the_sender et on utiliserait directement le protocole de Sender. Sauf que, cela va à l'encontre de la loi de Demeter.

    Existe-t-il un autre solution que de redéfinir tout le protocole de Sender?

  2. #2
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    Salut

    Citation Envoyé par r0d Voir le message
    Afin de faciliter l'utilisation de Sender au sein de notre programme
    (...)
    nous voudrions pouvoir utiliser directement toutes les fonctionalités de Sender
    C'est pas un peu contradictoire ces 2 besoins ? Si ta classe contient au moins les mêmes fonctionnalités, alors elle n'est pas plus simple.

    Si l'objectif est de simplifier l'utilisation, alors ta classe est un "handler" (je sais pas s'il y a un terme spécifique), c'est à dire une classe conçu pour manipuler un autre. Elle doit alors proposer une interface simple, destiné à répondre uniquement au besoin. S'il y a plusieurs besoins, il faut plusieurs handler (respect du SRP).
    Un exemple d'une telle classe, c'est stringstream, pour manipuler une string comme un flux, ou les QDataStream et QTextStream, pour manipuler QIODevice et QByteArray comme des flux.
    Dans ce cas, la classe manipulée n'est pas un détail interne, mais bien une classe externe, accessible aussi au code appelant. Il n'y a pas de violation de Déméter.


    Si tu as besoin d'exposer l'interface complète de Sender sans pour autant utiliser directement Sender, ni hériter publiquement de Sender (par exemple, pour contrôler les entrées et sorties de Sender), dans ce cas, c'est effectivement un wrapper et tu n'as pas d'autre choix que réimplémenter toutes les fonctions une par une (comme simple accesseur ou en ajoutant des contrôles dans les fonctions). Voir par exemple QOpenGLFunctions qui est un wrapper entre OpenGL (lib C) et Qt (lib C++). Dans ce cas, la classe Sender devient un détail interne, mais n'est pas exposée (retourner un getter permettrait d'appeller Sender sans passer par les fonctions dédiées et les contrôles), donc pas de violation de Déméter non plus

    Guillaume

  3. #3
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 292
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 292
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par gbdivers Voir le message
    C'est pas un peu contradictoire ces 2 besoins ?
    Effectivement, maintenant que tu le dis...
    En fait c'est là que ma question n'est pas claire: on est entre 2 chaises. D'un côté on veut wrapper l'API, et d'un autre on veut juste l'utiliser.

  4. #4
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    2 besoins = 2 classes

  5. #5
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Une autre possibilité, c'est d'utiliser des fonctions libres.

    Souvent, l'interface "nouvelle" de ce type de wrapper est résumé à quelques fonctions, et aucune variable membre autre que le wrapper.

  6. #6
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Par défaut
    Une petite remarque.

    Soit on pense qu'on à besoin de construire une façade (parce que c'est une façade que tu propose, en encapsulant Sender), et dans ce cas la logique veut que rien de l'interface encapsulée ne soit visible par l'appelant (tu te sers de ta façade, point final). Du coup, tu est obligé de re-créer une interface de configuration de l'objet Sender sur ta façade (des objets conn_param, conn_optim, ... ?)

    Soit tu penses que c'est une bonne chose d'utiliser l'objet Sender en direct, et dans ce cas, tu n'as pas besoin de façade. Tu peux juste écrire une fonction ou deux pour encapsuler certains traitements particuliers qui son communs dans l'utilisation que tu fait de l'interface de Sender.

    Quoi qu'il en soit, les deux approches ne sont pas vraiment compatible
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Talend et API Externe
    Par chris81 dans le forum Développement de jobs
    Réponses: 0
    Dernier message: 21/02/2013, 18h56
  2. Licence GPL Mysql et code source, dans une API externe
    Par guillaume-13015 dans le forum Administration
    Réponses: 4
    Dernier message: 28/11/2012, 19h14
  3. Réponses: 0
    Dernier message: 13/01/2012, 16h44
  4. API externe, comment authentifier ?
    Par Phach dans le forum Langage
    Réponses: 4
    Dernier message: 06/01/2010, 10h40
  5. swf avec api externe dans un swf qui ce lance pas
    Par marcuscircus dans le forum ActionScript 3
    Réponses: 1
    Dernier message: 02/01/2010, 14h06

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