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

Langage C++ Discussion :

[conception] Respectabilité du SRP


Sujet :

Langage C++

  1. #21
    Membre confirmé Avatar de Lavock
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 560
    Points : 633
    Points
    633
    Par défaut
    Entièrement d'accord !
    ...
    ...
    ...
    ...
    Mais je ne vois pas comment faire >< ! Le but, est au final celui annoncé dans le titre. Je n'arrive pas à respecter le SRP...

    Bon, je vais résumer l'architecture global juste au cas ou quelqu'un est une idée lumineuse... ou est déjà connue le problème :

    J'ai un client, qui d'une quelconque manière est mis en relation avec un objet (qu'on appellera "localisable"). Ce qui interesse ce client, c'est divers renseignement spatial + la composition matériel à un endroit précis.
    Les renseignement spatial sont évaluer en fonction de l'implémentation de localisable.
    "L'endroit précis" est d'ailleurs acquis par ces données spatiales.

    Côté fournisseur, j'ai une implémentation spatial spécifique et ses données + différent type d'organisation de la composition spatial (appelé "texture"). Certaine texture sont incompatible avec certain localisable, ou alors la requête pour trouver "L'endroit précis" ne peut-être généralisé pour certain couple texture/localisable.

    La question c'est évidemment comment faire pour respecter ce fichu SRP ! (Dans le but bien sûre de ne pas à avoir à modifier les implémentation de texture/localisable dans le cas d'un ajout de localisable/texture...

    Je sais que c'est mon boulot, mais le novice que je suis coince >< ! J'espère avoir était plus claire cette fois ! Merci de passer autant de temps à m'aider en tout cas koala !
    The mark of the immature man is that he wants to die nobly for a cause, while the mark of the mature man is that he wants to live humbly for one.
    --Wilhelm Stekel

  2. #22
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 612
    Points
    30 612
    Par défaut
    Un "petit coup" de programmation générique peut te permettre de résoudre simplement ton problème

    Tu crées une structure template proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    template<class T, class U>
    struct check
    {
        void operator()(T const &, U const &)
        {
            //ne fait rien par défaut
        }
    };
    que tu spécialise pour chaque couple Localisable <-> texture invalide sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    template <>
    struct check<typeLocalisabelParticulier, TextureInvalide>
    {
        void operator(typeLocalisabelParticulier const &, TextureInvalide const &)
        {
            throw TextureInvalide(" nom type particulier", "nom de la texture");
        }
    };
    et tu transforme la fonction addMaterial en
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void Mediateur::addMaterial(Localisable* L, Texture * T)
    {
        /*toute l'astuce se trouve à cette ligne-ci */
        check(*L, *T);
        /*...suite de l'ajout de texture */
    }
    De cette manière, s'il n'y a pas concordance avec l'une des spécialisations, check ne fait, purement et simplement, rien...

    Par contre, s'il y a concordance, une exception est levée, et tu as empêché un objet localisable d'être relié à une texture qu'il ne peut pas utiliser...

    J'ai choisi l'option de lancer une exception (qu'il faut que tu définisse), mais ce pourrait tout aussi bien être une assertion en mode debug

    EDIT je suis parti du principe que les couples invalides sont minoritaire, mais on pourrait parfaitement envisager d'inverser la logique si d'aventure il y avait plus de couples invalides que de couples valides
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  3. #23
    Membre confirmé Avatar de Lavock
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 560
    Points : 633
    Points
    633
    Par défaut
    !

    Et pour :

    Citation Envoyé par Lavock Voir le message
    ou alors la requête pour trouver "L'endroit précis" ne peut-être généralisé pour certain couple texture/localisable.
    Je peux peut-être "généraliser" cette méthode ! Bon, je cogite, en tout cas mille fois merci !
    The mark of the immature man is that he wants to die nobly for a cause, while the mark of the mature man is that he wants to live humbly for one.
    --Wilhelm Stekel

  4. #24
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    template<class T, class U>
    struct check
    {
        void operator()(T const &, U const &)
        {
            //ne fait rien par défaut
        }
    };
     
    template <>
    struct check<typeLocalisabelParticulier, TextureInvalide>
    {
        void operator(typeLocalisabelParticulier const &, TextureInvalide const &)
        {
            throw TextureInvalide(" nom type particulier", "nom de la texture");
        }
    };
    Moi, je ferai l'inverse :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    struct check
    {
        void operator()(T const &, U const &); // non implémenté par défaut
    };
     
    template <>
    struct check<typeLocalisabelParticulier, Texturevalide>
    {
        void operator(typeLocalisabelParticulier const &, TextureInvalide const &)
        {
            return; // ne fait rien pour tout type valide
        }
    };
    Certes, ça peut être plus lourd à générer (quoiqu'avec un tableur, ça se fasse bien), mais au moins, ça pète à la compilation.

  5. #25
    Membre confirmé Avatar de Lavock
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 560
    Points : 633
    Points
    633
    Par défaut
    C'est sûre que ça pourrait être mieux, mais mes objets et les associations sont faite au runtime >< !
    The mark of the immature man is that he wants to die nobly for a cause, while the mark of the mature man is that he wants to live humbly for one.
    --Wilhelm Stekel

  6. #26
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 612
    Points
    30 612
    Par défaut
    Citation Envoyé par Lavock Voir le message
    Je peux peut-être "généraliser" cette méthode ! Bon, je cogite, en tout cas mille fois merci !
    Désolé... NiepoNimaï, moi pas comprendre

    Ici, l'idée est simple: si on empêche de créer une relation invalide, toutes celles qui restent... seront forcément valides, et il n'y a, a priori, pas lieu de vérifier d'avantage

    Mais bon, tu peux utiliser check(/*...*/) strictement ou tu veux, y compris en "amont" de l'invocation de addMaterial... ou dans un contexte tout à fait différent
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  7. #27
    Membre confirmé Avatar de Lavock
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 560
    Points : 633
    Points
    633
    Par défaut
    En gros, cela résoud le problème des cas invalides. Mais reste le problème ou les méthode ne sont pas généralisable.

    Jusque là, j'essayais bêtement de rester dans mes deux classes, alors qu'en faite, je peux très bien passer par une fonction/classe interprète que je peux implémenter n'importe où. C'est ça la généralisation ! Il faut quand même que je regarde si c'est faisable correctement.
    The mark of the immature man is that he wants to die nobly for a cause, while the mark of the mature man is that he wants to live humbly for one.
    --Wilhelm Stekel

  8. #28
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 612
    Points
    30 612
    Par défaut
    Citation Envoyé par white_tentacle Voir le message
    Moi, je ferai l'inverse :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    struct check
    {
        void operator()(T const &, U const &); // non implémenté par défaut
    };
     
    template <>
    struct check<typeLocalisabelParticulier, Texturevalide>
    {
        void operator(typeLocalisabelParticulier const &, TextureInvalide const &)
        {
            return; // ne fait rien pour tout type valide
        }
    };
    Certes, ça peut être plus lourd à générer (quoiqu'avec un tableur, ça se fasse bien), mais au moins, ça pète à la compilation.
    Ainsi que mon édition le laisse penser, je crois que la meilleure solution sera celle qui colle "le mieux" à la situation...

    J'ai chois d'avoir, par défaut, l'accord d'ajouter une structure, toi de la refuser...

    J'ai choisi le traitement à l'exécution, et toi à la compilation..

    Deux points de vue proposant chacun une alternative nous donnant quatre possibilités, la meilleure solution sera, forcément, celle qui correspondra au cas général observé (majorité de couple autorié VS majorité de couples interdit; ajout de textures par l'utilisateur VS ajout de textures par le programmeur)

    Il faut "juste" voir "de quel coté on joue"
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  9. #29
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 612
    Points
    30 612
    Par défaut
    Citation Envoyé par Lavock Voir le message
    En gros, cela résoud le problème des cas invalides. Mais reste le problème ou les méthode ne sont pas généralisable.

    Jusque là, j'essayais bêtement de rester dans mes deux classes, alors qu'en faite, je peux très bien passer par une fonction/classe interprète que je peux implémenter n'importe où. C'est ça la généralisation ! Il faut quand même que je regarde si c'est faisable correctement.
    Ah, ok... je comprend ce que tu veux dire...

    Là encore, la programmation générique a de bonnes chances de te venir en aide.

    Un petit tour du coté du tutoriel de Alp au sujet des traits et politiques devrait te mettre sur la voie
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  10. #30
    Membre confirmé Avatar de Lavock
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 560
    Points : 633
    Points
    633
    Par défaut

    Hum, mais comment ça peut marcher si c'est à l'exécution justement >< ! L'appelle à check(*L,*T) utilisera toujours l'instance de Template pour les interfaces Localisable et Texture, non pas leur implémentation >< !

    Le principe est bon cela dit, il suffit juste que je trouve la bonne fonction à appeler au runtime.

    Bon, je continue à cogiter >< !
    The mark of the immature man is that he wants to die nobly for a cause, while the mark of the mature man is that he wants to live humbly for one.
    --Wilhelm Stekel

Discussions similaires

  1. [Concept] Métadatas ?
    Par melinda dans le forum Décisions SGBD
    Réponses: 5
    Dernier message: 10/11/2004, 11h56
  2. [Concept] Réplication
    Par melinda dans le forum Décisions SGBD
    Réponses: 4
    Dernier message: 31/03/2003, 17h29
  3. [Concept] BD ou Gestion par fichier. Intérêt de la BD ?
    Par Cian dans le forum Décisions SGBD
    Réponses: 3
    Dernier message: 28/11/2002, 12h16
  4. [Concept] Curseur coté client et curseur coté serveur
    Par freud dans le forum Décisions SGBD
    Réponses: 2
    Dernier message: 13/09/2002, 22h13
  5. [Concept] Stabilité d'une base de donnée
    Par lassmust dans le forum Décisions SGBD
    Réponses: 3
    Dernier message: 03/07/2002, 16h16

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