Pobre tu que esta buscando en la página 10 de google tratando de buscar algún código ejemplo de como se usar el patrón mvp y solo encuentras las pagina de Martin Fowler que te parece demasiado complicada para que la entiendas (si la llegas a leer por que esta en ingles)
Te dedico estas palabras aburridas y académicas que por compromiso y por presunción innecesaria escribo para malograrte la vida y mostrar que se mucho mas que tu y que puede escribir mucho sin decir nada que valga la pena.
Si ya sé que solo quieres ver código que no te gusta leer así que te recomiendo que te saltes a la parte práctica donde se muestra el código y los diagramas de clases
Limitaciones del proyecto
Este proyecto no es por ningún motivo amplio ni toma en consideración todos los puntos que deben ser tomados en cuenta para desarrollar una aplicación digna de un profesional. Se pasaron por alto varios temas como el manejo de errores e hilos. Tampoco voy a decir que soy un experto en el patrón ni que lo he usado en varios proyectos así que no puedo dar consejos de como funciona el patrón en aplicaciones grandes ni los posibles errores que presente en ellos.
Que es el patrón mvp
El patrón de diseño mvp es un patrón para el desarrollo de interface de usuario que se caracteriza por trabajar con una clase y dos interfaces. La primera clase es llamada presentador que actúa como intermediario entre la vista (como interface) y el modelo (como interface).
Poniendo en palabras que cualquier programador entienda, El presentador es una clase concreta y por el constructor le pasamos la vista y el modelo en forma de interfaces.
La comunicación entre la vista y el presentador se desarrolla mediante el uso del patrón observador. La comunicación entre el modelo y el presentador es también por el patrón observador pero es poco usual. Tranquilo vamos ha desarrollar un ejemplo practico para que los conceptos queden claro XD somos programadores y nos gusta el código
Deja de trabajar sin pensar lo que haces y toma en cuenta que cualquier patrón que uses tiene sus desventajas y que debes escoger siempre el que mas se amolde a tus necesidades nada es perfecto “no existen las balas de plata”
Que desventajas y limitaciones tiene
• Requiere una gran cantidad de código que no vale la pena hacer en proyectos fáciles y simples
• Requiere una inmensa cantidad de código para conectar los presentadores con sus vistas y sus modelos Requiere que crees interfaces para que puedas usar el patrón observador por cada acción (como presionar un botón)
• Requiere que pienses en la vista en forma abstracta lo cual es difícil para los formularios muy grandes
Cuales son sus ventajas
• La vista puede ser fácilmente cambiada
• La vista puede ser trabajada incluso por una persona diferente
• La vista y el modelo pueden cambiar y ser muy diferentes sin que eso afecte demasiado el sistema.
La verdad es que todo cambio en el modelo siempre obliga cambios en la vista y lo único que se logra con estar menos “desacoplado” es que sea mas fácil hacer cambio pero siempre va haber cambios. La única forma de cambiar el modelo sin malograr la vista es mediante el uso de frameworks que autogeneren la vista mediante reflexión
Cuando usarlo
Recomiendo que uses el patrón para migrar un sistema de escritorio legacy (prácticamente todos están en estado legacy no se hagan los locos) en el cual la vista allá pasado de moda y los usuario quiera algo mas sexy, mas cool, mas “empresarial”. Me refiero a que se puede hacer poco a poco refactoring y cambiar a pedazos la vista
Recomiendo también usarlo cuando se quiera hacer aplicaciones de escritorio en las cuales se quiera mantener varias vistas en simultaneo (swing , javafx, awt)
Cuales son sus variantes
• No usar interface para el modelo
• Ni tampoco tener un modelo para formularios simples
• Considerar alas clases Servicio como modelo
Diagrama de clases del patrón
Aplicación practica
Vamos a mostrar un simple mantenimiento de personal usando swing y el patrón mvp
Diagrama de clases
En este caso decido no crear una interface para el modelo por que no le vi el sentido
Interface grafica
Fragmentos de código
Código
public class PresentadorMantenimientoPersonal { private final PanMantenimientoPersonal panMantenimientoPersonal; private final ServicioPersonal servicioPersonas; public PresentadorMantenimientoPersonal( PanMantenimientoPersonal panMantenimientoPersonalM, ServicioPersonal servicioPersonas) { this.panMantenimientoPersonal = panMantenimientoPersonalM; this.servicioPersonas = servicioPersonas; } public void run() { panMantenimientoPersonal.addAgregoListener(new AgregoListener() { @Override public void fueAgregado() { agrego(); } }); panMantenimientoPersonal.addModificoListener(new ModificoListener() { @Override public void fueModificado() { modificado(); } }); panMantenimientoPersonal.addEliminadoListener(new EliminadoListener() { @Override public void fueEliminado() { eliminado(); } }); } private void eliminado() { Personal leeido = panMantenimientoPersonal.leerPersonal(); servicioPersonas.eliminar(leeido.getCodigo()); panMantenimientoPersonal.mostrar(servicioPersonas.lista()); } private void modificado() { Personal leeido = panMantenimientoPersonal.leerPersonal(); servicioPersonas.modifica(leeido); panMantenimientoPersonal.mostrar(servicioPersonas.lista()); } private void agrego() { Personal leeido = panMantenimientoPersonal.leerPersonal(); servicioPersonas.agregar(leeido); panMantenimientoPersonal.mostrar(servicioPersonas.lista()); } }
Código
import java.util.List; public interface PanMantenimientoPersonal { void addAgregoListener(AgregoListener agregoListener); void addModificoListener(ModificoListener modificoListener); void addEliminadoListener(EliminadoListener eliminadoListener); Personal leerPersonal(); void mostrar(List<Personal> lista); }
Código
import java.awt.Container; PanMantenimientoPersonal { public PanMantenimientoPersonalSwing() { setLayout(null); lblNombre.setBounds(10, 11, 56, 14); add(lblNombre); txtCodigo.setBounds(73, 8, 86, 20); add(txtCodigo); txtCodigo.setColumns(10); label.setBounds(10, 39, 56, 14); add(label); txtNombre.setColumns(10); txtNombre.setBounds(73, 36, 86, 20); add(txtNombre); lblApellido.setBounds(10, 67, 56, 14); add(lblApellido); txtApellido.setColumns(10); txtApellido.setBounds(73, 64, 86, 20); add(txtApellido); lblEdad.setBounds(10, 95, 56, 14); add(lblEdad); txtEdad.setColumns(10); txtEdad.setBounds(73, 92, 86, 20); add(txtEdad); scrollPane.setBounds(10, 148, 419, 142); add(scrollPane); "codigo", "nombre", "apellido", "edad", "sueldo" })); scrollPane.setViewportView(table); lblSueldo.setBounds(10, 123, 56, 14); add(lblSueldo); txtSueldo.setColumns(10); txtSueldo.setBounds(73, 120, 86, 20); add(txtSueldo); for (AgregoListener agregoListener : listaAgregoListener) { agregoListener.fueAgregado(); } } }); btnAgrega.setBounds(175, 7, 89, 23); add(btnAgrega); for (ModificoListener modificoListener : listaModificoListener) { modificoListener.fueModificado(); } } }); btnModifica.setBounds(175, 35, 89, 23); add(btnModifica); for (EliminadoListener eliminadoListener : listaEliminadoListener) { eliminadoListener.fueEliminado(); } } }); btnElimina.setBounds(175, 63, 89, 23); add(btnElimina); } private List<AgregoListener> listaAgregoListener = new ArrayList<>(); private List<ModificoListener> listaModificoListener = new ArrayList<>(); private List<EliminadoListener> listaEliminadoListener = new ArrayList<>(); @Override public void addAgregoListener(AgregoListener agregoListener) { listaAgregoListener.add(agregoListener); } @Override public void addModificoListener(ModificoListener modificoListener) { listaModificoListener.add(modificoListener); } @Override public void addEliminadoListener(EliminadoListener eliminadoListener) { listaEliminadoListener.add(eliminadoListener); } @Override public Personal leerPersonal() { return new Personal(codigo, nombre, apellido, sueldo, edad); } @Override public void mostrar(List<Personal> lista) { model.setRowCount(0); for (Personal personal : lista) model.addRow(aFila(personal)); } private Vector<Object> aFila(Personal personal) { Vector<Object> result = new Vector<>(); result.add(personal.getCodigo()); result.add(personal.getNombre()); result.add(personal.getApellido()); result.add(personal.getSueldo()); result.add(personal.getEdad()); return result; } }
Código
import java.awt.BorderLayout; import javax.swing.JFrame; public class Main { PanMantenimientoPersonalSwing panMantenimientoPersonal = new PanMantenimientoPersonalSwing(); new PresentadorMantenimientoPersonal(panMantenimientoPersonal// , new ServicioPersonal())// .run(); jFrame.setSize(500, 400); jFrame.setLocationRelativeTo(null); jFrame.getContentPane().add(panMantenimientoPersonal, jFrame.setVisible(true); } }
Aprendizaje y evolución
En el desarrollo se puede apreciar que el manejo de eventos no puede ser mas simple son solamente varios ArrayList que guardan varios eventos
Supongamos por ejemplo que un día el jefecito se le ocurrió que la vista esta fea y que le gustaría cambiar a javafx bueno pues simplemente cambiaríamos el main de esta manera
Código
PanMantenimientoPersonalJfx panMantenimientoPersonal = new PanMantenimientoPersonalJfx (); new PresentadorMantenimientoPersonal(panMantenimientoPersonal// , new ServicioPersonal())// .run(); mostrarEnVentana(panMantenimientoPersonal) ;
Solo crearíamos la vista imprentaríamos los métodos de la interface PanMantenimientoPersonal pero todo el resto de la aplicación no tendría que cambiar
Para los haraganes como descargar y usar el código
Por favor necesito que me ataquen
Traumas, críticas (destructivas), trolleos, venganzas, asuntos personales, propuestas indecentes, amenazas y tal vez preguntas son bienvenidas