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 :

Agrégation et interface exposée


Sujet :

C++

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    30
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 30
    Points : 31
    Points
    31
    Par défaut Agrégation et interface exposée
    Bonjour,

    Je suis aujourd'hui face à un problème qui me semble pourtant basique au niveau conception, mais aucune solution me satisfait pleinement.

    Il s'agit d'une architecture de jeu vidéo qui se compose (entre autres) des classes suivante: Application, Display, InputManager, UpdateDispatcher et Scene.
    L'Application est une classe qui, je pense, aggrége les classes InputManager, UpdateDispatcher et Display, pour en exposer les services à la Scene, qui utilisera chacuns de ces modules.

    Je suis indécis sur la façon d'implémenter cette aggrégation. Plusieurs solutions s'offrent à moi. Je les liste ici en donnant ce qui me semblent être les points importants qui y sont associés.

    L'agrégation en tant que membres avec accès direct:
    Dans cette implémentation, on aurait (en gros):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    class Application {
    private:
      Display mDisplay;
      InputManager mInputs;
      UpdateDispatcher mUpdater;
     
    public:
      Display& getDisplay();
      InputManager& getInputManager();
      UpdateDispatcher& getUpdater();
    };
    Ainsi, un objet Scene ayant une référence sur Application pourra accéder à l'affichage, enregistrer des InputListener ou des UpdateListener directement après des classes dédiées.

    Ce que je n'aime pas dans cette approche est en quelque sorte l'exposition de la structure interne d'Application vis-à-vis des services qu'elle rend. Scene n'a pas besoin de savoir que l'appel de sa fonction d'update se fait par une classe UpdateDispatcher. De plus, je serai obligé d'inclure le header d'UpdateDispatcher pour enregistrer une callable quelconque...

    L'agrégation avec forwarding des interfaces:
    Dans cette implémentation, la class Application possède les mêmes membres que précédemment mais ne les expose pas directement. A l'inverse, elle expose plutot les services rendus par l'intermédiaire de ces modules directement dans son interface.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    class Application {
    private:
      Display mDisplay;
      InputManager mInputs;
      UpdateDispatcher mUpdater;
     
    public:
      void addModel(Model);
      void addInputListener(Callable pCallable);
      void addUpdateListener(Callable pCallable);
    };
    Ainsi, j'ai plus l'impression qu'Application encapsule convenablement son implémentation et sa structure interne. En revanche, on risque d'assister à l'explosion de son interface ainsi que quelques autres détails d'implémentation que j'exposerai si on me le demande. Et peut-être qu'ici, Application rend plus de service qu'elle ne devrait... Mais il faut bien un noeud par où accéder aux autres services nécessaires quelque part!

    L’agrégation par héritage: (*esquive les projectiles*)
    Après la méthode précédente, le fait de devoir réexposer l'interface de chaque module m'a donné l'impression que l'héritage me priverai de ce fardeau. Peut-être est-ce un cas où l’agrégation par héritage serait pratique. Je ne suis par contre pas certain de pouvoir vraiment affirmer que l'Application est un UpdateDispatcher, même si elle est supposée rendre ce service.

    Donc voilà, si vous avez d'autres proposition d'implémentation n'hésitez pas. Je ne suis pas vraiment décidé sur la méthode à implémenter, peut-être juste un penchant pour la seconde.
    Est-ce qu'il me manque l'application d'une règle fondamentale de conception pour passer à travers ce dilemme?

  2. #2
    Invité
    Invité(e)
    Par défaut
    plop,

    L'Application est une classe qui, je pense, aggrége les classes InputManager, UpdateDispatcher et Display, pour en exposer les services à la Scene, qui utilisera chacuns de ces modules
    si ton application fait rien de plus que dispatcher les services et n'apporte aucune valeur ajoutée, si ce n'est d'assurer la même durée de vie pour chacun de tes modules, une vulgaire structure fait l'affaire.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    struct Application{
      Display mDisplay;
      InputManager mInputs;
      UpdateDispatcher mUpdater;
    }
    Cela dit, si ya que scene qui se sert de Application, autant stocker directement les modules dans scene.

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    30
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 30
    Points : 31
    Points
    31
    Par défaut
    Je ne pense pas, car je souhaite potentiellement avoir plusieurs Scene par Application. Pour le moment, Application ne gère que la boucle principale, mais avec l'étoffage des fonctionnalités, elle aura d'autres responsabilités : initialisation de structures particulières, ...

  4. #4
    screetch
    Invité(e)
    Par défaut
    pourquoi est-ce que un objet Scene a besoin d'une application?
    Si une scene a besoin de faire du rendu (ce dnt je ne suis pas convaincu) alors il faut lui donner un Renderer, pas une appication. Si elle a besoin de faire des updates (ce dont je suis encore moins convaincu) alors il lui faut un UpdateManager, pas une application.

    Le role de l'application serait alors de coordonner qui donne quoi a quoi en parametre; l'application peut creer une nouvelle scene avec un Renderer.

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    30
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 30
    Points : 31
    Points
    31
    Par défaut
    Disons que la Scene sera la partie "cliente" des modules, qui met en place les structures et le contenu spécifique à l'application. Donc elle devra instancier et placer potentiellement des récepteurs pour les inputs, pour les updates (un controler de caméra aura besoin des deux par exemple). De même, pour instancier un élément graphique particulier et son alter ego physique, il aura besoin d'accéder au module graphique (Display), ainsi qu'à la physique.

  6. #6
    screetch
    Invité(e)
    Par défaut
    Une scene a trop de choses a faire, c'est pour ca que tu te retrouves avec un probleme de conception. Une classe devrait avoir une seule chose a faire, et le faire bien. Ta classe Scene regroupe trop de choses et doit connaitre tout et tout le monde, et du coup tu ne sais plus comment faire.

    sinon je pense quand meme que ta scene devrait explicitement contenir des pointeurs sur tout ce dont elle a besoin au lieu de demander a l'application.

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    30
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 30
    Points : 31
    Points
    31
    Par défaut
    Je n'ai pas l'impression que ce soit un problème d'échelle ou de quantité de chose à faire. Pour moi, le problème se situe vraiment autour de la classe Application et des modules qu'elle gère. Même si la Scene était découpé en plusieurs classes à responsabilité limitée, ces classes auraient toujours besoin individuellement d'accéder aux fonctionnalités d'un module ou d'un autre. C'est cette mise à disposition des fonctionnalités qui me pose problème.

    Grosso modo, pour l'UML suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    Module1           Module2
        \                  /
     agrège          agrège
          \            /
           \          /
            Application
                  |
                  |
               Scene
    Comment l'Application met-elle à dispo les fonctionnalités de Module1 et Module2?
    Soit, comme tu l'as dis, Scene prend un pointeur sur les modules dont il a besoin (dans ce cas, on dessine une relation simple entre Scene et Module1,Module2). Soit Application met à dispo l'interface utile des modules dans sa propre interface (dans ce cas, Application devient trop lourde au niveau des fonctionnalités).

    J'ai déjà eu ce problème à plus grande échelle dans une autre application, avec un schéma plus complexe. Application composée de Display et InputManager, Display contient une Scene, qui contient un InstrumentManager, qui contient des Instruments : comment faire en sorte qu'un Intrument puisse écouter les Inputs...

  8. #8
    screetch
    Invité(e)
    Par défaut
    comme j'ai dit plus haut, la meme chose, au mot pres, s'applique sur ce second post: ta classe Scene fait trop de chose et donc doit connaitre trop de choses.

Discussions similaires

  1. Exposer une interface de service "normal" en webservice
    Par onlytoine dans le forum Services Web
    Réponses: 6
    Dernier message: 30/05/2008, 14h51
  2. Réponses: 2
    Dernier message: 30/07/2006, 20h12
  3. [VB6] [Interface] ComboBox à plusieurs colonnes
    Par mtl dans le forum VB 6 et antérieur
    Réponses: 7
    Dernier message: 30/03/2004, 18h35
  4. [VB6] [Interface] Horloge 7 segments
    Par selenay dans le forum VB 6 et antérieur
    Réponses: 11
    Dernier message: 07/10/2002, 17h15
  5. interface utilisateur avec OpenGL
    Par demis20 dans le forum OpenGL
    Réponses: 6
    Dernier message: 03/10/2002, 13h27

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