Sobre o padrão MVVM

34 views
Skip to first unread message

Paulo Quicoli

unread,
Jan 20, 2009, 8:59:08 AM1/20/09
to infra...@googlegroups.com

Neste link vcs verão uma grande introdução a esse design pattern:

http://channel9.msdn.com/shows/Continuum/MVVM/

--
Paulo R. Quicoli

Editor Técnico - ClubeDelphi Magazine - DevMedia

Magno Machado

unread,
Jan 21, 2009, 5:51:36 PM1/21/09
to Infra - Integrated Frameworks
Pelo que eu entendi, nesse pattern a view é mais complexa do que no
passive view, já que o mvvm elimina o controller e joga as suas
responsabilidades para a view.
Estou correto?
Se for isso mesmo, não seria algo ruim?

Quicoli

unread,
Jan 22, 2009, 4:57:33 AM1/22/09
to Infra - Integrated Frameworks
O ViewModel prepara o Model para ser visto pela View, expondo
propriedades e commands.
A View se conecta no ViewModel e o exibe. As propriedades são
atachadas na view através do mecanismo de binding do WPF.
Na view podemos ter algum código sim, desde que seja código relativo à
apresentação.

>>á que o mvvm elimina o controller e joga as suas
>> responsabilidades para a view.

Que responsabilidades são essas ?

Abraço


Não vejo como algo ruim. Tenho utilizado esse padrão em aplicativos
WPF.

mrbar2000

unread,
Jan 27, 2009, 7:40:52 PM1/27/09
to Infra - Integrated Frameworks
Pessoal vou colocar aqui uma conversa que tive com paulo sobre a parte
de binding pelo msn

Infra {Paulão}, 19/1/2009 13:28:58:
eu vi que estão planejando um mecanismo de binding. estou envolvido
com WPF, e no WPF o mecanismo de binding é muito, mas

muito superior ao que existe no windowsforms... e que seria uma boa
idéia ver o que tem de bom lá.

mrbar2000 *unicef, 13:30:17:
Nào conhecemos muito de wpf. vi que trabalha com xml

Infra {Paulão}, 13:30:39:
mas nao pra binding
xaml é apenas pra definiçao da interface....
por traz disso tem todo o framework .net...
o interessante é entender como o Binding deles funcionam e ver o que é
bom e melhorar

mrbar2000 *unicef, 13:32:10:
ok. vi aqui que o mvvm usa ioc e uma otima documentação sobre ele
neste blog:
http://blog.lab49.com/archives/2650

Infra {Paulão}, 13:57:01:
a ideia geral é o seguinte: temos: Model que são nossas entidades,
serviços, etc... Temos a View, que a interface

propriamente dita... e entre eles, temo o ViewModel. Qual o papel
desse cara

mrbar2000 *unicef, 14:00:15:
bem, pelo que parece o viewmodel é como um passiveview ou um mediator

Infra {Paulão}, 14:00:39:
isso... ele adapta o model para ser exibido na view
e a view se conecta nas propriedades do viewmodel através do mechanism
de binding

mrbar2000 *unicef, 14:03:35:
achei este documento
http://www.nikhilk.net/Silverlight-ViewModel-Pattern.aspx

Infra {Paulão}, 14:03:47:
sobre as açoes que a view pode tomar, por exemplo ao clicar em um
botão "Salvar", essas ações, são comandos do sistema de

RoutedCommanding do WPF... que é show de bola tbém... algo como o
TAction, mas turbinado

mrbar2000 *unicef, 14:04:18:
agora veja bem, o cara tem de implementar cada viewmodel

Infra {Paulão}, 14:05:22:
sim... mas isso é rapido cara... não dá trabalho... tenho um sistema
utiilzando isso.... pra aplicar testes unitários é

facinho facinho...

mrbar2000 *unicef, 14:06:47:
então na verdade a proposta nao é montar um framework o cara monta 1
contjunto de vm para cada tela dele seria isso?

Infra {Paulão}, 14:07:54:
sim. Separando realmente a apresentação da lógica... e tal modo que vc
consegue rodar a aplicação executando apenas o

viewmodel....

mrbar2000 *unicef, 14:08:22:
eu entendo, mas e quanto a eventos?
por exemplo o desenho no canvas de um grid dependendo da informação
que está sendo apresentada
teria de capturar o drawcolumncell da vida. que se for um listview
seria outro evento

Infra {Paulão}, 14:09:36:
aí vc está misturando as bolas... como apresentar os dados, é problema
da view, e nao do viewmodel no MVVM

mrbar2000 *unicef, 14:11:01:
então um form delphi por exemplo teria codigo

Infra {Paulão}, 14:11:02:
o ViewModel disponibiliza para a View umas espécies de comandos, que
são atachados em botoes
desde que o código seja pra tratar a apresentação dos dados, por
codigo no form não é problema. o problema é misturar as

camadas

mrbar2000 *unicef, 14:12:24:
dificil é os programadores perceberem até onde vai logica de
apresentação e apresentação
pq veja bem, se eu por acaso tenho de pintar uma linha do grid em
vermelho caso o valor de um campo seja abaixo de zero por

exemplo, eu acho que isso é lógica de apresentação

Infra {Paulão}, 14:12:46:
é uma questão de costume e hábito
a pintura do grid fica na camada de apresentação

mrbar2000 *unicef, 14:13:42:
então o que sobra para a logica da apresentacao? actions? chamada de
outros forms, etc....

Infra {Paulão}, 14:14:46:
validação, ações, estado dos objetos... e a view deve apenas saber
como reagir a isso
cara... agora que consegui abrir o site pra vc
http://mschnlnine.vo.llnwd.net/d1/ch9/5/7/8/3/5/4/TCSMVVM_ch9.wmv
cara, se conseguirmos fazer um mecanismo de binding similar ao do
WPF... estaremos no céu!

mrbar2000 *unicef, 14:17:47:
bem estava pensando em definir comentários usando o anotation do
infra. e a partir disso o trem tratar a coisa
eu vi um framework chamado G que ele faz isso pegando os comentarios e
jogando em um scanner usando expressao regular
mas eles jogam a coisa diretamente no objeto de negocio. ai já nao sei
se é uma boa

Infra {Paulão}, 14:20:19:
comentários pra que ? pra registrar o binding ?

mrbar2000 *unicef, 14:20:43:
sim. estava pensando em por exemplo em cima de uma propriedade do
viewmodel colocar
// @Binding.....
pq no wpf, vc tem o xaml

Infra {Paulão}, 14:21:33:
hummmm
acho que nao
o viewmodel deve expor as propriedades apenas...
nao precisa ser em xaml

mrbar2000 *unicef, 14:22:13:
e define o binding lá né isso?

Infra {Paulão}, 14:24:09:
a obrigação do viewmodel é adaptar o model para ser exibido, ponto. A
view, de "posse" do viewmodel é que é responsavel em

saber como exibir os dados. Portando por meio de um mecanismo de
binding registramos onde as propriedades do viewmodel serão

exibidas. E esse registro é feito na View.
Algo assim:

BindingMechanism.AddBinding(Edit1,'Text','ViewModel.Nome');

mrbar2000 *unicef, 14:26:31:
já imaginou uma tela cheia de controles paulo?

Infra {Paulão}, 14:26:55:
o cara vai fazer isso uma unica vez e outra coisa...
no mecanismo de binding existe um cara chamado Converter... com ele é
possivel por exemplo fazer o bind de uma propriedade

boolean para uma propriedade TColor.
aí teriamos:

BindingMechanism.AddBinding
(Edit1,'Color','ViewModel.Estado',ClasseQueImplementaIConverter );

mrbar2000 *unicef, 14:29:24:
sim eu vi este lance do converter

Infra {Paulão}, 14:32:14:
eu acho cara, que poderiamos até criar uma série de componentes que
facilitassem o binding... herdados mesmo dos componentes

básicos.... que implementassem algumas interfaces definidas por
nós... dessa forma, posteriormente o usuario final poderia

implementar essas nossas interfaces de binding em seus componentes de
terceiros

Infra {Paulão}, 14:32:27:
poderiamos criar os BindableControls. o trampo seria menor

mrbar2000 *unicef, 14:32:41:
pois é, isso é que acho chato
ficar criando vários componentes implementando interface
talvez criar classes views seja melhor
uma classe view que conhece a vcl por exemplo
estas sim implementariam a interface e apontariam para o componente
dela

Infra {Paulão}, 14:34:01:
mas esses bindable controls iriam permitir que qualquer propriedade do
controle fosse ligada a alguma propriedade do

viewmodel

mrbar2000 *unicef, 14:34:14:
sim, nao tem problema

Infra {Paulão}, 14:34:18:
certo... poderia ser uma especie de wrapper entao

mrbar2000 *unicef, 14:34:32:
poderiamos até fazer algo usando a rtti do delphi mesmo, na classe
base
o importante seria chegar no create do form ou em algum lugar, e
definir o bind do componente para uma view predefinida

Infra {Paulão}, 14:36:10:
então... voltamos ao ponto anterior.. de alguma forma teremos que
registrar, codificar isso, controle por controle...

mrbar2000 *unicef, 14:37:19:
talvez um componente, que ao ser colocado no form, clique com o
diretiro e ai abra um grid com a lista de componentes do form
e então lá vc escreve a propriedade, nome do converter, binding,
etc....
na verdade já poderia até apontar para a view padrão para aquele
controle
e ai o cara poderia escolher um outro que esteja registrado

Infra {Paulão}, 14:37:53:
interessante isso

mrbar2000 *unicef, 14:38:33:
mas é claro, acho que independente desta tela
BindMechanism tem de existir

Infra {Paulão}, 14:38:54:
sim, essa tela é apenas um "editor de binding"

mrbar2000 *unicef, 14:39:09:
só que definindo de alguma forma a view a ser usada

Infra {Paulão}, 14:40:57:
ao utilizar o "editor de binding" na View, automaticamente ele poderia
detectar a view, atraves de alguma propriedade

"parent"... e já, internamente, direcionar

mrbar2000 *unicef, 14:41:39:
é

mrbar2000 *unicef, 14:41:48:
assim, nao ficaria codigo algum no form
e o bindind seria feito da mesma forma

Infra {Paulão}, 14:42:27:
novamente digo... não é problema ter código na view, desde que seja
código "de exibição" :)

mrbar2000 *unicef, 14:42:35:
se bem que tem este caso de colorir grid e outros, mas para isso
poderia se definir classes render
e tambem amarrar no bind como se faz com o converter

Infra {Paulão}, 14:43:02:
pára com isso. nao complique as coisas...

mrbar2000 *unicef, 14:43:55:
é que eu penso paulo em que precisamos de algo que possa gerar algo
tanto para form quanto para web usando flex por exemplo
e se nao tiver estes recursos, o cara vai ter de escrever actionscript
ou javascript

Infra {Paulão}, 14:44:19:
o mecanismo de binding... independe disso

mrbar2000 *unicef, 14:44:36:
entendi

Infra {Paulão}, 14:45:17:
vamos por parte... um passo de cada vez... a primeira coisa é criar o
mecanismo de binding, permitindo inicialmente o

registro por código...
depois, acrescentamos os esquemas de IConverter
depois, podemos criar o "editor de binding" :)

mrbar2000 *unicef, 14:46:18:
este mvvm parece muito com o passive view

Infra {Paulão}, 14:46:31:
não sei nada sobre o esse passive view

mrbar2000 *unicef, 14:49:32:
viewmodel conhece a tela paulo, algum componente por exemplo?

Infra {Paulão}, 14:49:43:
nao
mas tem um detalhe

mrbar2000 *unicef, 14:50:15:
então por exemplo o que acontece se a mudança de um valor no viewmodel
deveria causar a mudanca de outra coisa na view?
por exemplo. ao colocar o valor de um campo em negativo, deveria
aparecer outro campo em vermelho
eu vi algo ontem sobre isso mas nao entendi como funciona direito

Infra {Paulão}, 14:52:28:
ah... era isso que eu ia explicar agora
o viewmodel deve implementar uma interface chamada
INotifyPropertyChanged

mrbar2000 *unicef, 14:53:06:
vi isso

Infra {Paulão}, 14:53:14:
isso torna o viewmodel capaz de notificar a view e vice-versa

Infra {Paulão}, 14:53:48:
através do mecanismo de binding é claro

mrbar2000 *unicef, 14:54:05:
tem algum parametro ou ele vai repassar por todo o binding?
ou seja, fazer um refresh geral?

Infra {Paulão}, 14:54:31:
nao... vc passa o nome da propriedade no set
por exemplo tenho uma classe base que chama BindableObject e nela
tenho o seguinte método:

protected virtual void RaisePropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
// Get the cached event args.
PropertyChangedEventArgs args =
GetPropertyChangedEventArgs(propertyName);

// Raise the PropertyChanged event.
handler(this, args);
}
this.AfterPropertyChanged(propertyName);
}

e as minhas classes de negocio herdam desse BindableObject e nelas
implemento assim:

public virtual string Name
{
get { return _name; }
set
{
_name = value;
base.RaisePropertyChanged("Name");
}
}

mrbar2000 *unicef, 14:58:46:
entendi, isso so no que vc precisar notificar e nao em cada setter

Infra {Paulão}, 14:59:29:
se propriedade vai ser exposta. em alguma view, coloco isso no set

mrbar2000 *unicef, 15:00:15:
os infratypes por exemplo já notificam mudança nas propriedades

mrbar2000 *unicef, 26/1/2009 12:53:32:
p. vi um video sobre o mvvm melhor que daqueles 2 caras falando
praticamente eles nao mostraram nada
e pelo que vi o lance é o esquema de binding 2way
tendo isso temos 90%

Infra {Paulão}, 12:53:57:
isso

mrbar2000 *unicef, 12:54:23:
temos que falar com o magno sobre isso
acredito que devemos trabalhar em cima do binding primeiro
por que com o binding até se nao tiver um framework mv..... a coisa já
vai ajudar

Infra {Paulão}, 12:55:07:
isso mesmo!!

mrbar2000 *unicef, 12:56:44:
como vc acha que devemos registrar o binding?

Infra {Paulão}, 12:57:12:
seria: bindingmanager.add...
no .net, os controles já possuem uma instancia desse bindingmanager.
No nosso caso, seria um objeto a parte. entao acredito

que seria assim:

Add( controle, propriedade_do_controle, propriedade_do_datacontext,
[modo do binding], [objeto que implementar IConverter])

mrbar2000 *unicef, 13:00:42:
estava pensando em juntar controle e propriedade em uma string
'Edit1.Text'
'Label1.Color'
etc,
e buscar isso por rtti
Problema vai ser implementar um 2way neste caso.

Infra {Paulão}, 13:00:51:
em wpf, todo objeto tem uma propriedade "dataContext" que é o objeto
de onde eles vão extrair os dados
pode até ser, porque esse registro vai ficar na view mesmo
o modo do binding é se ele é oneway, twoway, default

José Henrique

unread,
Mar 23, 2009, 11:01:33 AM3/23/09
to Infra - Integrated Frameworks
Olá me desculpem antes de mais nada se o que vou falar é besteira, ou
se a implementação utilizada no caso que vou descrever não é a melhor,
mas ficou funcional.

Já utilizei o FrameWork do DePO e abaixo da classe
TDepoPersistentObject foi criada a classe TDepoMyPersistentObject,
essa classe possuía dois métodos de comunicação com a interface:

ObjectToControls - pegava o form que estava sendo utilizado para
interface e o varria procurando por componentes que estavam ligados ao
objeto. Essa ligação nada mais era que o nome do componente
identificando o objeto e sua propriedade, como por exemplo num form de
cadastro teríamos alguns edits -

TEdit.name := ClienteNome;
TEdit.name := ClienteRg;
TCheckBox.name := ClienteVip;

Existia o trabalho árduo de ao colocar um componente na tela que seria
linkado com um objeto, ter de nomeá-lo corretamente, porém a
implementação ficava muito fácil. Pois criamos modelos de forms
padrões de pequenos cadastros, onde no form create somente definimos
qual era o nome do objeto do cadastro que possuíam propriedades
semelhantes assim podíamos trocar somente a classe do objeto a ser
criado, e uns 80% do form com o cadastro já estava pronto.

e
ControlsToObject: vazia o caminho contrário, varria os componentes e
localizava os objetos instanciados que estavam "linkados" aos
controles.

Gostaria que a crítica fosse feita sobre a solução acima, pois não
entendi direito esse conceito do "mecanismo de binding".

Estou numa empresa agora que deseja fortemente utilizar FW para
persistência e possivelmente para MVC então aceito qualquer crítica
pois irá me ajudar na tomada final de decisão.

Obrigado!!




_____________________________
José Henrique Pereira Nascimento
josehen...@gmail.com
(11) 6621-0366
(12) 8812-1012
Conheça o Aqua Data Studio
acesse: http://www.aquafold.com
> achei este documentohttp://www.nikhilk.net/Silverlight-ViewModel-Pattern.aspx
> cara... agora que consegui abrir o site pra vchttp://mschnlnine.vo.llnwd.net/d1/ch9/5/7/8/3/5/4/TCSMVVM_ch9.wmv
> Infra {Paulão}, 14:53:14: ...
>
> mais »

mrbar2000

unread,
Mar 23, 2009, 12:24:58 PM3/23/09
to Infra - Integrated Frameworks
> ObjectToControls - pegava o form que estava sendo utilizado para
> interface e o varria procurando por componentes que estavam ligados ao
> objeto. Essa ligação nada mais era que o nome do componente
> identificando o objeto e sua propriedade, como por exemplo num form de
> cadastro teríamos alguns edits -
> TEdit.name :=  ClienteNome;
> TEdit.name :=  ClienteRg;
> TCheckBox.name := ClienteVip;

Desvantagens desta abordagem:

- Vc tem de escrever mais código;
- Vc tem de nomear cada componente de seu form com nomes dos atributos
do objeto
- Não há suporte para controles complexos: grids, treeviews, etc...
- Vc tem de ficar chamando ObjectToControls e ControlsToObject quando
precisa
permutar dados e isso pode ser ruim pq vc pode ter mudando apenas 1
atributo apenas.
- A implementação não é de forma alguma mais simples a do Binding do
Infra.

> Gostaria que a crítica fosse feita sobre a solução acima, pois não
> entendi direito esse conceito do "mecanismo de binding".

Fizemos 2 pequenos exemplos:
http://code.google.com/p/infra/source/browse/#svn/branches/persistence/demos/Binding/ControlToControl
http://code.google.com/p/infra/source/browse/#svn/branches/persistence/demos/Binding/TypeToControl

Estes demos mostram como é simples fazer o binding no Infra, mais
tarde o binding será feito de forma RAd usando um expert no delphi ou
algum componente nao visual.

No InfraBinding, vc nao precisa ficar chamando método algum. mudou o
controle vcl, dependendo do controle já atualiza automáticamente o
objeto quando tirar o foco do controle, outros como checkbox, é
imediato. mudou o controle já muda o objeto
Outra vantagem do InfraBinding é vc poder amarrar controles a
controles e não só controles a objetos.

Dá uma olhadinha nos exemplo que vc vai ver o que é facilidade de
uso :D
Reply all
Reply to author
Forward
0 new messages