Patrón MVC en Android

497

¿Es posible implementar el patrón modelo-vista-controlador en Java para Android?

¿O ya se implementa a través de Actividades? ¿O hay una mejor manera de implementar el patrón MVC para Android?

Mohit Deshpande
fuente
64
Tu pregunta es muy buena. Pero la respuesta marcada como solución no es correcta en mi opinión. Podría confundir a varias personas.
Saghar
44
Mira mis 2 publicaciones a partir de aquí Arquitectura de Android: MV?
Dori
1
¿También hay un conjunto adicional de reglas a seguir para adherirse a MVC o el desarrollo de Android ya está diseñado para MVC debido a la Actividad, XML, Recursos?
Llama de udun
3
@Dori, arreglo su enlace: Arquitectura de Android: ¿MV?
Andreybeta
Este artículo coincide exactamente con lo que está buscando, MVC en Android a través de un ejemplo práctico: digigene.com/architecture/android-architecture-part-2-mvc
Ali Nem

Respuestas:

239

En Android no tienes MVC, pero tienes lo siguiente:

  • Usted define su interfaz de usuario en varios archivos XML por resolución, hardware, etc.
  • Usted define sus recursos en varios archivos XML por configuración regional, etc.
  • Extiende clases como ListActivity , TabActivity y hace uso del archivo XML por los infladores .
  • Puede crear tantas clases como desee para su lógica empresarial.
  • Ya se han escrito muchas utilidades para usted: DatabaseUtils, Html.
Pentium10
fuente
3
@JDPekham, ¿por qué dice "No puede crear una instancia de una actividad sin hablar con su diseño / vista"? Crear una instancia de una actividad no requiere hablar con las vistas, de hecho, hablar con las vistas no forma parte de la instanciación de la Actividad. PUEDE (pero no tiene que hacerlo) llamar a varios métodos de Actividad que interactúan con sus puntos de vista cuando lo considere conveniente. Segunda pregunta: suponiendo que la actividad está destinada a asumir el papel de "controlador" (creo que muchos desarrolladores de Android lo ven de esa manera) ¿por qué no hablar con sus puntos de vista de la actividad?
8
Para cualquiera que diga que "Android es MVC", intente Backbone.js (sí, js del lado del cliente) durante una semana, y luego vuelva y diga que "Android es MVC". Finalmente entenderás la pregunta y por qué seguimos preguntando :)
Mark Peterson
14
"En Android no tienes MVC" ???? En Android, como en otros idiomas, tienes MVC si quieres MVC.
Lorenzo Barbagli
1
@LorenzoBarbagli Quiere decir que Android no impone MVC en las aplicaciones por diseño (como lo hace iOS). Debe implementar un sabor de MVC, MVP u otra cosa usted mismo si desea lograr lo que MVC proporciona, es decir, la separación de preocupaciones y un Modelo aislado y fácilmente comprobable.
Piovezan
No. Definitivamente hay MVC en Android, pero más implícitamente. Simplemente se implementa de una manera diferente según la forma en que Android estructura todo.
6rchid
229

No hay un patrón MVC universalmente único. MVC es un concepto más que un marco de programación sólido. Puede implementar su propio MVC en cualquier plataforma. Siempre y cuando se apegue a la siguiente idea básica, implementará MVC:

  • Modelo: qué renderizar
  • Vista: Cómo renderizar
  • Controlador: eventos, entrada del usuario

También piense de esta manera: cuando programe su modelo, el modelo no debería tener que preocuparse por el renderizado (o el código específico de la plataforma). El modelo diría a la vista, no me importa si su renderizado es Android o iOS o Windows Phone, esto es lo que necesito que renderice. La vista solo manejaría el código de representación específico de la plataforma.

Esto es particularmente útil cuando usa Mono para compartir el modelo con el fin de desarrollar aplicaciones multiplataforma.

Ramon Chan
fuente
12
Si bien eso es cierto, y bien dicho, ¡esto es teoría y la gente es práctica!
TWiStErRob
1
@TWiStErRob Pero los patrones de diseño son ideas teóricas y abstractas que no tienen una sola forma de realizarlas. Proclamar "No quiero entender MVC en teoría, solo quiero tenerlo implementado" me parece que podría resultar en "Voy a poner una lavadora en mi cocina porque las lavadoras implementan el patrón Cleaner ™ y las cocinas lo necesitan ".
Lukas Juhrich
1
Creo que los ejemplos son invaluables porque muestran lo que otras personas han inventado. Uno puede mejorar sobre ellos y aprender de su esfuerzo. No es necesario que todos reinventen la rueda. En el contexto de Android y su ciclo de vida complejo, hay problemas que no se abordan en un patrón de diseño, pero todos los enfrentarán. Esto es lo que quise decir con práctica.
TWiStErRob
47

Las acciones, vistas y actividades en Android son la forma integrada de trabajar con la interfaz de usuario de Android y son una implementación del patrón modelo-vista-modelo de vista (MVVM) , que es estructuralmente similar (en la misma familia que) modelo-vista -controlador.

Que yo sepa, no hay forma de salir de este modelo. Probablemente se pueda hacer, pero es probable que pierda todos los beneficios que tiene el modelo existente y tenga que reescribir su propia capa de interfaz de usuario para que funcione.

Derick Bailey
fuente
29

Después de algunas búsquedas, la respuesta más razonable es la siguiente:

MVC ya está implementado en Android como:

  1. Ver = diseño, recursos y clases integradas como Buttonderivadas de android.view.View.
  2. Controlador = Actividad
  3. Modelo = las clases que implementan la lógica de la aplicación

(Esto por cierto no implica lógica de dominio de aplicación en la actividad).

Lo más razonable para un desarrollador pequeño es seguir este patrón y no intentar hacer lo que Google decidió no hacer.

PD Tenga en cuenta que la actividad a veces se reinicia, por lo que no es lugar para los datos del modelo (la forma más fácil de provocar un reinicio es omitir android:configChanges="keyboardHidden|orientation"del XML y encender su dispositivo).

EDITAR

Podemos estar hablando de MVC , pero será así decir FMVC , Framework - Model - View - Controller . El Framework (el sistema operativo Android) impone su idea del ciclo de vida de los componentes y los eventos relacionados, y en la práctica, el Controlador ( Activity/ Service/ BroadcastReceiver) es, ante todo, responsable de hacer frente a estos eventos expuestos al Framework (como onCreate () ). ¿Se debe procesar la entrada del usuario por separado? Incluso si debería, no puede separarlo, los eventos de entrada del usuario también provienen de Android.

De todos modos, cuanto menos código que no sea específico de Android pongas en tu Activity/ Service/ BroadcastReceiver, mejor.

18446744073709551615
fuente
3
La actividad tiene acceso directo a la interfaz de usuario, mientras que en el controlador MVC no debería saber sobre la vista (solo viceversa).
Konrad Morawski
2
@KonradMorawski Hmmm .... ¿Una vista para saber cómo mostrar cosas y sobre el controlador ? ¿Un niño de, digamos, Buttonsaber sobre el controlador ? Parece más lógico que las Vistas solo sepan sobre mostrar cosas. Y teniendo en cuenta que el Modelo solo conoce la naturaleza de los datos, es por eso que se necesita el Controlador : algo debe saber tanto sobre el Modelo como sobre la Vista .
18446744073709551615
44
Obviamente, la Vista necesita saber sobre el controlador para delegar eventos al controlador. El controlador lo sigue hasta el modelo e informa a la Vista cuáles fueron los resultados (para que pueda mostrarlo). El controlador no infla la vista (mientras que Activity sí lo hace), ni debe saber algo sobre botones, cuadros de texto, listas, etc. (mientras que Activity lo sabe).
Konrad Morawski
1
Creo que Servicetambién
estamos
1
¿Has oído hablar de observadores? La mejor separación que Iv ha encontrado hasta ahora es cuando 1. el controlador solo tiene una instancia del modelo, 2. el modelo no conoce el controlador o la vista, pero la vista puede registrarse como observador del modelo (por lo que el modelo sabe un poco sobre la vista pero no sabe quién es y él no le importa): cuando el modelo se realiza con la carga de datos, notifica a todos los observadores (generalmente 1) y 3. view solo tiene una instancia de modelo para extraer los datos. De esta manera, solo hay 2 dependencias para todos los marcos MVC. Creo que 2 es mínimo, por lo que debería ser el mejor diseño.
Srneczek
18

No hay un patrón MVC único al que puedas obedecer. MVC simplemente declara más o menos que no debe mezclar datos y vistas, de modo que, por ejemplo, las vistas son responsables de mantener datos o clases que procesan datos que afectan directamente a la vista.

Pero, sin embargo, la forma en que Android maneja las clases y los recursos, a veces incluso te ves obligado a seguir el patrón MVC. En mi opinión, más complicadas son las actividades que a veces son responsables de la vista, pero que, sin embargo, actúan como controlador al mismo tiempo.

Si define sus vistas y diseños en los archivos XML, cargue sus recursos desde la carpeta res, y si evita más o menos mezclar estas cosas en su código, entonces de todos modos está siguiendo un patrón MVC.

RoflcoptrException
fuente
14

Puede implementar MVC en Android, pero no es "compatible de forma nativa" y requiere un poco de esfuerzo.

Dicho esto, personalmente tiendo a MVP como un patrón arquitectónico mucho más limpio para el desarrollo de Android. Y al decir MVP quiero decir esto:

ingrese la descripción de la imagen aquí

También he publicado una respuesta más detallada aquí .

Después de jugar con los diversos enfoques para la implementación de MVC / MVP en Android, se me ocurrió un patrón arquitectónico razonable, que describí en esta publicación: Patrones arquitectónicos MVP y MVC en Android .

Vasiliy
fuente
14

El mejor recurso que encontré para implementar MVC en Android es esta publicación :

Seguí el mismo diseño para uno de mis proyectos, y funcionó muy bien. Soy un principiante en Android, así que no puedo decir que esta sea la mejor solución.

Hice una modificación: creé una instancia del modelo y el controlador para cada actividad en la clase de aplicación para que no se vuelvan a crear cuando cambia el modo de retrato horizontal.

Hervé Donner
fuente
8
Sería genial obtener un resumen en caso de que el artículo se elimine algún día.
pqsk
12

Estoy de acuerdo con JDPeckham, y creo que XML solo no es suficiente para implementar la parte de la interfaz de usuario de una aplicación.

Sin embargo, si considera la Actividad como parte de la vista, la implementación de MVC es bastante sencilla. Puede anular la aplicación (tal como lo devuelve getApplication () en Activity) y es aquí donde puede crear un controlador que sobreviva durante la vida útil de su aplicación.

(Alternativamente, puede usar el patrón singleton como lo sugiere la documentación de la Aplicación)

Typingduck
fuente
12

MVC- Arquitectura en Android Es mejor seguir cualquier MVP en lugar de MVC en Android. Pero aún así, según la respuesta a la pregunta, esta puede ser la solución

Ingrese la descripción de la imagen aquí

Descripción y pautas

     Controller -
        Activity can play the role.
        Use an application class to write the
        global methods and define, and avoid
        static variables in the controller label
    Model -
        Entity like - user, Product, and Customer class.
    View -
        XML layout files.
    ViewModel -
        Class with like CartItem and owner
        models with multiple class properties
    Service -
        DataService- All the tables which have logic
        to get the data to bind the models - UserTable,
        CustomerTable
        NetworkService - Service logic binds the
        logic with network call - Login Service
Helpers -
        StringHelper, ValidationHelper static
        methods for helping format and validation code.
SharedView - fragmets or shared views from the code
        can be separated here

AppConstant -
        Use the Values folder XML files
        for constant app level

NOTA 1:

Ahora aquí está la pieza de magia que puedes hacer. Una vez que haya clasificado el fragmento de código, escriba una clase de interfaz base como, por ejemplo, IEntity e IService. Declarar métodos comunes. Ahora cree la clase abstracta BaseService y declare su propio conjunto de métodos y separe el código.

NOTA 2: Si su actividad presenta múltiples modelos, en lugar de escribir el código / lógica en la actividad, es mejor dividir las vistas en fragmentos. Entonces es mejor. Entonces, en el futuro, si se necesita más modelo para aparecer en la vista, agregue un fragmento más.

NOTA 3: La separación del código es muy importante. Cada componente de la arquitectura debe ser independiente y no tener una lógica dependiente. Si por casualidad tiene algo que depende de la lógica, escriba una clase de lógica de mapeo en el medio. Esto te ayudará en el futuro.

DropAndTrap
fuente
11

La creación de la interfaz de usuario de Android utilizando diseños, recursos, actividades e intentos es una implementación del patrón MVC. Consulte el siguiente enlace para obtener más información al respecto: http://www.cs.otago.ac.nz/cosc346/labs/COSC346-lab2.2up.pdf

espejo para el pdf

Arunabh Das
fuente
77
el enlace está roto señor
Rat-a-tat-a-tat Ratatouille
2
Parece que este archivo COSC346-lab2.2up.pdf no incluye todos los detalles.
james
9

El patrón MVC de Android se implementa (tipo de) con sus clases de Adaptador . Reemplazan un controlador con un "adaptador". La descripción del adaptador indica:

Un objeto Adapter actúa como un puente entre un AdapterView y los datos subyacentes para esa vista.

Solo estoy buscando esto para una aplicación de Android que lee desde una base de datos, por lo que aún no sé qué tan bien funciona. Sin embargo, parece un poco como la arquitectura Model-View-Delegate de Qt, que afirman que es un paso adelante de un patrón MVC tradicional. Al menos en la PC, el patrón de Qt funciona bastante bien.

Ben
fuente
9

Aunque esta publicación parece ser antigua, me gustaría agregar las siguientes dos para informar sobre el desarrollo reciente en esta área para Android:

Android- Encuadernación: proporciona un marco que permite vincular los widgets de vista de Android al modelo de datos. Ayuda a implementar patrones MVC o MVVM en aplicaciones de Android.

roboguice : RoboGuice elimina las conjeturas del desarrollo. Inyecte su Vista, Recurso, Servicio del sistema o cualquier otro objeto, y deje que RoboGuice se encargue de los detalles.

Mahendra Liya
fuente
9

Controlador de vista de modelo (MVC)

ingrese la descripción de la imagen aquí


Descripción:

  • Cuando tenemos que centrar grandes proyectos en el desarrollo de software, MVC se usa generalmente porque es una forma universal de organizar los proyectos.
  • Los nuevos desarrolladores pueden adaptarse rápidamente al proyecto.
  • Ayuda en el desarrollo de grandes proyectos y multiplataforma también.

El patrón MVC es esencialmente este:

  • Modelo: Qué mostrar. Esta puede ser la fuente de datos (Ej: Servidor, Datos sin procesar en la aplicación)
  • Vista: cómo se muestra. Este puede ser el xml. Por lo tanto, actúa como un filtro de presentación. Se adjunta una vista a su modelo (o parte del modelo) y obtiene los datos necesarios para la presentación.
  • Controlador: manejo de eventos como la entrada del usuario. Esta es la actividad

Característica importante de MVC: podemos modificar el modelo, la vista o el controlador que aún no afectan a los demás

  • Digamos que cambiamos el color de la vista, el tamaño de la vista o la posición de la vista. Al hacerlo, no afectará al modelo o al controlador
  • Supongamos que cambiamos el modelo (en lugar de los datos obtenidos del servidor de los datos) aún no afectará la vista y el controlador
  • Digamos que cambiamos el controlador (lógica en la actividad) no afectará el modelo y la vista
Devrath
fuente
2
Solo he usado el controlador como un conducto para ver la información del modelo / retransmisión. Tengo curiosidad por saber cómo tienen modelo y visión en contacto directo entre sí. ¿Tiene una fuente o ejemplo de esta implementación?
Jacksonkr
7

Creo que la explicación simplificada más útil está aquí: http://www.cs.otago.ac.nz/cosc346/labs/COSC346-lab2.2up.pdf

De todo lo que he visto y leído aquí, implementar todas estas cosas lo hace más difícil y no encaja bien con otras partes de Android.

Tener una actividad para implementar otros oyentes ya es la forma estándar de Android. La forma más inofensiva sería agregar Java Observer como las diapositivas describen y agrupan onClick y otros tipos de acciones en funciones que aún están en la Actividad.

La forma de Android es que la Actividad hace ambas cosas. Combatirlo en realidad no facilita la extensión o la codificación futura.

Estoy de acuerdo con la segunda publicación . Ya está implementado, pero no es la forma en que las personas están acostumbradas. Ya sea que esté o no en el mismo archivo o no, ya hay separación. No es necesario crear una separación adicional para que se ajuste a otros lenguajes y sistemas operativos.

Edmund Chang
fuente
66
El enlace que proporcionó está roto.
mmBs
6

Fue sorprendente ver que ninguna de las publicaciones aquí respondió la pregunta. Son demasiado generales, vagos, incorrectos o no abordan la implementación en Android.

En MVC, la capa de Vista solo sabe cómo mostrar la interfaz de usuario (UI). Si se necesita algún dato para esto, lo obtiene de la capa Modelo . Pero la Vista NO le pide directamente al modelo que encuentre los datos, lo hace a través del Controlador . Entonces, el Controlador  llama al Modelo para proporcionar los datos requeridos para la Vista . Una vez que los datos están listos, el Controlador informa a la Vista que los datos están listos para ser adquiridos del Modelo . Ahora la Vista puede obtener los datos del Modelo .

Este flujo se puede resumir de la siguiente manera:

ingrese la descripción de la imagen aquí

Vale la pena señalar que la Vista puede conocer la disponibilidad de los datos en el  Modelo  a través del Controlador , también conocido como  MVC pasivo , o al observar los datos en el Modelo al registrar observables en él, que es MVC activo .

En la parte de implementación, una de las primeras cosas que viene a la mente es ¿qué componente de Android se debe usar para la Vista ? Activity  o Fragment ?

La respuesta es que no importa y ambos se pueden usar. La Vista debería poder presentar la interfaz de usuario (IU) en el dispositivo y responder a la interacción del usuario con la IU. Ambos Activity  y Fragment  proporcionan los métodos necesarios para esto.

En la aplicación de ejemplo utilizada en este artículo , la he usado Activity para la capa Vista , pero Fragment  también puedo usarla.

La aplicación de muestra completa se puede encontrar en la rama 'mvc' de mi repositorio de GitHub aquí .

También he tratado los pros y los contras de la arquitectura MVC en Android a través de un ejemplo aquí .

Para aquellos interesados, he comenzado una serie de artículos sobre arquitectura de aplicaciones de Android aquí en los que comparo las diferentes arquitecturas, es decir, MVC, MVP, MVVM, para el desarrollo de aplicaciones de Android a través de una aplicación de trabajo completa.

Ali Nem
fuente
He tomado un curso de arquitectura donde el instructor dice que las actividades y los fragmentos no deben usarse como vistas y, de hecho, deben ser controladores y las vistas deben ser archivos separados. ¿Tienes alguna opinión o razonamiento sobre por qué esto no debería ser?
brandonx
No creo que el instructor sea exacto en eso. Elegir actividad o fragmento como controlador significa pasar contexto al controlador. Por otro lado, la vista también necesita contexto para dibujar en la pantalla. De esta forma, es decir, pasando el contexto al controlador, la aplicación es propensa a la pérdida de memoria y creo que el controlador no debe llevar el estado.
Ali Nem
5

Cansado del desastre de MVx en Android, recientemente he creado una pequeña biblioteca que proporciona un flujo de datos unidireccional y es similar al concepto de MVC: https://github.com/zserge/anvil

Básicamente, tiene un componente (actividad, fragmento y grupo de vista). En el interior, define la estructura y el estilo de la capa de vista. También define cómo deben vincularse los datos a las vistas. Finalmente, puede vincular a los oyentes en el mismo lugar.

Luego, una vez que se modifiquen sus datos, se llamará al método global "render ()" y sus vistas se actualizarán de manera inteligente con los datos más recientes.

Aquí hay un ejemplo del componente que tiene todo dentro para la compactación del código (por supuesto, el Modelo y el Controlador se pueden separar fácilmente). Aquí "count" es un modelo, el método view () es una vista y "v -> count ++" es un controlador que escucha los clics de los botones y actualiza el modelo.

public MyView extends RenderableView {
  public MyView(Context c) {
      super(c);
  }

  private int count = 0;

  public void view() {
    frameLayout(() -> {              // Define your view hierarchy
      size(FILL, WRAP);
      button(() -> {
          textColor(Color.RED);      // Define view style
          text("Clicked " + count);  // Bind data
          onClick(v -> count++);     // Bind listeners
      });
    });
  }

Con el modelo y el controlador separados se vería así:

button(() -> {
   textColor(Color.RED);
   text("Clicked " + mModel.getClickCount());
   onClick(mController::onButtonClicked);
});

Aquí, en cada botón, se aumentará el número, luego se llamará "render ()" y se actualizará el texto del botón.

La sintaxis se vuelve más agradable si usa Kotlin: http://zserge.com/blog/anvil-kotlin.html . Además, hay una sintaxis alternativa para Java sin lambdas.

La biblioteca en sí es muy liviana, no tiene dependencias, no usa reflejos, etc.

(Descargo de responsabilidad: soy el autor de esta biblioteca)

zserge
fuente
4

Según la explicación que explicó el equipo de Xamarin (en el MVC de iOS "Sé que parece extraño, pero espera un segundo"):

  • El modelo (datos o lógica de aplicación),
  • La vista (interfaz de usuario) y
  • El controlador (código detrás).

Puedo decir esto:

El modelo en Android es simplemente el objeto parcelable. La vista es el diseño XML, y el controlador es la (actividad + su fragmento).

* Esta es solo mi opinión, no de ningún recurso o libro.

zaPlayer
fuente
3

He visto que muchas personas dicen que MVC ya está implementado en Android, pero no es cierto. Android no sigue MVC por defecto.

Debido a que Google nunca impondrá las restricciones de una implementación de MVC como iPhone, pero depende de los desarrolladores qué patrón o técnica desean en su proyecto, en aplicaciones pequeñas o simples no se requiere el uso de MVC, sino como aplicación crece y se complica y requiere modificaciones de su código en años posteriores, luego surge la necesidad del patrón MVC en Android.

Proporciona una manera fácil de modificar el código y también ayuda a reducir los problemas. Si desea implementar MVC en Android, siga este enlace a continuación y disfrute de la implementación de MVC en su proyecto.

http://www.therealjoshua.com/2011/11/android-architecture-part-1-intro/

Pero hoy en día creo que MVP junto con Android Architectural Pattern es una de las mejores opciones que los desarrolladores deberían usar para una aplicación de Android limpia y robusta.

Lucky Rana
fuente
1
Convenido. Android tiene suficiente flexibilidad para ahorcarse. Esa actividad tuya puede volverse gigantesca y complicada rápidamente, ya que maneja los tres aspectos de MVC.
Scott Biggs
2

Cuando aplicamos MVC, MVVM o Presentation Model a una aplicación de Android, lo que realmente queremos es tener un proyecto estructurado claro y, lo que es más importante, más fácil para las pruebas unitarias.

Por el momento, sin un marco de terceros, generalmente tiene mucho código (como addXXListener (), findViewById (), etc.), que no agrega ningún valor comercial.

Además, debe ejecutar las pruebas unitarias de Android en lugar de las pruebas JUnit normales, que tardan años en ejecutarse y hacen que las pruebas unitarias sean poco prácticas. Por estas razones, hace algunos años comenzamos un proyecto de código abierto, RoboBinding : un marco de modelo de presentación de enlace de datos para la plataforma Android.

RoboBinding lo ayuda a escribir código de interfaz de usuario que es más fácil de leer, probar y mantener. RoboBinding elimina la necesidad de código innecesario como addXXListener o algo así , y cambia la lógica de la interfaz de usuario al Modelo de presentación, que es un POJO y se puede probar a través de pruebas JUnit normales . RoboBinding en sí viene con más de 300 pruebas JUnit para garantizar su calidad.

Cheng
fuente
1

Según tengo entendido, la forma en que Android maneja el patrón MVC es como:

Tienes una Actividad, que sirve como controlador. Tiene una clase cuya responsabilidad es obtener los datos: el modelo, y luego tiene la clase Vista, que es la vista.

Cuando se habla de la vista, la mayoría de la gente piensa solo por su parte visual definida en el xml. No olvidemos que la Vista también tiene una parte del programa con sus constructores, métodos, etc., definidos en la clase java.

Rados
fuente