Ajuda com MVVM complexo (várias visualizações)

18

Preciso de ajuda para criar modelos de exibição para o seguinte cenário:

  1. Dados hierárquicos profundos
  2. Várias visualizações para o mesmo conjunto de dados
  3. Cada visualização é uma visualização única, de mudança dinâmica, com base na seleção ativa
  4. Dependendo do valor de uma propriedade, exiba diferentes tipos de guias em um controle de guia

insira a descrição da imagem aqui

Minhas perguntas:

Devo criar uma representação do modelo de exibição para cada exibição (VM1, VM2, etc)?

1. Yes:
    a. Should I model the entire hierarchical relationship? (ie, SubVM1, HouseVM1, RoomVM1)
    b. How do I keep all hierarchies in sync? (e.g, adding/removing nodes)

2. No:
    a. Do I use a huge, single view model that caters for all views?

Aqui está um exemplo de uma única visualização

Figura 1: Várias visualizações atualizadas com base na sala ativa. Controle da guia Aviso

insira a descrição da imagem aqui

Figura 2: Sala ativa diferente. Várias visualizações atualizadas. Os itens de controle da guia foram alterados com base na propriedade do objeto.

insira a descrição da imagem aqui

Figura 3: Tipo de seleção diferente. Alterações na visualização inteira

insira a descrição da imagem aqui

jayars
fonte
entre o que é uma exibição muli? erro de digitação?
JensG
"Muli view" foi um erro de digitação. Eu quis dizer visões diferentes para o mesmo modelo / modelo de exibição. Minha pergunta era: devo remodelar / agrupar toda a hierarquia do modelo para cada visualização, para que cada modelo contenha apenas o que a visualização individual precisa? Ou devo criar uma hierarquia de modelo de exibição única que contenha propriedades de todas as exibições? Desde que publiquei essa pergunta, tive (in) sorte de descobrir os prós / contras dos dois, da maneira mais difícil. Atualizarei esse tópico no futuro com um diagnóstico completo da minha experiência, uma vez que as coisas não são tão agitadas.
Jayars
Lembre-se de que uma regra de design é mostrar as coisas gerais primeiro e depois entrar em detalhes. isso deixará você com uma visão clara e, se o usuário se aprofundar, novas visualizações aparecerão. portanto, use pequenas visualizações com seu modelo de exibição separado. verifique este artigo design interface do usuário
Csharls
@jsjslim Estremeci quando li "manter todas as hierarquias sincronizadas". Suspeito que você tenha optado pela visualização múltipla e suspeito de ter se arrependido (mas eu já estive errado antes). Pelo bem de outros leitores que possam ter a mesma pergunta, você pode pelo menos nos dar uma resposta rápida (ish)?
Guy Schalnat
2
@ guy-schalnat A exibição múltipla era um requisito. Meu problema foi tentar descobrir como criar os modelos de exibição. O projeto ainda está em andamento e não encontro tempo para redigir uma análise completa. Mas, em resumo: eu deveria ter ignorado a estrutura do modelo e focado nas visualizações. A complexidade que encontrei foi auto-imposta: eu queria tanto usar a ligação de dados do WPF que me fixei. O que fiz no final foi bom, antigo "copiar / colar / refatorar". O design final que emergiu foi leve (pouca repetição) e, mais importante, funcionou. Irá escrever uma análise completa no futuro.
jayars

Respostas:

13

Para responder à pergunta, Sim, cada visualização deve ter seu próprio modelo de visualização. Mas não há necessidade de modelar toda a hierarquia. Somente o que a vista precisa.

O problema que tive com a maioria dos recursos online relacionados ao MVVM:

Na maioria dos exemplos, a Visualização é quase um mapeamento 1 para 1 do Modelo. Mas, no meu cenário, onde existem diferentes visões para diferentes facetas do mesmo modelo, eu me vejo preso entre duas opções:

Um modelo de vista monolítico usado por todos os outros modelos de vista

insira a descrição da imagem aqui

Ou um modelo de vista para cada vista

insira a descrição da imagem aqui

Mas ambos não são ideais.

O MVM (Model-oriented View Model), embora com pouca duplicação de código, é um pesadelo para manter

O Modelo de Visão Orientada à Visão (VVM) produz classes altamente especializadas para cada visão, mas contém duplicatas.

No final, eu decidi que ter uma VM por exibição é mais fácil de manter e codificar, então fui com a abordagem VVM.

Depois que o código está funcionando, comecei a refatorar todas as propriedades e operações comuns em sua forma final atual:

insira a descrição da imagem aqui

Nesta forma final, a classe de modelo de vista comum é composta em cada VVM.

Claro, ainda tenho que decidir o que é considerado comum / especializado. E quando uma visualização é adicionada / mesclada / excluída, esse saldo é alterado.

Mas o bom disso é que agora eu sou capaz de enviar membros para cima / baixo do comum para o VVM e vice-versa facilmente.

E uma observação rápida sobre como manter os objetos sincronizados:

Ter um modelo de visão comum cuida da maior parte disso. Cada VVM pode simplesmente ter uma referência ao mesmo modelo de visualização comum.

Também costumo começar com métodos simples de retorno de chamada e evoluir para evento / observador, se houver necessidade de vários ouvintes.

E para eventos realmente complexos (ou seja, atualizações em cascata inesperadas), eu passaria a usar um Mediador.

Não evito o código em que uma criança tem uma referência anterior ao pai. Qualquer coisa para obter o código funcionando.

E se surgir a oportunidade de refatorar, eu aceitaria.

As lições que aprendi:

  1. Código feio / funcional> Código bonito / não funcional
  2. É mais fácil mesclar várias classes pequenas do que dividir uma classe enorme
jayars
fonte
Eu gostaria de poder votar isso duas vezes. Essa é uma das explicações mais claras das opções que eu já vi.
Clever Human
3

Analisando suas maquetes, eu recomendaria definitivamente a criação de hierarquia de ViewModels e muitas pequenas Views. E você provavelmente terá que modelar um pouco da hierarquia original.

Para manter as coisas sincronizadas entre os ViewModels, use eventos ou tenha propriedades entre si entre os ViewModels. A sincronização entre modos de exibição e modelos de exibição deve ser propriedades de notificação padrão.

Eufórico
fonte