2010-07-08 15 views
-1

J'ai tendance à avoir une classe pour décrire un concept général et des sous-classes pour décrire les variances dans ce concept. Par exemple, Polygon < | - {Rectangle, Triangle, etc.}.Détermination de la classe de représentation pour un objet de données en fonction de son type spécialisé?

Cependant, je trouve souvent que j'ai diverses représentations de ces hiérarchies. Par exemple, je veux garder la représentation graphique (par exemple, un QPolygon), ou la représentation physique (masse, centerOfMass), etc., séparée d'une autre représentation que j'ai.

Dans mon cas, j'ai une hiérarchie d'objets purement données (Command < | - {WaitCommand, UnknownCommand, etc.}) et j'ai une représentation graphique correspondant pour chacune des classes de données (WaitCommandPanel, UnknownCommandPanel) .

Mon problème est qu'une fois que je construis la représentation des données, j'ai besoin de faire le saut des données à l'interface graphique. Étant donné une liste d'objets de données, je veux être capable de construire les éléments GUI correspondants mais garder les deux représentations séparées.

Une solution [minable] serait pour chaque Command d'avoir la capacité (ie, Command::getPanel()) de retourner sa représentation GUI. Je n'aime pas ça parce que mes classes de données ont maintenant du code de représentation.

L'autre solution (que j'ai adoptée pour le moment) est de faire une recherche. C'est-à-dire, lors de l'initialisation de l'interface graphique, étant donné une liste de Command s (la généralisation), la fonction détermine quel objet créer en fonction de son type spécialisé. Je n'aime pas ça non plus.

Des suggestions?

Répondre

0

À mon humble avis, aucune classe de rendu de classe de données no a la responsabilité de prendre une décision sur le rendu à utiliser pour un objet de données donné. Je préfère votre deuxième option. J'utilise généralement une carte qui mappe le type de données dans une classe de rendu. Notez également qu'un tel mappage est spécifique au contexte (le rendu Web utilisera des rendus différents de l'application destop ou du contexte de remise en forme).

Une telle cartographie peut être construite automatiquement, par exemple en utilisant des attributs (dans .Net) ou peut-être une convention de dénomination (dans Lua). Ou en utilisant un fichier XML-config externe. Résumé: quelqu'un doit prendre cette décision, et selon SRP, ni le moteur de rendu ni l'objet de données ne doivent en être responsables. Une telle logique est spécifique au contexte de l'application et, en tant que telle, devrait être «au-dessus» de ces deux acteurs (c'est-à-dire le moteur de rendu et les données).

+0

Ma GUI a été matryoshka-dolled (la fenêtre principale a des panneaux de projet, des panneaux de projet ont des panneaux de commande, etc.) Chaque niveau ne sait pas où il est imbriqué/le niveau ci-dessus. Cependant, chaque niveau connaît les niveaux ci-dessous (c'est le contexte dans lequel les niveaux inférieurs existent). Je suppose que je vais le laisser au niveau dans lequel les panneaux sont utilisés pour décider. Je n'ai pas besoin de XML sophistiqué car l'appariement des classes ne change pas ('X' utilisera toujours' XPanel' comme représentation graphique).De plus, ceci est assez facile à associer en python en utilisant des dictionnaires: type (X) => constructeur pour XPanel. Merci. – jkiv

+0

en particulier avec Python, vous pouvez utiliser une convention de nommage pour faire l'association. Parcourez la portée et remplissez votre carte de recherche de rendu, de sorte que toute classe de formulaire (? . *) Renderer soit enregistrée en tant que: type (obj) => type (objRenderer). Donc, vous aurez juste besoin de définir des classes MyData et MyDataRenderer - et ils seront automatiquement associés. (IMHO cette approche est ** cool **, mais pas pratique - va causer plus de problèmes que cela résout) –

0

Vous pouvez vous intéresser à l'utilisation d'un conteneur d'inversion de contrôle (IoC) pour créer vos classes.

Chaque classe contiendrait une interface de sa classe associée. Le conteneur IoC injecterait alors l'implémentation de cette classe dans votre objet en fonction de la façon dont vous l'avez configuré.

+0

Je vais regarder dans, merci! – jkiv