2010-08-03 6 views
8

J'ai une classe de base (représentant un conteneur du monde réel rempli de petites sphères) et quelques classes dérivées. Cela fonctionne très bien.
Mon problème est comment faire leur visualisation. J'ai un UserControl visualisant la classe de base. La meilleure solution est-elle d'avoir un UserControl dérivé pour chacune des classes dérivées? Ou est-il préférable d'avoir un seul travail pour tous?
Editer:
Apparemment, je n'étais pas assez spécifique. Il y a toujours le même aspect de base: rectangle avec beaucoup de cercles à l'intérieur. La différence entre les classes est la façon dont le conteneur est rempli. Un type met une graine au milieu et crée d'autres sphères dans une structure arborescente - dans ce cas, les lignes de connexion entre les parents et leurs enfants doivent être dessinées.
En général, il devrait y avoir une apparence cohérente des visualisations des classes avec quelques spécialités pour chaque type dérivé.Visualisation des classes dérivées en C#

+5

Êtes-vous essayer de gagner un concours de comptage-fèves à la gelée? –

+1

Je pense que c'est une question très importante en génie logiciel; J'ai rencontré des situations similaires et je ne sais jamais vraiment comment le résoudre correctement. C'est une honte que toutes les réponses à ce jour aient manqué le point. – Timwi

+2

@ James Curran: En quelque sorte. Seulement il n'y a pas de concurrents et les jelly-beans sont remplacés par des microsphères de verre creuses – Lukas

Répondre

0

Je suppose que vous seul pouvez répondre à cette question définitivement. Une interface utilisateur pour une sous-classe donnée est probablement ce que vous voulez, mais si les sous-classes ne diffèrent que légèrement, vous pourriez trouver plus facile d'ajouter une logique conditionnelle dans moins de contrôles utilisateur. Je ne pense pas qu'il y ait une seule bonne réponse à celle-ci.

0

Il est difficile de dire à partir de la vague description. Nous aurions vraiment besoin de savoir, au moins, quelles sont les différences entre les classes dérivées.

En général, avec une connaissance limitée, je partirais avec un dérivé UserControl par classe dérivée

0

Si les classes dérivées de visualisation ne diffère pas de l'autre, puis, par tous les moyens, utilisez un UserControl. Le point principal ici est DRY.

1

Cela dépend beaucoup de la similitude des affichages. Si les affichages des classes dérivées sont très similaires à la classe de base, vous n'avez besoin que d'un UserControl pour effectuer la visualisation. OTOH, si chaque classe dérivée doit afficher des choses uniques, il vaudra mieux avoir un UserControl séparé pour visualiser chaque classe dérivée. Je ne peux vraiment pas être plus spécifique sans plus d'informations spécifiques sur vos cours. À partir de vos informations supplémentaires, je dirais que vous devriez avoir une classe d'affichage de base qui dessine le conteneur commom rectangulaire puis avoir des UserControls dérivés qui gèrent le dessin du contenu de chaque type spécifique.

+0

Je suis d'accord avec la réponse éditée. Demandez à votre classe de base de faire tout le dessin et de dériver une classe et de remplacer ceux qui changent entre les types. Vous pourriez avoir une boucle générique dans la classe de base qui appelle une méthode 'draw next' que vous substituez dans les sous-classes. –

0

Une approche du problème serait décomposer suivant la perspective MVVC:

Vous aurez besoin d'un UserControl comme une vue.

Un peintre base, qui gère la peinture de votre "boîte avec des cercles dedans" comme un ViewModel. Dérivés Les peintres implémentent différentes logiques de positionnement des objets et de leurs interconnexions. Si l'aspect de vos objets peut varier, ils doivent être donnés à l'artiste peintre sous la forme de ViewModel, éventuellement via le motif Adapter.

Enfin, vos cercles, rectangles et éléments associés à eux sont le modèle.

D'une manière générale:

Voir (UserControl) -> ViewModel (Peintre + Peintres dérivés + objet ViewModels) -> Modèle (cercle, rectangle, etc.)

0

Je ne comprends pas bien votre domaine de problème mais je pense que vous devez briser un peu plus. décomposer votre modèle en parties et écrire des vues pour chaque partie, vous pouvez simplement les relier. Je voudrais écrire une vue pour vos sphères, une vue pour les lignes entre vos sphères et une vue pour le rectangle tenant tout alors chacun de vos modèles sera responsable de les organiser et de créer les SphereModels et LineModels correspondants (et tout le reste vous avez besoin) alors votre point de vue principal doit juste être responsable de les mettre dans la boîte. Rappelez-vous toujours préférez la composition à l'héritage!

Concentrez-vous sur la division de votre problème en petits morceaux.

bonne chance

0

Je pense que j'irais avec une classe de Visualiseur de base qui avait des méthodes protégées pour dessiner les cercles et les lignes, et peut-être une propriété de la surface de dessin (toile?) De sorte que chaque mise en œuvre peut calculer la mesure positions basées sur la base, etc.

La classe de base implémente toutes les méthodes/tous les accessoires d'interface nécessaires pour en faire un visualiseur. Utilisez le modèle de stratégie dans la méthode appelée par IDE lorsque votre visualiseur est supposé se dessiner ... cette implémentation de méthode pourrait effacer le canevas, mettre en place des pinceaux et d'autres choses qui doivent être communes à chaque implémentation - alors appelle une méthode abstraite de la classe de base qui place réellement les cercles/boîtes/lignes/etc sur le canevas. De cette manière, chaque implémentation spécifique n'a plus qu'à se soucier de la logique pour positionner correctement les choses en fonction de son ensemble de règles - tous les «trucs de dessin sur le canevas» sont conservés dans la classe de base.

HTH

EDIT: Correction faute de frappe qui peut avoir causé une certaine confusion, où je le mot « contrôle » quand je voulais dire « Visualizer. »

0

Cela ressemble à une situation avec plusieurs solutions.

Une façon de procéder consiste à configurer UserControl pour appeler une méthode virtuelle dans la classe de base, puis à la remplacer dans les classes dérivées. Dans les classes dérivées, vous pouvez simplement appeler l'implémentation de base pour configurer la trame initialement.

Vous pouvez également configurer le rendu en couches (couche conteneur, couche de sphère, couche de ligne, etc.) et demander à la classe enfant de restituer des couches uniques et de déterminer l'ordre. Cela peut être coûteux, mais il pourrait lisser les visuels si la plupart de l'image reste la même.

Un autre est d'utiliser des délégués par opposition à l'héritage, mais cela a tendance à être salissant. Ce n'est généralement pas une bonne idée en raison des pénalités de performance. Cependant, il a l'avantage de la flexibilité d'exécution. Selon le reste de votre code, vous pourrez peut-être changer de style de croissance à mi-chemin avec ce modèle. Si vous ne vous voyez pas profiter de cette flexibilité, je vous recommande d'utiliser un modèle différent, cependant.

Peu importe la méthode que vous utilisez, je recommande que la classe de base fournisse les routines de dessin courantes pour assurer la cohérence.Les routines de la classe de base doivent être utilisées par la plupart des classes enfants, mais pas nécessairement toutes. Cela entraîne généralement un code plus maniable (à moins que vous ne vous retrouviez avec un fichier de 10000 lignes), moins de bugs et moins d'effort.

Questions connexes