vista tutorial que programacion patron modelo mac implementar español controlador c# wpf mvvm

c# - que - wpf mvvm tutorial español



¿Por qué usar MVVM? (13)

De acuerdo, he estado investigando el patrón de MVVM, y cada vez que intenté investigarlo, me rendí por una serie de razones:

  1. Codificación innecesaria de larga duración
  2. No hay ventajas aparentes para los codificadores (no hay diseñadores en mi oficina. Actualmente solo yo mismo seré otro codificador)
  3. ¡No hay muchos recursos / documentación de buenas prácticas! (O al menos difícil de encontrar)
  4. No puedo pensar en un solo escenario donde esto sea ventajoso.

Estoy a punto de darme por vencido una vez más, y pensé en preguntar si alguien respondía las razones anteriores.

Honestamente, no puedo ver una ventaja de usar esto para una codificación única / asociada. Incluso en proyectos complejos con 10 de ventanas. Para mí, el DataSet es una vista lo suficientemente buena y vinculante como en la respuesta de Brent siguiente question

¿Podría alguien mostrar un ejemplo de cómo usar el patrón MVVM del tiempo ahorrado en comparación con XAML DataBinding?

El 100% de mi enlace está hecho en XAML en este momento. Y, por lo tanto, no veo el objetivo de la máquina virtual, ya que es solo un código adicional detrás del que tengo que escribir y del que dependo.

EDITAR:
Después de pasar la tarde investigando sobre MVVM, finalmente encontré algo que me hizo darme cuenta de los verdaderos beneficios de esta answer .


Resumen

  • El uso de todos los patrones es situacional, y el beneficio (si hay alguno) siempre se encuentra en una complejidad reducida.
  • MVVM nos guía sobre cómo distribuir responsabilidades entre clases en una aplicación GUI.
  • ViewModel proyecta los datos del Modelo en un formato que se ajusta a la Vista.
  • Para proyectos triviales, MVVM es innecesario. Usar solo View es suficiente.
  • Para proyectos simples, la división ViewModel / Model puede ser innecesaria, y solo usar un Model y una View es lo suficientemente bueno.
  • El modelo y el modelo de vista no necesitan existir desde el principio y pueden introducirse cuando se necesiten.

Cuándo usar patrones y cuándo evitarlos

Para una aplicación lo suficientemente simple, cada patrón de diseño es excesivo. Supongamos que escribe una aplicación GUI que muestra un solo botón que cuando se presiona muestra "Hello world". En este caso, los patrones de diseño como MVC, MVP, MVVM agregan mucha complejidad, sin agregar ningún valor.

En general, siempre es una mala decisión introducir un patrón de diseño simplemente porque encaja un poco. Los patrones de diseño deben usarse para reducir la complejidad, ya sea reduciendo directamente la complejidad general o reemplazando la complejidad desconocida con la complejidad familiar. Si el patrón de diseño no puede reducir la complejidad en ninguna de estas 2 formas, no lo use.

Para explicar la complejidad familiar y desconocida, tome las siguientes 2 secuencias de caracteres:

  • "D. € | Ré% dfà? C"
  • "CorrectHorseBatteryStaple"

Si bien la segunda secuencia de caracteres es dos veces la longitud de la primera secuencia, es más fácil de leer, más rápida de escribir y más fácil de recordar que la primera secuencia, todo porque es más familiar. Lo mismo es cierto para los patrones familiares en el código.

Tenga en cuenta que algunos patrones pueden no ser familiares para todos los desarrolladores que van a trabajar con el código en el futuro. En términos del ejemplo anterior, la siguiente secuencia puede o no ser más fácil de recordar que cualquiera de las secuencias anteriores, dependiendo de la experiencia y el entrenamiento de la persona que la recuerda: "3.14159265358979323846264338327950". En algunos casos, cuando se trata de patrones de diseño más avanzados, solo tiene sentido utilizar un patrón de diseño si los desarrolladores de mantenimiento ya están familiarizados con él.

MVVM

Dicho esto, profundicemos en el tema de MVVM por medio de un ejemplo. MVVM nos guía sobre cómo distribuir responsabilidades entre clases en una aplicación GUI (o entre capas, más sobre esto más adelante), con el objetivo de tener un pequeño número de clases, manteniendo al mismo tiempo el número de responsabilidades por clase pequeñas y bien definidas.

La MVVM ''adecuada'' supone al menos una aplicación moderadamente compleja, que trata con los datos que obtiene de "algún lugar". Puede obtener los datos de una base de datos, un archivo, un servicio web o de una miríada de otras fuentes.

Ejemplo

En nuestro ejemplo, tenemos 2 clases View y Model , pero no ViewModel . El Model envuelve un archivo csv que lee al inicio y lo guarda cuando la aplicación se apaga, con todos los cambios que el usuario realizó en los datos. La View es una clase de ventana que muestra los datos del Model en una tabla y permite que el usuario edite los datos. El contenido de csv podría verse algo así:

ID, Name, Price 1, Stick, 5$ 2, Big Box, 10$ 3, Wheel, 20$ 4, Bottle, 3$

Nuevos requisitos: Mostrar precio en euros

Ahora se nos pide que hagamos un cambio en nuestra aplicación. Los datos consisten en una grilla bidimensional que ya tiene una columna de "precio", que contiene un precio en USD. Necesitamos agregar una nueva columna que muestre los precios en euros además de los en USD, basados ​​en una tasa de cambio predefinida. El formato del archivo csv no debe cambiar porque otras aplicaciones funcionan con el mismo archivo, y estas otras aplicaciones no están bajo nuestro control.

Una posible solución es simplemente agregar la nueva columna a la clase Model . Esta no es la mejor solución, porque el Model guarda todos los datos que expone en la csv, y no queremos una nueva columna de precios del Euro en el csv. Entonces, el cambio al Model no sería trivial, y también sería más difícil describir lo que hace la clase Modelo, que es un olor a código .

También podríamos hacer el cambio en la View , pero nuestra aplicación actual utiliza el enlace de datos para mostrar los datos directamente como lo proporciona nuestra clase de Model . Debido a que nuestro marco de GUI no nos permite introducir una columna calculada adicional en una tabla cuando la tabla está unida a datos a una fuente de datos, tendríamos que hacer un cambio significativo en la View para que esto funcione, haciendo que la View mucho mas complejo.

Presentamos ViewModel

No hay ViewModel en la aplicación porque hasta ahora el Model presenta los datos exactamente de la manera en que la Csv lo necesita, que también es la forma en que View necesitaba. Tener un ViewModel entre ellos hubiera sido una complejidad añadida sin propósito. Pero ahora que el Model ya no presenta los datos de la manera en que View necesita, escribimos un ViewModel . ViewModel proyecta los datos del Model de tal forma que la View puede ser simple. Anteriormente, la clase View suscribió a la clase Model . Ahora la nueva clase ViewModel suscribe a la clase Model y expone los datos del Model a la View , con una columna adicional que muestra el precio en Euros. La View ya no conoce el Model , ahora solo conoce ViewModel , que desde el punto de View tiene el mismo aspecto que el Model anterior, excepto que los datos expuestos contienen una nueva columna de solo lectura.

Nuevos requisitos: forma diferente de formatear los datos

La siguiente solicitud del cliente es que no deberíamos mostrar los datos como filas en una tabla, sino mostrar la información de cada elemento (también conocido como fila) como una tarjeta / caja, y mostrar 20 cuadros en la pantalla en una cuadrícula 4x5, mostrando 20 cajas a la vez. Debido a que mantuvimos la lógica de la View simple, simplemente reemplazamos la View completo con una nueva clase que hace lo que el cliente desea. Por supuesto, hay otro cliente que prefiere la View , por lo que ahora debemos admitir ambos. Debido a que toda la lógica comercial común ya está en ViewModel eso no es un gran problema. Así que podemos resolver esto cambiando el nombre de la clase View en TableView y escribiendo una nueva clase CardView que muestre los datos en un formato de tarjeta. También tendremos que escribir un código de pegamento, que podría ser un oneliner en la función de inicio.

Nuevos requisitos: tipo de cambio dinámico

La siguiente solicitud del cliente es que retiremos la tasa de cambio de internet, en lugar de usar una tasa de cambio predefinida. Este es el punto donde volvemos a visitar mi declaración anterior sobre "capas". No cambiamos nuestra clase de Model para proporcionar una tasa de cambio. En cambio, escribimos (o encontramos) una clase adicional completamente independiente que proporciona la tasa de cambio. Esa nueva clase se convierte en parte de la capa del modelo, y nuestro ViewModel consolida la información del modelo csv y del modelo de tasa de cambio, que luego presenta a la View . Para este cambio, ni la vieja clase Model ni la clase View deben tocarse. Bueno, necesitamos cambiar el nombre de la clase Model a CsvModel y llamamos a la nueva clase ExchangeRateModel .

Si no hubiéramos presentado ViewModel cuando lo hicimos, pero hubiéramos esperado hasta ahora para hacerlo, la cantidad de trabajo para presentar ViewModel ahora sería mayor porque necesitamos eliminar cantidades significativas de funcionalidad tanto de la View como del Model y mueva la funcionalidad al ViewModel .

Epílogo de pruebas unitarias

El propósito principal de MVVM no es que el código en el Modelo y el Modelo de Vista se pueda someter a Prueba Unitaria. El propósito principal de MVVM es que el código se divida en clases con un número reducido de responsabilidades bien definidas. Uno de los muchos beneficios de tener un código que consiste en clases con un número reducido de responsabilidades bien definidas es que es más fácil poner el código bajo Prueba Unitaria. Un beneficio mucho mayor es que el código es más fácil de comprender, mantener y modificar.


Beneficios de MVVM

  1. Complejidad reducida
  2. Aislamiento de Diseño y Desarrollo.
  3. Inyección de dependencia.
  4. La principal ventaja es cuando tienes una aplicación de Windows Phone bien estructurada en MVVM y deseas desarrollar la misma para Windows Metro Desktop. Lo único que quieres es concretar en el diseño ya que el mismo modelo de vista se puede usar tal como es.

Espero eso ayude.


Del artículo de Josh Smith sobre MVVM :

Además de las características de WPF (y Silverlight 2) que hacen que MVVM sea una forma natural de estructurar una aplicación, el patrón también es popular porque las clases de ViewModel son fáciles de probar por unidad. Cuando la lógica de interacción de una aplicación reside en un conjunto de clases de ViewModel, puede escribir fácilmente el código que la prueba. En cierto sentido, las vistas y las pruebas unitarias son solo dos tipos diferentes de consumidores de ViewModel. Tener un conjunto de pruebas para ViewModels de una aplicación proporciona pruebas de regresión gratuitas y rápidas, lo que ayuda a reducir el costo de mantener una aplicación a lo largo del tiempo.

Para mí, esta es la razón más importante para usar MVVM.

Antes, tenía controles que machacaban la vista y el modelo de vista juntos. Pero una vista esencialmente tiene eventos de mouse y teclado como entrada y píxeles dibujados como salida. ¿Cómo pruebas tu unidad algo así? MVVM hace que este problema desaparezca ya que separa la vista no comprobable del modelo de vista comprobable y mantiene la capa de vista lo más delgada posible.


Desde wintellect.com/CS/blogs/jlikness/archive/2010/04/14/… :

¿Por qué deberías, como desarrollador, preocuparte por el patrón Model-View-ViewModel? Hay una serie de beneficios que este patrón brinda a WPF y al desarrollo de Silverlight. Antes de continuar, pregúntese:

  • ¿Necesita compartir un proyecto con un diseñador y tener la flexibilidad para que el trabajo de diseño y el trabajo de desarrollo ocurran casi simultáneamente?
  • ¿Exige pruebas unitarias exhaustivas para sus soluciones?
  • ¿Es importante que tenga componentes reutilizables, tanto dentro como a través de proyectos en su organización?
  • ¿Desea más flexibilidad para cambiar su interfaz de usuario sin tener que refactorizar otra lógica en la base de códigos?

Si respondió "sí" a alguna de estas preguntas, estos son solo algunos de los beneficios que puede aportar el uso del modelo MVVM para su proyecto.


Estoy de acuerdo en que usar MVVM pone más peso en nuestros hombros al escribir código de mineral, pero mira el lado bueno donde todo está aislado, entonces si eres diseñador, entonces puedes diseñar tu programa y otro puede codificarlo para ti y otro hace la base de datos. para usted, mire cómo es el entorno sostenible en el que estará, especialmente en grandes aplicaciones empresariales si no usa MVVM, entonces el mantenimiento casi está matando ... Yo mismo lo usé al desarrollar la solución ERP ahora el mantenimiento es bastante directo porque de ese nivel de aislamiento


Hay muchas cosas buenas acerca de MVVM, pero quizás lo más importante es la capacidad de probar tu código (la unidad prueba los Modelos de Vista).

La falta de conexión entre la vista y el modelo de vista realmente ayuda al acoplamiento flojo también. Se vuelve realmente fácil reutilizar los componentes que codifica.


Implementar patrones y seguir las mejores prácticas a menudo parece una actividad sin sentido, pero te convertirás en un converso cuando, meses después, tu jefe te pida que agregue o modifique una función. Usando MVVM (y patrones en general), en realidad podrá seguir su propio código y cumplir con el requisito en unas pocas horas o días en el peor en lugar de semanas o meses. (Es probable que este cambio sea solo unas pocas líneas de código, en lugar de pasar semanas intentando descubrir cómo hiciste lo que hiciste, incluso antes de intentar agregar nuevas funciones).

Seguimiento: los patrones y las mejores prácticas ralentizarán el desarrollo inicial y, a menudo, son difíciles de vender para la gerencia y la ingeniería. El retorno de la inversión (ROI en términos biz) proviene de tener un código bien estructurado que es realmente mantenible, escalable y extensible.

Como ejemplo, si sigue MVVM correctamente, debería poder realizar cambios muy drásticos en la lógica de visualización, como intercambiar una vista completa, sin impacto en la lógica de datos y biz.

Una idea sobre el uso de conjuntos de datos para su modelo : (en realidad también me he enamorado de esto). Los conjuntos de datos parecen una forma perfectamente válida de moverse por los datos del modelo en una aplicación. El problema viene con la forma en que identifica los elementos de datos. Debido a que sus datos se almacenan en filas y columnas, debe realizar búsquedas por nombre de columna o índice, así como tener que filtrar por una fila en particular. Estos bits de lógica significan tener que usar cadenas mágicas y números en la lógica de cableado en su aplicación. El uso de un conjunto de datos tipeados aliviaría parte de este problema, pero no del todo. Al utilizar conjuntos de datos tipeados, se estaría alejando de MVVM y hacia un acoplamiento más ajustado entre la interfaz de usuario y la fuente de datos.


Le ayuda a separar la GUI y la lógica del programa; mezclarlos puede resultar en aplicaciones muy difíciles de mantener, especialmente cuando su proyecto crece con el tiempo.


Lea la introducción a MVVM en este artículo

En 2005, John Gossman, actualmente uno de los arquitectos de WPF y Silverlight en Microsoft, dio a conocer el patrón Model-View-ViewModel (MVVM) en su blog. MVVM es idéntico al modelo de presentación de Fowler, ya que ambos patrones presentan una abstracción de una vista, que contiene el estado y el comportamiento de una vista. Fowler presentó Presentation Model como un medio para crear una abstracción independiente de la plataforma de UI de una Vista, mientras que Gossman introdujo MVVM como una forma estandarizada de aprovechar las funciones principales de WPF para simplificar la creación de interfaces de usuario. En ese sentido, considero que MVVM es una especialización del patrón PM más general, hecho a medida para las plataformas WPF y Silverlight.

..

A diferencia del Presentador en MVP, un ViewModel no necesita una referencia a una vista. La vista se vincula a las propiedades en un ViewModel, que, a su vez, expone los datos contenidos en los objetos del modelo y otros estados específicos de la vista. Los enlaces entre View y ViewModel son simples de construir porque un objeto ViewModel se establece como el DataContext de una vista. Si los valores de propiedad en ViewModel cambian, esos nuevos valores se propagan automáticamente a la vista a través del enlace de datos. Cuando el usuario hace clic en un botón en la Vista, se ejecuta un comando en ViewModel para realizar la acción solicitada. ViewModel, nunca View, realiza todas las modificaciones realizadas en los datos del modelo. Las clases de vista no tienen idea de que las clases de modelo existen, mientras que ViewModel y el modelo no son conscientes de la vista. De hecho, el modelo es completamente ajeno al hecho de que el ViewModel y la vista existen. Este es un diseño muy débilmente acoplado, que paga dividendos de muchas maneras, como verá pronto.

También el artículo explica por qué usar estos patrones de GUI:

Es innecesario y contraproducente usar patrones de diseño en un simple "¡Hola mundo!" programa. Cualquier desarrollador competente puede entender algunas líneas de código de un vistazo. Sin embargo, a medida que aumenta el número de funciones en un programa, la cantidad de líneas de código y partes móviles aumenta en consecuencia. Eventualmente, la complejidad de un sistema y los problemas recurrentes que contiene, alientan a los desarrolladores a organizar su código de tal forma que sea más fácil de comprender, discutir, extender y solucionar. Disminuimos el caos cognitivo de un sistema complejo aplicando nombres bien conocidos a ciertas entidades en el código fuente. Determinamos el nombre para aplicar a un fragmento de código al considerar su función en el sistema.

Los desarrolladores a menudo estructuran intencionalmente su código de acuerdo con un patrón de diseño, en lugar de dejar que los patrones surjan orgánicamente. No hay nada de malo en ninguno de los enfoques, pero en este artículo, examino los beneficios de usar explícitamente MVVM como la arquitectura de una aplicación WPF. Los nombres de ciertas clases incluyen términos conocidos del patrón MVVM, como por ejemplo terminar con "ViewModel" si la clase es una abstracción de una vista. Este enfoque ayuda a evitar el caos cognitivo mencionado anteriormente. En cambio, puedes existir felizmente en un estado de caos controlado, que es el estado natural de los asuntos en la mayoría de los proyectos de desarrollo de software profesional.


MVVM es realmente un código excesivo.

Entonces, ¿qué beneficios ofrece el MVVM?

Es solo separación de preocupaciones, no más. También podría escribir la lógica de ViewModel en el controlador. ViewModel es simplemente responsable de realizar una conversión (por ejemplo, y objeto en una cadena). Al usar MVVM, utiliza un estilo de programación orientado a objetos. Al escribir la lógica de conversión en el controlador, utiliza un estilo de programación más funcional.

Entonces, todo se reduce a tener más código con una mejor legibilidad o menos código con los grandes archivos del Controlador. En conclusión, no puede decir que tiene que usar MVVM, porque es mejor que MVC, es solo una preferencia personal.

Para que quede claro por qué menciono un controlador: MVVM también tiene un código de controlador en alguna parte. No tengo idea de por qué hay un amplio consenso para dejar la C.


Serás feliz a largo plazo si utilizas un patrón como MVVM por todos los motivos que otros publicaron. Recuerde que no necesita seguir los requisitos del patrón palabra por palabra, solo asegúrese de tener una buena separación entre su ventana (Ver) y su lógica (código subyacente).


Todavía estoy lidiando con el patrón yo mismo, pero creo que es valioso. El mayor desafío en este momento es que el enfoque todavía es bastante nuevo y, por lo tanto, hay mucha confusión y ciertos componentes clave del patrón aún son difíciles de implementar. Descubrí algunas cosas que me han ayudado mucho a hacer implementaciones más limpias del patrón:

  1. Utilizo mucho el RelayCommand de la Fundación MVVM de Josh Smith. Esto hace que el enlace de View a ViewModel a través de Commands sea mucho más limpio.

  2. Uso AOP para aliviar el dolor de implementar INotifyPropertyChanged. Actualmente estoy usando Postsharp, aunque creo que hay otras herramientas que pueden hacer esto. Si no hubiera descubierto esto, probablemente ya me habría dado por vencido, ya que el código repetitivo para implementarlo manualmente me estaba molestando.

  3. He tenido que invertir mi enfoque sobre cómo se implementa el software. En lugar de tener una clase de dictadores que les diga a todos sus secuaces qué hacer, que a su vez usan a sus secuaces, mi software se convierte más en una cuestión de servicios débilmente acoplados que dicen:

    • Esto es lo que sé cómo hacer

    • Estas son las cosas que necesito haber hecho

Cuando comienzas a estructurar tu código de esta manera y utilizas herramientas que facilitan el cableado de las dependencias (hay una amplia gama de frameworks IoC para elegir), he encontrado que alivia algo de la incomodidad de MVVM, como puede reducir el código repetitivo asociado con la inyección de los Modelos en los Modelos de Vista y ubicar varios Servicios de Visualización (como mostrar diálogos de archivos) para que sus Modelos de Vista consuman.

Es una gran inversión aprender este enfoque diferente y, como con cualquier cambio importante en la implementación, la productividad es mucho menor cuando comienza a usarla. Sin embargo, estoy empezando a ver algo de luz al final del túnel y creo que, una vez que domine los detalles desordenados, mis aplicaciones serán más limpias y mucho más fáciles de mantener.

Para abordar la pregunta sobre INotifyPropertyChanged a través de Postsharp, uso un aspecto basado en el ejemplo here . Lo he personalizado un poco para mi uso, pero eso te da la esencia. Con esto, solo etiqueto la clase [NotifyPropertyChanged] y todas las propiedades públicas tendrán el patrón implementado en sus setters (incluso si son auto setters de propiedad). Me parece mucho más limpio, ya que no tengo que preocuparme si quiero tomar el tiempo para que la clase implemente INotifyPropertyChanged. Solo puedo agregar el atributo y terminarlo.


  • Es más fácil trabajar con diseñadores (no programadores, solo personas que usan Blend)
  • El código es comprobable (pruebas unitarias)
  • Es mucho más fácil cambiar la vista sin jugar con el resto del código
  • Mientras desarrolla la interfaz de usuario, puede simular el modelo y desarrollar su interfaz sin ejecutar un servicio real (simplemente utilizando datos simulados del modelo). Luego solo volteas bandera y te conectas al servicio.