Em seu livro 'Arquitetura limpa', o tio Bob diz que o apresentador deve colocar os dados que recebe em algo que ele chama de 'modelo de exibição'.
É o mesmo que o 'ViewModel' do padrão de design Model-View-ViewModel (MVVM) ou é um simples Data Transfer Object (DTO)?
Se é não um simples DTO, como ele se relaciona com a View? A visualização obtém atualizações através de um relacionamento de Observador?
Meu palpite é que é mais parecido com o ViewModel do MVVM, porque no capítulo 23 de seu livro, Robert Martin diz:
O trabalho [do apresentador] é aceitar dados do aplicativo e formatá-los para apresentação, para que o View possa simplesmente movê-los para a tela. Por exemplo, se o aplicativo desejar exibir uma data em um campo, ele entregará ao apresentador um objeto Data. O Presenter formatará esses dados em uma sequência apropriada e os colocará em uma estrutura de dados simples chamada modelo View, onde a View pode encontrá-los.
Isso implica que o View esteja de alguma forma conectado ao ViewModel, em vez de simplesmente recebê-lo como um argumento de função, por exemplo (como seria o caso de um DTO).
Outro motivo pelo qual acho que isso ocorre porque, se você olhar para a imagem, o Presenter usa o View Model, mas não o View. Considerando que os usos do apresentador tanto a saída limite e a saída de dados DTO.
Se não é um DTO nem o ViewModel do MVVM, por favor, descreva o que é.
fonte
ViewModel
é wrapper paraController
,Presenter
eViewModel
em arquitetura limpa do tio Bob.Controller
->ICommand
ePresenter
->data-binding mechanism
.Respostas:
Não.
Isso seria o seguinte :
Isso tem ciclos. O tio Bob tem evitado cuidadosamente os ciclos .
Em vez disso, você tem o seguinte:
O que certamente não tem ciclos. Mas está deixando você se perguntando como a exibição sabe sobre uma atualização. Chegaremos a isso em um momento.
Para citar Bob da página anterior:
Então, claro, se você quiser.
Mas eu suspeito fortemente o que realmente está incomodando você é o seguinte :
Esse pequeno abuso da UML contrasta a direção da dependência do código-fonte com a direção do fluxo de controle. É aqui que a resposta para sua pergunta pode ser encontrada.
Em um relacionamento de uso:
o fluxo de controle segue na mesma direção que a dependência do código fonte.
Em um relacionamento de implementação:
o fluxo de controle normalmente segue na direção oposta à da dependência do código-fonte.
O que significa que você está realmente olhando para isso:
Você deve conseguir ver que o fluxo de controle nunca vai passar do Apresentador para a Visualização.
Como pode ser? O que isso significa?
Isso significa que a visualização possui seu próprio encadeamento (o que não é incomum) ou (como o @Euphoric aponta) o fluxo de controle está entrando na visualização de algo mais não descrito aqui.
Se for o mesmo thread, o View saberá quando o View-Model está pronto para ser lido. Mas, se esse for o caso, e a visualização for uma GUI, será difícil repintar a tela quando o usuário a mover enquanto espera pelo banco de dados.
Se a visualização tiver seu próprio encadeamento, ele terá seu próprio fluxo de controle. Isso significa que, para implementar isso, o View precisará pesquisar o View-Model para observar as alterações.
Como o apresentador não sabe que a exibição existe e a exibição não sabe que o apresentador existe, eles não podem se ligar. Eles não podem arremessar eventos um para o outro. Tudo o que pode acontecer é que o Presenter gravará no View-Model e o View lerá o View-Model. Sempre que lhe apetecer.
De acordo com este diagrama, a única coisa que o View e o Presenter compartilham é o conhecimento do View-Model. E é apenas uma estrutura de dados. Portanto, não espere que ele tenha algum comportamento.
Isso pode parecer impossível, mas pode funcionar mesmo que o View-Model seja complexo. Um pequeno campo atualizado é tudo o que a visualização teria que pesquisar para detectar uma alteração.
Agora, é claro, você pode insistir em usar o padrão de observador ou ter alguma coisa estruturada para esconder esse problema, mas entenda que não precisa.
Aqui está um pouco de diversão que ilustrei o fluxo de controle:
Observe que sempre que você vê o fluxo indo contra as direções definidas anteriormente, o que você vê é uma chamada retornando. Esse truque não nos ajudará a chegar ao ponto de vista. Bem, a menos que voltemos ao que chamamos de Controller. Ou você pode simplesmente mudar o design para poder acessar a visualização. Isso também corrige o que parece ser o início de um problema de ioiô com o Data Access e sua interface.
A única outra coisa a aprender aqui, além disso, é que o Use Case Interactor pode praticamente chamar as coisas na ordem que quiser, desde que o último seja o apresentador.
fonte
Acho esse problema muito confuso e levaria muito texto e tempo para explicar adequadamente o problema, pois acredito que você não entendeu bem a arquitetura limpa de Martin e a MVVM.
A primeira coisa a observar é que o diagrama que você postou está incompleto. Ele mostra apenas "lógica de negócios", mas está faltando algum tipo de "orquestrador" que realmente faz as peças se moverem na ordem certa.
O código do orquestrador seria tão simples quanto
Acredito ter ouvido Martin falar sobre isso em uma de suas palestras sobre Arquitetura Limpa.
Outra coisa a salientar é que a observação de candied_orange sobre falta de ciclos está errada. Sim, o ciclo não existe (e não deveria) na arquitetura do código. Mas os ciclos entre instâncias de tempo de execução são comuns e geralmente levam a um design mais simples.
Esse é o caso no MVVM. No MVVM, o View depende do ViewModel, e o ViewModel usa eventos para notificar o View sobre suas alterações. Isso significa que, no design das classes, há apenas dependência das classes View e Model, mas durante o tempo de execução, há dependência cíclica entre as instâncias View e ViewModel. Por esse motivo, não há necessidade de orquestrador, pois o ViewModel fornecerá ao View uma maneira de descobrir quando se atualizar. É por isso que as "notificações" neste diagrama usam a linha "ondulada" e não a linha direta. Isso significa que o View observa alterações no ViewModel, não que o ViewModel dependa do View.
A coisa mais importante que você deve tirar da arquitetura limpa de Martin não é o design em si, mas como você lida com as dependências. Um dos pontos críticos que ele faz em suas palestras é que, quando há um limite, todas as dependências de código que cruzam esse limite o atravessam em uma única direção. No diagrama, esse limite é representado por linha dupla. E há muita inversão de dependência por meio de interfaces (
InputBoundary
,OutputBoundary
eDataAccessInterface
) que corrigem a direção da dependência do código.Em contraste, a
ViewModel
arquitetura limpa é simplesmente um DTO simples, sem lógica. Isso é óbvio por<DS>
tag. E é por isso queorchestrator
é necessário, poisView
não saberá quando executar sua lógica.Se eu "achatasse" o diagrama em como ele será durante o tempo de execução, ele será assim:
Portanto, durante o tempo de execução, as dependências estão na direção "errada", mas tudo bem.
Eu recomendo assistir sua palestra sobre Arquitetura Limpa para entender melhor seu raciocínio.
fonte