Android/MVC. Implementació amb el patró observador

Què és el patró Model-Vista-Controlador?

modifica

El patró MVC (Model-Vista-Controlador) neix amb la idea d'independitzar les dades de la seva presentació i de la interacció que fa l'usuari sobre aquesta presentació. Consta de 3 parts fonamentals:

  • El Model: Conjunt de dades que manipulem. Envia a la Vista aquella part de la informació que en cada moment es vol mostrar, normalment per part de l'usuari.
  • El Controlador: Respon events (habitualment accions de l'usuari) i fa peticions al Model quan es fa alguna solicitud sobre la informació.
  • La Vista: És la visualització del Model. S'encarrega de mostrar les dades del Model en un format adequat per interactuar-hi des de la interfície d'usuari.

Hi ha diverses versions del patró MVC, però totes comparteixen un flux de control similar:

  1. L'usuari interactua amb la interfície, per exemple al prèmer un botó.
  2. El controlador reb l'avís d'aquesta interacció i gestiona l'event que arriba.
  3. El controlador accedeix al model, actualitzant-lo segons l'event de rebut.
  4. El controlador delega a la vista la tasca de mostrar la nova interfície amb les dades actualitzades. El model no té coneixement directe sobre la vista (excepte si s'implementa el patró observador).

Quina funció té l'observador dins del MVC?

modifica

Com explicàvem abans, el Model-Vista-Controlador es pot implementar de manera que el model no tingui cap visibilitat sobre la Vista. Això comporta que el controlador hagi de gestionar la interacció entre el Model i la Vista, cosa que ens augmenta l'acoblament. L'ús del patró observador permet al Model avisar directament a la Vista de qualsevol canvi, sense haver de passar pel controlador.

L'observador s'acostuma a implementar de la següent manera:

  • Vista: Observador del Model
  • Model: Observable

Per tant, en aquest cas:

  • El model defineix una interficie i els seus mètodes són els events que pot generar el model.
  • La vista implementa aquesta interficie.

Cal afegir que hi poden haver múltiples Observadors sobre el mateix Observable, i de fet en alguns casos és gairebé una necessitat.


D'altra banda, en fer servir el Patró Observador obtenim alguns avantatges, detallats a continuació:

  • Garanteix el principi de menor acoblament entre objectes que interactuen
  • Permet tenir molts observadors vinculats a un mateix observable i viceversa
  • Permet enviar dades a altres objectes d'una manera efectiva sense afectar
  • Es poden afegir o eliminar observadors de l'observable en qualsevol moment


L'Exemple: Una llista d'Estudiants modificable

modifica

Per posar en pràctica l'esquema Model-Vista-Controlador amb patró observador, implementarem un exemple amb una llista d'estudiants, que permeti afegir nous estudiants, esborrar el primer estudiant de la llista o esborrar-los tots.

La classe Estudiant

modifica

Comencem per crear la classe Estudiant, necessària per la representació d'un conjunt d'estudiants.




Com veiem, cada estudiant consta de 4 atributs:

  • Nom
  • Cognom
  • Naixement
  • DNI

Aquests atributs poden prendre valors aleatoris gràcies a la classe pròpia GeneradorEstudiant.java, o bé poden prendre vendre els valors que li especifiquem.

Classe GeneradorEstudiant

modifica

Per poder generar múltiples estudiants fàcilment, hem creat la classe GeneradorEstudiant que permet crear Estudiants amb Noms, Cognoms, data de naixement i dni generats aleatòriament.




Implementació del Model: Conjunt d'estudiants

modifica

El model és el conjunt d'estudiants. Necessitem l'existència d'una classe ConjuntEstudiants.java que encapsuli aquest model.




La classe consta d'una llista privada d'estudiants, i dels constructors bàsics. A més, li hem implementat les operacions bàsiques d'afegir i eliminar estudiants de la llista.

El model fa d'observable

modifica

Definim la interfície pública interna a ConjuntEstudiants que els nostres observadors hauran d'implementar, amb un únic mètode: onModificaConjuntEstudiants()




onModificaConjuntEstudiants() és l'event que s'executa quan hi ha algun canvi en el nostre model (ConjuntEstudiants).

El comportament d'observable ens requereix un mètode per vincular els Observadors. En aquest exemple es podria haver utilitzat un únic Observador, però fent-ho amb múltiples observadors és més generalista.





També necessitem un mètode per notificar als observadors quan es produeix una modificació en el model.





Els mètodes modificadors, és a dir, el d'afegir i els d'esborrar, han d'avisar als observadors de que hi ha hagut canvis. Per tant hem d'afegir una crida a notificaObservadors()




Implementació de la Vista: Vista de la llista d'estudiants

modifica

Com el nostre model és una llista d'estudiants, una manera raonable i senzilla de definir la Vista és partint d'una ListView, que la podem veure com una Vista gestionada per un Adapter. Crearem una classe pròpia que extengui de ListView.




La Vista fa d'observador

modifica

Ens cal afegir un mètode per vincular el model a la Vista i establir-la com a Observadora del Model




Tenim un TextView per representar cada estudiant. Ho describim en el fitxer estudiant_item.xml




Implementació del Controlador: l'Activitat Principal

modifica

El controlador és l'Activity. És el primer que actua quan hi ha una interacció de l'usuari amb la interfície. Té la responsabilitat de:

  • Crear la Vista
  • Crear el Model
  • Vincular la Vista com a observadora del Model.

Per tant, ha de tenir una visibilitat d'atribut sobre el model i sobre la vista.





Visualització de l'aplicació

modifica

Per aquest exemple s'ha utilitzat un Constraint Layout amb els següents components:

  • Un TextView, que mostra el títol "Llista d'Estudiants"
  • 3 botons: Afegir un estudiant/Esborrar un estudiant/Esborrar tots els estudiants






La nostra classe VistaDeLlistaEstudiants és una extensió d'una ListView, la qual cosa no pot aparèixer en un Layout XML. La solució és referenciar-la afegint-hi el prefix del package que la conté.




 
Model de components del patró MVC de la Llista d'Estudiants

Mostres d'execució

modifica


 
Exemple d'execució

Pàgines de referència

modifica

Pàgina d'Android Developer

Participants

modifica