Patrom mvp

Iniciado por sapito169, 7 Noviembre 2013, 02:25 AM

0 Miembros y 1 Visitante están viendo este tema.

sapito169

Patron mvp

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 (java) [Seleccionar]
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 (java) [Seleccionar]

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 (java) [Seleccionar]

import java.awt.Container;

public class PanMantenimientoPersonalSwing extends JPanel implements
PanMantenimientoPersonal {
public PanMantenimientoPersonalSwing() {
setLayout(null);

JLabel lblNombre = new JLabel("codigo");
lblNombre.setBounds(10, 11, 56, 14);
add(lblNombre);

txtCodigo = new JTextField();
txtCodigo.setBounds(73, 8, 86, 20);
add(txtCodigo);
txtCodigo.setColumns(10);

JLabel label = new JLabel("Nombre");
label.setBounds(10, 39, 56, 14);
add(label);

txtNombre = new JTextField();
txtNombre.setColumns(10);
txtNombre.setBounds(73, 36, 86, 20);
add(txtNombre);

JLabel lblApellido = new JLabel("Apellido");
lblApellido.setBounds(10, 67, 56, 14);
add(lblApellido);

txtApellido = new JTextField();
txtApellido.setColumns(10);
txtApellido.setBounds(73, 64, 86, 20);
add(txtApellido);

JLabel lblEdad = new JLabel("Edad");
lblEdad.setBounds(10, 95, 56, 14);
add(lblEdad);

txtEdad = new JTextField();
txtEdad.setColumns(10);
txtEdad.setBounds(73, 92, 86, 20);
add(txtEdad);

JScrollPane scrollPane = new JScrollPane();
scrollPane.setBounds(10, 148, 419, 142);
add(scrollPane);

table = new JTable();
table.setModel(new DefaultTableModel(new Object[][] {}, new String[] {
"codigo", "nombre", "apellido", "edad", "sueldo" }));
scrollPane.setViewportView(table);

JLabel lblSueldo = new JLabel("sueldo");
lblSueldo.setBounds(10, 123, 56, 14);
add(lblSueldo);

txtSueldo = new JTextField();
txtSueldo.setColumns(10);
txtSueldo.setBounds(73, 120, 86, 20);
add(txtSueldo);

JButton btnAgrega = new JButton("agrega");
btnAgrega.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
for (AgregoListener agregoListener : listaAgregoListener) {
agregoListener.fueAgregado();
}
}
});
btnAgrega.setBounds(175, 7, 89, 23);
add(btnAgrega);

JButton btnModifica = new JButton("modifica");
btnModifica.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
for (ModificoListener modificoListener : listaModificoListener) {
modificoListener.fueModificado();
}
}
});
btnModifica.setBounds(175, 35, 89, 23);
add(btnModifica);

JButton btnElimina = new JButton("elimina");
btnElimina.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
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<>();
private JTextField txtCodigo;
private JTextField txtNombre;
private JTextField txtApellido;
private JTextField txtEdad;
private JTable table;
private JTextField txtSueldo;

@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() {
int codigo = Integer.parseInt(txtCodigo.getText());
String nombre = txtNombre.getText();
String apellido = txtApellido.getText();
double sueldo = Double.parseDouble(txtSueldo.getText());
int edad = Integer.parseInt(txtEdad.getText());
return new Personal(codigo, nombre, apellido, sueldo, edad);
}

@Override
public void mostrar(List<Personal> lista) {
DefaultTableModel model = (DefaultTableModel) table.getModel();
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 (java) [Seleccionar]


import java.awt.BorderLayout;

import javax.swing.JFrame;

public class Main {
public static void main(String[] args) {
PanMantenimientoPersonalSwing panMantenimientoPersonal = new PanMantenimientoPersonalSwing();
new PresentadorMantenimientoPersonal(panMantenimientoPersonal//
, new ServicioPersonal())//
.run();

JFrame jFrame = new JFrame();
jFrame.setSize(500, 400);
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jFrame.setLocationRelativeTo(null);
jFrame.setLayout(new BorderLayout());
jFrame.getContentPane().add(panMantenimientoPersonal,
BorderLayout.CENTER);
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 (java) [Seleccionar]
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

egyware

Es mi idea, o es  MVC (Modelo Vista Controlador) porque en ciertos aspectos se parece mucho, pero solo cambia una letra.


PS: Debo felicitarte, porque quedo todo muy bien explicado.

sapito169

 ;D

jajajaja

no es tu idea es la idea de todos los que han intentado averiguar de estos temas llegan a la misma conclusión.

Todos los autores escriben ha cerca de lo que es mvp mvc todos lo definen de manera distinta xd todo lo programan de manera distinta y al final nadie sabe cual es la verdadera respuesta

Yo pienso que no hay respuesta correcta que ya se fregó y todos lo definirán de manera diferente xd . Mira yo defino el patrón mvp de esa manera por que es asi como nos ilustra martin fowler en sus papers.

Mitsu

Muy interesante, de lo poco que he leído hoy de esto, sé que deriva del clásico MVC. Ahora, si lo comenta/aconseja Martin Fowler, pues a estudiarlo xD

Gracias por compartir.

ThinkByYourself

Buen aporte! Se agradece un poco de luz académica y la concentración de la información siempre es útil!
Gracias!
No te voy a engañar.
Todos hemos sido programados para normalizar la psicopatía de las élites económicas y políticas, y para realimentar su patrón de ciega codicia.