Per rispondere alla domanda, Sì, ogni vista dovrebbe avere il proprio modello di vista. Ma non è necessario modellare l'intera gerarchia. Solo ciò di cui ha bisogno la vista.
Il problema che ho riscontrato con la maggior parte delle risorse online riguardanti MVVM:
Nella maggior parte degli esempi, la vista è una mappatura quasi 1 a 1 del modello. Ma nel mio scenario, in cui ci sono viste diverse per diverse sfaccettature dello stesso Modello, mi trovo bloccato tra due scelte:
Un modello di vista monolitico utilizzato da tutti gli altri modelli di vista
O un modello di vista per ogni vista
Ma entrambi non sono l'ideale.
Il modello di visualizzazione orientato al modello (MVM), sebbene a basso livello di duplicazione del codice, è un incubo da mantenere
Il modello di vista orientato alla vista (VVM) produce classi altamente specializzate per ogni vista, ma contiene duplicati.
Alla fine, ho deciso che avere una VM per View è più facile da gestire e codificare, quindi ho scelto l'approccio VVM.
Una volta che il codice funziona, ho iniziato a refactoring tutte le proprietà e le operazioni comuni nella sua forma attuale e finale:
In questa forma finale, la classe del modello di vista comune è composta in ogni VVM.
Certo, devo ancora decidere cosa è considerato comune / specializzato. E quando una vista viene aggiunta / unita / eliminata, questo equilibrio cambia.
Ma la cosa bella di questo è che ora sono in grado di spingere su / giù i membri dal comune a VVM e viceversa facilmente.
E una breve nota relativa alla sincronizzazione degli oggetti:
Avere un modello di vista comune si occupa della maggior parte di questo. Ogni VVM può semplicemente avere un riferimento allo stesso modello di visualizzazione comune.
Tendo anche a iniziare con semplici metodi di callback, evolvendo in evento / osservatore se dovesse sorgere la necessità di più ascoltatori.
E per eventi davvero complessi (ad es. Aggiornamenti inaspettati a cascata), passerei all'utilizzo di un mediatore.
Non esito dal codice in cui un bambino ha un riferimento posteriore al suo genitore. Qualsiasi cosa per far funzionare il codice.
E se si presentasse l'opportunità di refactoring, la prenderei.
Le lezioni che ho imparato:
- Codice brutto / funzionante> Codice bello / non funzionante
- È più facile unire più classi piccole piuttosto che suddividere una classe enorme