Problème de conception OO incorrect - J'ai besoin de quelques fonctionnalités générales en Java mais je ne sais pas comment les implémenter.

StackOverflow https://stackoverflow.com/questions/125463

  •  02-07-2019
  •  | 
  •  

Question

Je développe un petit éditeur de classe UML en Java, principalement un projet personnel. Il pourrait arriver à SourceForge si je trouve le temps de créer un projet dessus.

Le projet est assez avancé: je peux créer des classes, les déplacer, créer des interfaces, créer des liens, etc.

Je travaille sur la boîte de dialogue permettant de définir les propriétés de classe / interface et de créer de nouvelles classes / interfaces.

Par exemple, j'ai une classe qui étend JDialog. C’est la fenêtre principale " fenêtre " pour éditer des classes et des interfaces (enfin, il y a une classe pour chacune). Il contient un JTabbedPane qui contient à son tour JPanels.

Ce JPanel sont en réalité ceux personnalisés. J'ai créé une classe abstraite qui étend JPanel. Cette classe utilise des composants (définis par ses sous-classes) et ajoute leurs valeurs à un JTable (également contenu dans JPanel).

Par exemple, si je veux éditer les attributs d'une classe, JPanel contiendra un JTextField pour entrer le nom de l'attribut ainsi qu'un autre pour entrer son type. Il existe également un ensemble de boutons permettant de traiter les données saisies dans ces champs. Lorsque je clique sur "Enregistrer", les données que j'ai entrées dans les JTextField sont ajoutées à la JTable (à la manière de Enterprise Architect). La classe concrète qui étend la classe abstraite est responsable de la définition du contrôle et du choix de l'utilisation des données lorsqu'une ligne est ajoutée ou supprimée de la table JTable. La gestion de JTable relève toutefois de la responsabilité de la classe abstraite.

Voici mon problème: dans OO, une classe a des méthodes et une interface a aussi des méthodes. Je me suis dit: je pourrais utiliser le même fichier JPanel personnalisé (AttributesPanel (qui étend la classe abstraite JPanel que j'ai créée)) pour stocker les méthodes d'une classe ou d'une interface.

Cependant, la classe doit conserver une copie (en tant qu'attribut) de la classe ou de l'interface sur laquelle je travaille. Ainsi, lorsqu'une méthode est ajoutée, je peux appeler ededClass.addMethod () (ou ededInterface.addMethod ()). Le problème est que je n'ai aucun moyen de dire si je travaille sur une classe ou une interface.

La solution que j'ai trouvée est moche: conservez un attribut EdedClass et un attribut ededInterface dans la classe AttributesPanel. Selon que j'édite une classe ou une interface, l'un de ces attributs sera nul, alors que l'autre ne le sera pas.

C'est assez moche si vous me demandez. En fait, je peux entendre mes professeurs de génie logiciel dans ma tête crier de douleur en brûlant (enfin, en train de geler) dans le neuvième cercle de l’Enfer.

La solution rapide à ce problème de conception serait de créer une interface appelée "ObjectWithMethods", que mes classes de classe et d'interface implémenteront. De cette façon, il me suffira de mettre un paramètre ObjectWithMethods dans ma classe AttributesPanel.

Mais cela signifie-t-il que je devrais créer une classe nommée "ObjectWithAttributes", ou "ObjectWithBlahBlah"? ? Je vois de bons "TheDailyWTF". potentiel ici ... En outre, je ne pense pas que je devrais modifier mes objets de domaine (une classe, une interface, une note, une relation (pour mon éditeur UML)) ou créer une nouvelle interface uniquement pour des raisons d'interface utilisateur ... .

Qu'en pensez-vous?

J'ai besoin de plus de précisions (parce que je suis très fatigué et que j'ai tendance à avoir des problèmes de frappe (surtout en anglais - ma langue maternelle est le français) alors que dans cet état d'esprit ...), demandez simplement et je ' ll éditer cette question.

A bientôt,

Guillaume.

Était-ce utile?

La solution

Quand je lis votre question, il semble vraiment que vous décriviez un endroit où utiliser le modèle de visiteur .

La raison pour laquelle le modèle de visiteur devrait fonctionner ici est une idée appelée double dépêche. Votre code d'interface utilisateur passe un appel et passe une référence à lui-même, puis la classe ou l'interface finit par appeler l'appelant initial. Puisque la classe ou l’interface est celle qui appelle la méthode, elle connaît son propre type et sait comment effectuer le travail propre à son type.

Bien sûr, ma description est insuffisante pour implémenter cette technique, vous aurez donc envie de la lire. Je pense que c'est bien documenté. Par exemple, j’ai trouvé cela en environ 2 secondes en Java, ce qui devrait vous aider à démarrer: http://www.javaworld.com/javaworld/javatips/jw-javatip98.html

Autres conseils

Habituellement, je fais juste la chose la plus simple, et commence à penser à factoriser les interfaces, quand je commence à voir trop de constructions if (.. instanceof ..) -like dans mon code. Cela ne me coûte pas beaucoup avec les capacités modernes de refactoring de code IDE.

Dans votre cas particulier, j’envisagerais d’implémenter les diagrammes fournis dans la spécification UML , car ils étaient si aimables de spécifier UML en utilisant la notation UML!

Vous avez une application. Dans cette application. votre représentant et modifier des données.

Ces données représentent une classe de langage de programmation ou une interface de langage de programmation.

Lorsque vous créez un éditeur pour certaines données, vous devez parfois ajouter des informations supplémentaires / complémentaires, par exemple, chaque diagramme de classes peut avoir une couleur de trait différente et n'a pas à voir avec les attributs ou les méthodes de votre classe.

Il en va de même pour le champ ou la propriété qui indique que vous modifiez une classe ou une interface.

Je suggère de faire certaines choses.

Séparez les données représentées du code ou de la logique de votre programme:

si vous avez quelque chose comme:

// all code, classes, mixed up
public class JCustomPanel:  {

    protected ChartClass Charts;
    protected ArrayList<String> MyClassAttributes;
    protected ArrayList<String> MyClassMethods;

    void PanelDoSomeThing();
    void ClassDoSomeThing();
    void InterfaceDoSomeThing();

    // ...
} // class JCustomPanel

Changez en ceci:

// things related to a single class or interface,
// nothing to do with the chart

public class JClassRepresentation:  {

    ArrayList<String> Attributes;
    ArrayList<String> Methods;

    bool IsInterface;

    void ClassDoSomeThing();
    void InterfaceDoSomeThing();

    // ...
} // class JCustomPanel

// things related to the editor,
// contains the classes and interfaces,
// but, as separate stuff
public class JCustomPanel:  {

    ArrayList<JClassRepresentation> Classes;

    int PagesCount;

    void InterfaceDoSomeThing();

    // ...
} // class JCustomPanel

A bientôt.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top