Vous êtes sur la page 1sur 13

Como implementar MVP en nuestras aplicaciones Android.

El patron de diseno MVP permite a un desarrollador de aplicaciones moviles en crear una


arquitectura solida, escalable, desacoplar componentes, etc. Este patron de diseno ya
exisitia desde hace mucho pero apenas empezo a implementarse dentro de nuestras
aplicaciones.

El MVP se comporta por 3 capas las cuales se describiran a continuacion.


VIEW
Una View dentro de MVP no representa una vista del SDK de android (Android class
View), es decir no es un TextView, ni un Button, ni un Layout, ni una Custom View, ni
mucho menos una Activity o un Fragment.
Una View representa una abstraccin de que puedo hacer con la vista, normalmente se
asocia a una interface para representar la funcionalidad de una vista. La parte
importante est en que una Activity o un Fragmento tienen la responsabilidad nicamente
de implementar la interface View y conectar las acciones del usuario con el presenter.

PRESENTER

En este patrn es el encargado de coordinar la implementacin de la vista y el modelo,


actualiza la vista y acta sobre los eventos de usuario que se envan por la vista. El
presenter tambin recupera los datos del modelo y los prepara para su visualizacin.

INTERACTOR (MODEL)
Es el proveedor de los datos que queremos mostrar en la vista, si estuviramos usando
Clean Architecture el modelo sera un interactor que implemente algn caso de uso.

Se muestra un diagrama del funcionamieto de este patron de diseno, en donde se logra


percatar como es la comunicacin entre diferentes capas, viendo que la mas oculta es la
capa del modelo.

Algo importante a la hora de desarrollar bajo este patron de diseno es que, debemos de
saber con claridad cual sera el flujo de nuestra aplicacin, sabiendo que primero se
iniciara con la capa View la cual no se encargara de ralizar nada de la logica de negocio si
no sera la unica que notifique al Presenter que sucedi dentro de la UI para que el
Presenter reaccione y le comunique al Modelo o Interactor que hay algo nuevo por
realizar.
Aqui se ve el funcionamiento en forma de clases e interfaces de como interacuta este
patron de diseno.

Veamos un ejemplo super sencillo el cual nos deje mas claro como funciona el MVP.

La aplicacin consta de enlistar una serie de articulos,


pero estos seran almacenados en un BD y a la vez mostrados.
Ahora bien, intentare mostrar un diagrama para identificar
el flujo de la app utilizando el MVP.

Diagrama del funcionamiento de la app, mediante el MVP.

Capa View
Primero que nada tendriamos que definir nuestras interfaces las cuales nos van a
permitir comunicar entre diferentes capas, asi es que, aqu enlisto las 4 interfaces que
implemente para la aplicacin.
Interfaz ListaArticulosView.
public interface ListaArticulosView {
void mostrarListaArticulos(ArrayList<String> articulo);
void errorInputArticulo();
void limpiarInputArticulo();
}
Interfaz ListaArticulosPresenter.
public interface ListaArticulosPresenter {
void recibirArticulo(String articulo);
void obtenerListadoArticulos();
}
Interfaz ListaArticuloInteractor.
public interface ListaArticuloInteractor {
void agregarArticulo(String articulo, ListaArticulosCallback callback);
void obtenerAllArticulos(ListaArticulosCallback callback);
}
Estas son las interfaces de como es que interactua la aplicacin, donde puedes
abstraerlas desde antes y agregar mas conforme el flujo de la aplicacin vaya creciendo,
para esto no hay ninguna restriccion, solo tener cuidado de donde se esta agregando el
codigo si es en una capa correspondiente o no.

Aqui vemos que hay otra interfaz, pero esta no la mezclo con las demas porque solo va a
ser la encargada de devolver una notificacion cuando alla llegado al Interactor, y esta
interfaz comunicara al Presenter de lo que sucedi en el Interactor.
Interfaz ListaArticulosCallback
public interface ListaArticulosCallback {
void notificarArticuloAgregado(ArrayList<String> articulo);
void notificarArticuloEliminado();
}
Hasta aqu todo bien ahora biene la parte de como se comunican entre si las diferentes
capas. Podemos empezar con la activityMain o como se llama su actividad principal a la
cual estan aplicando este MVP.
En mi caso la clase principal es ListaArticulosActivity de aqu es donde empiza a surgir
la comunicacin. Se puede observar que la clase implementa una interfaz la cual es
ListaArticulosView que como ya viamos visto con anterioridad tenian ya metodos listos
para ser encapsulados.
public class ListaArticulosActivity extends AppCompatActivity implements
ListaArticulosView {
Uso de ButterKnife en esta parte, para reducir el findById().
@Bind(R.id.inputArticulo)
EditText inputArticulo;
@Bind(R.id.listView)
ListView listaArticulos;
@Bind(R.id.contenedor)
RelativeLayout contenedor;
ListaArticulosPresenter presenter;
ArrayAdapter adapter;

Si vemos nuestra logica de esta app, vemos que en el metod onCreate es donde se
inicializa el Presenter para poder hacer uso de sus implementaciones.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_lista_articulos);
ButterKnife.bind(this);
Aqui es donde se instacia el Presenter para poderlo usar correctamente.
presenter = new ListaArticulosPresenterImplement(this,getBaseContext());
}
Estos tres metodos que vemos aqu mostrarListaArticulos, limpiarInputArticulo,
errorInputArticulo, son los que implementamos por la interfaz y estos seran notificados
cuando suceda algo desde el Interactor. Me refiero a que cuando el flujo de la app llege
al Interactor y este devuelva una llamada (Notificacion) a la capa Presenter el cual
actuara como puente comunicara a la capa View para poder usar uno de estos 3 metodos.
@Override
public void mostrarListaArticulos(ArrayList<String> articulo) {
adapter = new ArrayAdapter<>(this,android.R.layout.simple_list_item_1,
articulo);
listaArticulos.setAdapter(adapter);
}
@Override
public void limpiarInputArticulo() {
inputArticulo.setText("");
}
@Override
public void errorInputArticulo() {
Snackbar.make(contenedor, R.string.listaArticulos_snackbar_mesaje_aviso,
Snackbar.LENGTH_SHORT).show();
}

Ahora bien estos OnClick son los encargados de desencadenar el flujo que llevara nuestra
apliacion, no necesariamente sera un Button, si no que los que realmente desencadenaran
el flujo seran los Eventos, entre otros. Sabemos que un evento es una accion que se
raliza cuando es notificada por el usuario.
@OnClick(R.id.btnAgregarArticulo)
public void agregarArticulo() {
presenter.recibirArticulo(inputArticulo.getText().toString());
}
@OnClick(R.id.btnMostrarListaArticulos)
public void mostrarListadoArticulos() {
presenter.obtenerListadoArticulos();
}
}

Capa Presenter
La capa Presenter es la encargada de comunicar a la View y al Interactor para tener una
comunicacin entre si, en esta capa yo suelo hacer algunas validaciones para que puedan
acceder a la capa del Interactor si esto no sucede automaticamente regresa a la capa
View y jamas accede al Interactor.
Presenter implementa a 2 interfaces la propia de Presenter y una de Callback porque
como vimos en el diagrama una vez que se accede a la capa Interactor esta ya no sabe
como devolver los datos entonces generamos una interfaz la cual permite hacer un
Callback hacia la capa Presenter, esta interfaz contendra metodos que responderan a las
acciones que tome el Interactor y una vez responde le comunica al Presenter, ya que
notifica algo al Presenter este le notifica al View para darle una respuesta al usuario.

public class ListaArticulosPresenterImplement implements ListaArticulosPresenter,


ListaArticulosCallback {
public ListaArticulosView view;
public ListaArticuloInteractor interactor;
public ListaArticulosPresenterImplement(ListaArticulosView view, Context context)
{

this.view = view;
interactor = new ListaArticulosInteractorImplement(context);

}
@Override
public void recibirArticulo(String articulo) {
if(view != null) {
filtroDeCampos(articulo);
}
}
public void filtroDeCampos(String articulo) {
if (!articulo.equals("")) {
agregarArticulo(articulo);
} else {
view.errorInputArticulo();
}
}
public void agregarArticulo(String articulo) {
interactor.agregarArticulo( articulo, this);
}
@Override
public void obtenerListadoArticulos() {
if(view != null){
interactor.obtenerAllArticulos(this);
}
}
@Override
public void recibirArticuloEliminar(String articulo) {
}

Estos son los dos metodos que tiene Callback los cuales van a notificar a la capa View,
dependiendo de la accion que le de el Interactor.
@Override
public void notificarArticuloAgregado(ArrayList<String> articulo) {
if(view != null) {
view.limpiarInputArticulo();
view.mostrarListaArticulos(articulo);
}
}
@Override
public void notificarArticuloEliminado() {
}
}

Capa Interactor
La capa de interactor es la encargada de acceder a los datos, ya se por medio de una
base de datos localmente, archivos guardados en la memoria o internamente, como
tambien un servicio web.
El interactor como tal, debe de hacer uso del objeto callback o llamada de regreso,
porque este sera el encargado de retornar una notificacion, o el mismo dato obtenido por
el tipo de consumo de la informacion.

Podemos ver aqu en el codigo que se esta implementado una base de datos como tal con
SQLite, en donde esta encapsulada para solo usar un objeto de ella y poderla
implementar con mayor facilidad.
public class ListaArticulosInteractorImplement implements ListaArticuloInteractor {
DataBaseController dbController;
ArrayList<String> articulos = new ArrayList<>();
public ListaArticulosInteractorImplement(Context context) {
dbController = new DataBaseController(context);
}
En esta parte se ve como le pasamos como parametro el callBack, no es mas que una
interfaz y una vez obtenido el callback podemos usar la interfaz y asi poderla
implementar en el Presenter.
@Override
public void obtenerAllArticulos(final ListaArticulosCallback callback) {
getAllArticulos();
callback.notificarArticuloAgregado(articulos);
}
@Override
public void agregarArticulo(String articulo, final ListaArticulosCallback callback) {
dbController.insertarNuevoArticulo(articulo);
getAllArticulos();
callback.notificarArticuloAgregado(articulos);
}
public void getAllArticulos() {
limpiarListaArticulos();
articulos = dbController.getAllArticulos();
}
public void limpiarListaArticulos() {
articulos.clear();
}
@Override
public void eliminarArticulo(String articulo) {
}
}

Por que deberia usar Model View Presenter?


Para que una aplicacin se extendible, mantenible y testable requiere que mantener sus
capas separadas, ya que en android existen clases muy acopladas como es el caso de los
Cursores y Adaptadores. Las actividades suelen estar muy acopladas a nuestra interfaz y
nuestra lgica de negocio en un MVC clsico, el comn ejemplo est cuando decidimos
traer informacin local de algun lugar dentro del dispositivo para pintarla en una simple
lista hasta ah vamos bien ;pero que tal si en unas semanas decidimos traer los datos de
la red y olvidar esos datos locales Necesitaremos reescribir esa clase? pues la
respuesta es que s porque nuestra Activity o Fragment estar acoplada a nuestras vistas
y a la forma en que obtenemos los datos para pintarlos.
Si aplicamos el MVP de una forma limpia la vista jamas sabra de donde se obtienen los
datos y solo se enfocara en renderizarlos independizando la vista de la forma de
conseguir esos datos.

Vous aimerez peut-être aussi