🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: es.comp.lenguajes.java
2 messages
2 total messages Started by Kazud Mon, 13 Aug 2007 20:22
Arquitectura de aplicaciones Swing
#402
Author: Kazud
Date: Mon, 13 Aug 2007 20:22
41 lines
3144 bytes
Primero quería saludar al grupo, es mi primer mensaje :)

Y ahora al tema: repasando patrones de arquitectura, MVC y compañía,
empecé a hacer una aplicación de ejemplo en Swing para aplicar estos
patrones, pero me surgen una serie de dudas.

La aplicación es una tontería, pero quiero empezar por lo básico y
hacerla crecer un poco para contemplar los casos típicos de una
aplicación de gestión para el escritorio. Así que ahora mismo, lo
único que hace es listar libros (con un JFrame que tiene un área de
texto) y permitir añadir nuevos (un JDialog con los campos).

Con esto empecé separando la clases en dos capas: modelo (con la clase
"Libro") y vista-controlador (con las ventanas). Ahora bien, esto ya
me plantea una serie de dudas:

- En MVC, la vista guarda una referencia al modelo que va a mostrar.
Si la ventana lo que hace es mostrar todos los libros disponibles,
¿guarda un ArrayList de Libros? ¿Se debe crear una lista específica
para los libros? ¿Cómo encaja el patrón Observador/Observable con la
lista?

- La clase "Libro", en "principio", tiene toda la pinta de ser un
JavaBean. Sin embargo, los datos tienen que persistir, por lo que
¿dónde se meten los típicos métodos save/update/delete/find/etc.? ¿En
una clase separada como LibrosDAO? ¿Entonces la ventana, para recoger
los libros disponibles que tiene que mostrar, accede a LibrosDAO? ¿O
lo hace a través de Libros y éste es el único que usa LibrosDAO (lo
que implica volver a definir los métodos de persistencia para
encapsular a los métodos de la clase DAO)?

- Cuando se crea un nuevo libro, el usuario cubre los campos y le da a
un botón "Guardar": ¿Es la ventana la que crea el Libro, la rellena
con los datos de los JTextField y llama a su método "guardar"? ¿O es
el controlador el que recoge los datos introducidos por el usuario,
crea el Libro y llama a su guardar?

Por ahora esas son mis dudas.

Un saludo.
Re: Arquitectura de aplicaciones Swing
#407
Author: Ricardo Palomares Martinez
Date: Sun, 26 Aug 2007 18:09
178 lines
7955 bytes
Kazud escribió:
> Primero quería saludar al grupo, es mi primer mensaje :)
>


Saludos, desgraciadamente, este grupo no tiene toda la actividad que
sería deseable, así que cada mensaje es bienvenido (aunque,
precisamente por la falta de actividad, con frecuencia no habrá
respuestas, o no serán todo lo completas que sería deseable).


> Y ahora al tema: repasando patrones de arquitectura, MVC y compañía,
> empecé a hacer una aplicación de ejemplo en Swing para aplicar estos
> patrones, pero me surgen una serie de dudas.
> 
> La aplicación es una tontería, pero quiero empezar por lo básico y
> hacerla crecer un poco para contemplar los casos típicos de una
> aplicación de gestión para el escritorio. Así que ahora mismo, lo
> único que hace es listar libros (con un JFrame que tiene un área de
> texto) y permitir añadir nuevos (un JDialog con los campos).
> 
> Con esto empecé separando la clases en dos capas: modelo (con la clase
> "Libro") y vista-controlador (con las ventanas). Ahora bien, esto ya
> me plantea una serie de dudas:
> 
> - En MVC, la vista guarda una referencia al modelo que va a mostrar.
> Si la ventana lo que hace es mostrar todos los libros disponibles,
> ¿guarda un ArrayList de Libros?


Al estar usando un área de texto para mostrar lo que es, en realidad,
una lista, creo que te estás complicando ligeramente el diseño.
Sustituye el JTextArea por un JList y tendrás una propiedad en éste
llamada "model". A esa propiedad se le asigna una referencia al
modelo, que será una implementación del interface ListModel, y tú
puedes escribir esa implementación de manera que cada fila sea una
instancia de la clase Libro.


> ¿Se debe crear una lista específica para los libros?


Sí. Más exactamente, necesitas implementar ListModel (o TableModel, si
usas un JTable). Teóricamente, podrías hacerlo de manera que se
consultase la base de datos bajo demanda y no tuvieras la lista en
memoria, pero seguro que sería muy lento. Para listas cortas, lo que
yo he hecho es hacer un SELECT, cargarlo en la lista, y re-ejecutar el
SELECT cada vez que el usuario modifica la lista en su instancia. Así,
si hay varios accesos concurrentes, se ven las modificaciones sin
demasiada sobrecarga.

Todo lo anterior asume una base de datos por debajo y posibilidad de
accesos concurrentes. Si sólo te interesa una lista en memoria es más
fácil, claro.


> ¿Cómo encaja el patrón Observador/Observable con la lista?


ListModel y la mayoría de los interfaces *Model de Swing incluyen ese
patrón. ListModel, por ejemplo, define addListDataListener para
mantener una lista de observadores. Si en lugar de implementar
directamente ListModel extiendes AbstractListModel, tendrás además
otros métodos que te ayudan a la gestión del patrón Observador/Observable.



> 
> - La clase "Libro", en "principio", tiene toda la pinta de ser un
> JavaBean. Sin embargo, los datos tienen que persistir, por lo que
> ¿dónde se meten los típicos métodos save/update/delete/find/etc.?


En mi caso particular (pero yo soy relativamente nuevo en OOP, si
alguien me contradice hazle caso a él) :-) la clase Libro definiría un
libro aislado. La persistencia se implementaría en otra clase que
podría contener una instancia de Libro como propiedad. También podrías
definir un interface que proporcione la persistencia, e implementarlo
en varias clases, una que proporcione persistencia usando JDBC, otra
usando un fichero de texto y una lista en memoria, etc.


> ¿En una clase separada como LibrosDAO?


En mi opinión, tu clase que gestiona el modelo de la lista de libros
implementaría ListModel, crearía y eliminaría instancias de Libro, y
haría "permeable" a la capa de persistencia las modificaciones en la
lista. Para esto último tendrías LibrosDAO.


> ¿Entonces la ventana, para recoger
> los libros disponibles que tiene que mostrar, accede a LibrosDAO? ¿O
> lo hace a través de Libros y éste es el único que usa LibrosDAO (lo
> que implica volver a definir los métodos de persistencia para
> encapsular a los métodos de la clase DAO)?


Para mi gusto, las clases Swing acceden a los datos únicamente a
través de su modelo (ListModel, TableModel). Tu clase que gestiona la
lista implementa ese modelo y el patrón Observable/Observador (de
nuevo, AbstractListModel y AbstractTableModel son los puntos de
partida más prácticos para eso), maneja instancias de Libro y habla
con las clases de persistencia, que probablemente implementen patrones
DAO.

¿Qué pasa si quieres tener una vista de los libros en forma de tabla y
otra en forma de lista? Pues que tu clase que gestiona la lista debe
implementar a la vez ListModel y TableModel. Yo he hecho eso para
poder mostrar una tabla de códigos como lista (para su interfaz
gráfica de mantenimiento) y como lista desplegable (JComboBox) para
usarla como clave externa en otras tablas.


> 
> - Cuando se crea un nuevo libro, el usuario cubre los campos y le da a
> un botón "Guardar": ¿Es la ventana la que crea el Libro, la rellena
> con los datos de los JTextField y llama a su método "guardar"? ¿O es
> el controlador el que recoge los datos introducidos por el usuario,
> crea el Libro y llama a su guardar?


Buff, ahí me pillas. Las clases Swing no implementan realmente MVC,
sino M-VC. Es decir, la vista y el controlador están íntimamente
ligados, y el modelo es el que está realmente separado. En mi caso, el
"controlador" es el que define qué hay que hacer cuando se pulsa el
botón Guardar, y eso es un Listener de eventos del botón; normalmente
se implementa como clase anónima.

Al listener se le despierta cuando se pulsa el botón y hace lo siguiente:

- comprueba que los valores introducidos son válidos (sin campos en
blanco, códigos ISBN con el formato correcto, etc.)

- puede comprobar que el registro no existe ya consultando al modelo
por campo clave (aunque yo lo dejo completamente en manos del modelo)

- si todo está bien, pide al modelo la adición del registro (a su vez,
éste informará a la(s) vista(s) que los datos han cambiado, para que
éstas lo reflejen), y tras la adición actuarán en lo que sea necesario
de las vistas, como por ejemplo cerrar la ventana de diálogo o poner
en blanco los campos para la siguiente adición.


Yo dejo para el modelo la comprobación de la unicidad de registros
porque considero que no es un requisito de la arquitectura del
interfaz gráfico, sino un requisito del diseño del modelo de datos, y
así la comprobación está centralizada.

Espero haber sido de ayuda, aunque llegue tarde.

Saludos.

-- 
If it's true that we are here to help others,
then what exactly are the OTHERS here for?
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads