Mal problema de diseño de OO: necesito alguna funcionalidad general en Java pero no sé cómo implementarla

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

  •  02-07-2019
  •  | 
  •  

Pregunta

Estoy desarrollando un pequeño editor de clases UML en Java, principalmente un proyecto personal, podría terminar en SourceForge si encuentro tiempo para crear un proyecto en él.

El proyecto está bastante avanzado:Puedo crear clases, moverlas, crear interfaces, crear enlaces, etc.

En lo que estoy trabajando es en el cuadro de diálogo para configurar propiedades de clase/interfaz y crear nuevas clases/interfaces.

Por ejemplo, tengo una clase que extiende JDialog.Esta es la "ventana" principal para editar clases e interfaces (bueno, hay una clase para cada una).Contiene un JTabbedPane que a su vez contiene JPanels.

Estos JPanel son en realidad personalizados.Creé una clase abstracta que extiende JPanel.Esta clase utiliza componentes (definidos por sus subclases) y agrega sus valores a una JTable (también contenida en el JPanel).

Por ejemplo, si quiero editar los atributos de una clase, el JPanel contendrá un JTextField para ingresar el nombre del atributo y otro para ingresar su tipo.También hay un conjunto de botones para procesar los datos ingresados ​​en estos campos.Cuando hago clic en "Guardar", los datos que ingresé en JTextFields se agregan a JTable (al estilo Enterprise Architect).La clase concreta que extiende la abstracta es responsable de definir el control y decidir qué hacer con los datos cuando se agrega o elimina una línea del JTable.La gestión de JTable es, sin embargo, responsabilidad de la clase abstracta.

Aquí está mi problema:En OO, una clase tiene métodos y una interfaz también tiene métodos.Me dije a mí mismo:Podría usar el mismo JPanel personalizado concreto (AttributesPanel (que extiende la clase JPanel abstracta que creé)) para almacenar los métodos para una clase o una interfaz.

Sin embargo, la clase necesita conservar una copia (como atributo) de la clase o interfaz en la que estoy trabajando.De esa manera, cuando se le agrega un método, puedo llamar a editedClass.addMethod() (o editedInterface.addMethod()).El problema es que no tengo forma de saber si trabajo en una clase o en una interfaz.

La solución que encontré es fea:mantenga un atributo editedClass y un atributo editedInterface en la clase AttributesPanel.Según esté editando una clase o una interfaz, uno de estos atributos será nulo mientras que el otro no.

Es bastante feo si me preguntas.De hecho, puedo escuchar a mis profesores de ingeniería de software en mi cabeza gritando de agonía mientras arden (bueno, en realidad, se congelan) en el noveno círculo del infierno.

La forma rápida de solucionar este problema de diseño sería crear una interfaz llamada "ObjectWithMethods", que implementarán mis clases Clase e Interfaz.De esa manera, sólo tendré que poner un parámetro ObjectWithMethods en mi clase AttributesPanel.

¿Pero eso significa que debo crear una clase llamada "ObjectWithAttributes" u "ObjectWithBlahBlah"?Veo un buen potencial para "TheDailyWTF" aquí...Además, no creo que deba modificar los objetos de mi dominio (una clase, una interfaz, una nota, una relación (para mi editor UML)) o crear una nueva interfaz solo por considerar la interfaz de usuario...

¿Qué opinas?

Si necesitas más aclaraciones (porque estoy muy cansado en este momento y tiendo a corregir bastante mal (especialmente en inglés, mi lengua materna es el francés) mientras estoy en este estado de ánimo...), solo pregunta y editaré esto. pregunta.

Salud,

Guillaume.

¿Fue útil?

Solución

Cuando leo tu pregunta, realmente parece que estás describiendo un lugar para usar el patrón de visitante.

La razón por la que el patrón de visitantes debería funcionar aquí es una idea conocida como envío doble.Su código de interfaz de usuario realizará una llamada y se pasará una referencia a sí mismo, luego la clase o interfaz terminará llamando a la persona que llama original.Dado que la clase o interfaz es la que realiza la llamada al método, conoce su propio tipo y cómo realizar el trabajo específico de su tipo.

Por supuesto, mi descripción es insuficiente para implementar esta técnica, por lo que querrás leer más sobre ella.Creo que está bien documentado.Por ejemplo, encontré esto en aproximadamente 2 segundos en Java que debería ayudarte a comenzar: http://www.javaworld.com/javaworld/javatips/jw-javatip98.html

Otros consejos

Por lo general, hago lo más sencillo y empiezo a pensar en descartar interfaces cuando empiezo a ver demasiadas. if( .. instanceof ..)-como construcciones en mi código.No me cuesta mucho con las capacidades modernas de refactorización de código IDE.

En su caso específico, consideraría implementar los diagramas proporcionados en especificación UML, ¡porque fueron muy amables al especificar UML usando notación UML!

Tienes una aplicación.En esa aplicación.su representación y editar algunos datos.

Esos datos representan una clase de lenguaje de programación o una interfaz de lenguaje de programación.

Cuando haces un editor para algunos datos, a veces tienes que agregar información adicional/complementaria, por ejemplo, cada gráfico de clase puede tener un color de línea diferente, y no tiene que ver con los atributos o los métodos de tu clase.

Lo mismo ocurre con el campo o propiedad que indica si estás editando una clase o una interfaz.

Sugiero hacer algunas cosas.

Separa los datos representados del código o lógica de tu programa:

si tienes algo como:

// 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

Cambie a esto:

// 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

Salud.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top