Pido disculpas por la larga pregunta, se lee un poco como una queja, ¡pero prometo que no lo es! He resumido mis preguntas a continuación
En el mundo MVC, las cosas son sencillas. El Modelo tiene estado, la Vista muestra el Modelo y el Controlador hace cosas con / con el Modelo (básicamente), un controlador no tiene estado. Para hacer cosas, el controlador tiene algunas dependencias en los servicios web, el repositorio, el lote. Cuando crea una instancia de un controlador, le importa suministrar esas dependencias, nada más. Cuando ejecuta una acción (método en el Controlador), usa esas dependencias para recuperar o actualizar el Modelo o llamar a algún otro servicio de dominio. Si hay algún contexto, digamos que si algún usuario quiere ver los detalles de un elemento en particular, pasa el Id de ese elemento como parámetro a la Acción. En ninguna parte del controlador hay alguna referencia a ningún estado. Hasta aquí todo bien.
Ingrese MVVM. Me encanta WPF, me encanta el enlace de datos. Me encantan los marcos que hacen que el enlace de datos a ViewModels sea aún más fácil (usando Caliburn Micro atm). Sin embargo, siento que las cosas son menos sencillas en este mundo. Vamos a hacer de nuevo el ejercicio: el modelo ha estado, la vista muestra el ViewModel, y el modelo de vista hace cosas para / con el Modelo (básicamente), un modelo de vista hace que el estado! (para aclarar, tal vez delega todas las propiedades a uno o más modelos, pero eso significa que deben tener una referencia al modelo de un modo u otro, que es el estado en sí mismo) Para hacerEl ViewModel tiene algunas dependencias en los servicios web, el repositorio, el lote. Cuando crea una instancia de un ViewModel, le importa suministrar esas dependencias, pero también el estado. Y esto, damas y caballeros, me molesta sin fin.
Siempre que necesite crear una instancia ProductDetailsViewModel
de ProductSearchViewModel
(de la cual llamó a la ProductSearchWebService
que a su vez regresó IEnumerable<ProductDTO>
, ¿todos siguen conmigo?), Puede hacer una de estas cosas:
- llame
new ProductDetailsViewModel(productDTO, _shoppingCartWebService /* dependcy */);
, esto es malo, imagine 3 dependencias más, esto significa que tambiénProductSearchViewModel
necesita asumir esas dependencias. También cambiar el constructor es doloroso. - llame
_myInjectedProductDetailsViewModelFactory.Create().Initialize(productDTO);
, la fábrica es solo un Func, son generados fácilmente por la mayoría de los marcos de IoC. Creo que esto es malo porque los métodos Init son una abstracción permeable. Tampoco puede usar la palabra clave de solo lectura para los campos que se establecen en el método Init. Estoy seguro de que hay algunas razones más. - llame
_myInjectedProductDetailsViewModelAbstractFactory.Create(productDTO);
Entonces ... este es el patrón (fábrica abstracta) que generalmente se recomienda para este tipo de problema. Pensé que era genial, ya que satisface mis ansias de escritura estática, hasta que realmente comencé a usarlo. La cantidad de código repetitivo es demasiado (creo, aparte de los ridículos nombres de variables que uso). Por cada ViewModel que necesite parámetros de tiempo de ejecución, obtendrá dos archivos adicionales (interfaz de fábrica e implementación), y deberá escribir las dependencias que no sean de tiempo de ejecución como 4 veces adicionales. Y cada vez que cambian las dependencias, también puedes cambiarlo en la fábrica. Parece que ya ni siquiera uso un contenedor DI. (Creo que Castle Windsor tiene algún tipo de solución para esto [con sus propios inconvenientes, corrígeme si me equivoco]). - hacer algo con tipos anónimos o diccionario. Me gusta mi escritura estática.
Así que sí. La combinación de estado y comportamiento de esta manera crea un problema que no existe en absoluto en MVC. Y siento que actualmente no hay una solución realmente adecuada para este problema. Ahora me gustaría observar algunas cosas:
- La gente realmente usa MVVM. Entonces, o no les importa todo lo anterior, o tienen alguna otra solución brillante.
- No he encontrado un ejemplo en profundidad de MVVM con WPF. Por ejemplo, el proyecto de muestra NDDD me ayudó inmensamente a comprender algunos conceptos DDD. Realmente me gustaría que alguien pudiera señalarme en la dirección de algo similar para MVVM / WPF.
- Tal vez estoy haciendo MVVM todo mal y debería poner mi diseño al revés. Quizás no debería tener este problema en absoluto. Bueno, sé que otras personas han hecho la misma pregunta, así que creo que no soy el único.
Para resumir
- ¿Estoy en lo cierto al concluir que tener el ViewModel como un punto de integración tanto para el estado como para el comportamiento es la razón de algunas dificultades con el patrón MVVM en su conjunto?
- ¿Usar el patrón de fábrica abstracto es la única / mejor manera de crear una instancia de ViewModel de forma estática?
- ¿Hay algo como una implementación de referencia en profundidad disponible?
- ¿Tener muchos ViewModels con estado / comportamiento es un olor de diseño?