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

Qt Discussion :

Signal/Slot : Quand ne pas les utiliser ?


Sujet :

Qt

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 27
    Points : 46
    Points
    46
    Par défaut Signal/Slot : Quand ne pas les utiliser ?
    Bonsoir à tous,

    Pour certains d'entre vous, ma question aurait plus sa place dans le forum de conception, les Signals / Slots étant l'implémentation du design pattern Observateur. Pourtant, mon "problème" se situe purement au niveau de l'implémentation. Je m'explique :

    En train de découvrir progressivement Qt, je suis tombé sur le mécanisme de signal/slot qu'après quelques expérimentations je trouve extrêmement puissant.
    Au fur et à mesure de l'implémentation des méthodes de mes classes, je me rends compte que je me pose systématiquement la même question pour chaque méthode publique qui renvoie void : même si je ne l'ai pas prévu conceptuellement, pourquoi je ne l'implémenterais pas sous forme de slot ? Elle restera appelable comme une méthode classique, ça me coûte simplement de déplacer sa déclaration de la zone "public:" à la zone "public slots:" (et d'hériter de QObject, ce qui ne me dérange pas), pour y gagner la possibilité de connecter n'importe quel signal assez facilement (notamment ceux générés par les widgets graphiques).

    Les seuls points faibles que je vois sont que ça me bloquerait pour l'héritage multiple (qui m'empêcherait de dériver de plusieurs classes elles-mêmes héritant de QObjet), et que les méthodes renvoyant autre chose que void ne sont pas éligibles.

    Dans la mesure où je n'utilise pas l'héritage multiple pour ce projet, et comme la perte de performance semble négligeable, ça me parait un peu un outil "magique", qu'il est tentant d'utiliser systématiquement. Comme je sais que les outils parfaits n'existent pas, quels sont ses autres points faibles que je ne vois pas, et dans quels cas n'utiliseriez-vous pas ce mécanisme ?

    Merci.

  2. #2
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Points : 2 161
    Points
    2 161
    Par défaut
    salut,

    quelques axes de réflexiontout personnels (je ne prétend surtout pas avoir une réponse exhaustive et définitive sur le sujet, bien au contraire):

    Tu as raison concernant l'aspect technique: rien ne t'empêche de transformer n'importe quel fonction 'void' en slot pour un surcoût (pratiquement) négligeable en perfs et peu de contraintes supplémentaires pour peu que dériver de QObject ne te pose pas de soucis.

    C'est finalement un peu la même idée que la visibilité de tes données membres: au final, n'importe quelle donnée membre de tes classes pourrait très bien être mise en 'public' et - techniquement parlant - ton code marcherait tout aussi bien.

    Quand on met une certaine portée à une donnée dans une classe, le but principal est avant tout d'organiser le code en ajoutant de la signification à la donnée elle-même. Par exemple, si je mets un 'private', celui qui relit le code (quelqu'un d'autre ... ou même moi, six mois après) comprendra immédiatement "attention: cette donnée assure uniquement le fonctionnement interne de la classe ; elle n'a pas pour but d'exposer quoi que ce soit aux utilisateurs tiers (autres classes, autres développeurs)".

    Je prends personnellement le choix 'fonctions simples' vs. 'signaux/slots' à peu près au même niveau: techniquement, le changement est facile, mais il a aussi et surtout une signification sur l'utilité et l'utilisation de ladite fonction.

    Notamment:

    - les signaux/slots sont surtout là pour répondre à un besoin de découplage entre l'appelant et l'appelé: le but est de permettre à un objet de recevoir des notifications ou d'émettre des événements par/depuis un autre objet dont elle ne connait absolument rien. Dans ce cadre, je limite souvent mon usage à des classes amenées à interagir avec des autres classes bien distinctes et qui n'ont pas grand chose à voir en terme de 'sémantique'.
    Par exemple son utilisation me semble indiquée entre un widget graphique (un bouton) et un objet métier.
    Par contre, utiliser un signal/slot pour qu'une classe SocketConnexion prévienne sa classe parente NetworkManager (qui maintient un pool de SocketConnexions) que la socket vient d'être déconnectée me semble un peu exagéré. Je préfère alors mettre un pointeur 'NetworkManager*' dans chaque SocketConnexion et l'utiliser pour notifier la déconnexion. C'est tout de suite plus parlant au niveau du code: une lecture en diagonale du header de SocketConnexion montre immédiatement qu'elle est hautement couplée à NetworkManager et qu'elle sera amenée à intéragir avec ; info que tu perds avec des signaux/slots (il faudra lire le code lui-même pour se rendre compte qu'on a une relation entre eux.

    - les signaux/slots sont très pratiques pour ajouter de la flexibilité à des parties de programmes plus enclines à être modifiées. Typiquement, les IHM: là où je mets un bouton aujourd'hui, je voudrai peut-être le remplacer demain par une entrée dans un menu. Donc quand les dépendances entre objets sont amenées à bouger, je privilégie les signaux/slots.

    - a chaque fois qu'on utilise un signal et un slot, on aura fait un 'connect' quelque part pour les relier. Et ce connect ne se fera souvent pas dans la partie du code où le traitement sera exécuté, mais souvent ailleurs (le constructeur d'une classe tierce, par exemple). L'abus de signaux slots, peu rapidement amener à faire des dizaines de connexions un peu dans tous les sens et des 'connects' ajoutés à l'arrache un peu n'importe où. Et on se retrouve vite avec un code difficile à relire, à déboguer. Bref, on risque rapidement la programmation 'spaghetti-like'.

    - surtout, les signaux/slots sont à l'origine pensés pour fournir une solution de réponse à des événements, donc des choses qui se passent à un moment plus ou moins indéterminé, dans la logique de la programmation événementielle (un signal est une action initiée par un acteur 'extérieur' à l'application (comme l'utilisateur (souris, clavier) ou le réseau). Si on utilise un signal/slot pour simplement faire une connexion entre deux bouts de code qui sont censées s'enchaîner dans le code, je trouve que c'est déjà un usage détourné.

    Bon voilà quelques grandes lignes que j'essaie de respecter. Après c'est un peu comme toujours en dév. : il n'y a rarement qu'une seule solution à une problématique donnée (ou une solution qui soit meilleure en tout points) ; à chacun de faire en fonction de ses habitudes, de sa 'logique propre', et du contexte.

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

Discussions similaires

  1. [Toutes versions] XLSX | XLSM | XLSB - Quand et pourquoi les utiliser ?
    Par TheChovix dans le forum Conception
    Réponses: 9
    Dernier message: 02/05/2020, 17h52
  2. Comprendre les optionnelles : quand et comment les utiliser ?
    Par Lana.Bauer dans le forum Développement iOS
    Réponses: 1
    Dernier message: 10/12/2015, 08h16
  3. [Débutant] SNMP & Proxy pas les utiliser mais leurs paramètres
    Par Speed41 dans le forum C#
    Réponses: 1
    Dernier message: 26/05/2014, 10h15
  4. Réponses: 6
    Dernier message: 04/03/2008, 12h19

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