Escolar Documentos
Profissional Documentos
Cultura Documentos
Login
HOME
NOTCIAS
ARTIGOS
FRUM
BUSCA
BUSCAR
Registrese
ENVIARNOTCIA
CONTRIBUIR
Curtir
2,9mil
131
SIGA
@JAVAFREE
Home>Artigos>EngenhariadeSoftware>
ApresentandoModelViewPresenter,oMVCfocadonavisualizao
PublicadoporTutoriaisAdminem04/10/2012209.339visualizaes
comentrios:1
DanielFernandesMartins
dfmwork@gmail.com
Neste artigo sero abordados os aspectos principais do padro MVP, ou ModelViewPresenter. Sero explicados quais problemas motivaram a criao desse
padro,comoeleresolvetaisproblemase,principalmente,osasvantagensedesvantagensdeseusaroMVP.Parademonstraressesconceitosdeformaprtica,
nsdesenvolveremosumaaplicaodeexemploutilizandoSwing.
OmodelodeprogramaoMVPoquepodemoschamardeumaderivaodomodeloMVC,quesurgiucomoSmalltalk.NoSmalltalk,oscomponentesvisuais,
comoascaixasdetextoebotes,soregidosportrsabstraescentrais:Model,VieweController.
Model:Soinformaesqueindicamoestadodocomponente,como,porexemplo,otextodeumTextFieldouaindicaoonoffdeumCheckBox
View:AcessaosdadosdoModeleespecificacomoosdadosdoModelsomostradosaousurio,como,porexemplo,umtextodentrodeumTextBoxouum&#
61692indicandoqueumCheckBoxestmarcado
Controller:ComponenteparamapearasaesdousurionaView(asquaisocorremnormalmenteatravsdeeventos)efazemcomqueoModelsejamodificado.
Paracitarumexemplo,quandoumCheckBox?marcado?recebeumeventodeclick,oControllermapeiaessaaodousurioemodificaoModel,indicandoque
este agora est desmarcado. O Model, por sua vez, notifica a View, indicando mudana em seu estado. A View recebe a notificao e renderiza o CheckBox
desmarcadonatela.
AFigura1ilustraainteraoentreoModel,aVieweoController:
Figura1?ModeloMVC
Estemodelodeprogramaofuncionamuitobemnocontextodecomponentesindividuais,comoexplicadoanteriormente.Porm,duranteodesenvolvimento,
necessrioagruparvriosdessescomponentessobcontextosespecficosque,juntos,representamodomniodoproblemaasersolucionadopelosistema.
Imagineumajanelaquesirvaparacadastrarclientesnosistema.agrupadoumconjuntodediversostiposdecontrolesvisuais(View)querepresentamumalista
deobjetosClientenosistema(Model).Oresultadodainteraodousuriocomajanelatraduzidoemeventos(Controller),quecontrolamofluxodaaplicaoe
modificamoestadodoscontrolesdajanela,atualizandotambmosobjetosdenegcio.
Namaioriadoscasos,ocdigoresponsvelpelotratamentodoseventosecontroledefluxodaJanelaficadentrodeumamesmaclasse.Temosentoumaquebra
de camadas: a View no deve conhecer nem o modelo que representa e nem a lgica de apresentao, j que temos alguns tipos de ao na lgica de
apresentao que so regidas pelo domnio do problema em questo. Outro problema de manter tanto o cdigo de montagem da tela quanto o tratamento de
eventosumaclasseextremamentegrande,difcildemanter,difcildeexpandirecomcdigodeimpossvelreutilizao.
aqueentraoMVP!
Motivaes do MVP
AdiferenaentreoMVCeoMVPficabasicamentenoconceito,jqueasfunesdo?C?(Controller)doMVCsosemelhantesao?P?(Presenter)doMVP.
Imaginenovamenteoexemplodocadastrodeclientes.OModelacoleodeobjetosClientequesomanipuladospelajanela.AViewajanelapropriamente
dita.OPresenterresponsvelporinterceptaroseventosgeradosnaView,comafinalidadedecontrolaralgicadeapresentao.
Portanto, foco principal do MVP separar a lgica de apresentao da apresentao em si. Com isso, conseguimos alternar entre diferentes apresentaes
facilmente, atravs da reutilizao da lgica de apresentao. Alm disso, conseguimos realizar testes na classe responsvel pela lgica de apresentao sem
precisarutilizaraViewparaisso.Ganhamostambmnoquesitomanuteno,jqueasresponsabilidadesforamdivididasemmaisclassesespecializadasefceis
deentender.
MVP na Prtica
Jqueo?corao?doMVPaseparaodalgicadeapresentaodaapresentaoemsi,temoscomoresultadoumaViewquenocontmmuitocdigoalm
necessrioparaorganizaroscomponentesnatela.Issopareceserocaminhomaiscorreto,poisafunodaViewdevesersomenteoferecerumaformadeo
usuriointeragircomosistema.NoteaquiumasemelhanacomopadroMVCclssico.
Considereoseguintediagramadeclasses:
Figura2?Estruturadeclassesdoexemplo,seguindooMVP.
Paracriaranossaaplicaodeexemplo,utilizaremoscomobaseodiagramadeclassesmostradonaFigura2.
TodasasViewscapazesdecadastrarclientesdevemimplementarainterfaceCadastroClienteView.Essainterfacedefinemtodosget()eset()paraconfiguraros
valoresdoscomponentes,habilitar/desabilitarentradadedadosnoscomponentesvisuaisequaisqueroutrasoperaesquesejamnecessrias.Essasoperaes
soutilizadaspeloPresenter,quenocasoaclasseCadastroClientePresenter.ComomostradonaFigura2,aclasseCadastroClientePresenterseregistracomo
observadordoseventosdisparadosnaView,eostrata.
ParailustrarmelhorainteraoentreasclassesdefinidasnaFigura2,considereoseguintediagramadeseqncia:
Figura3?Procedimentodeinserodeumnovoclientenosistema
Note que o diagrama est dividido em trs partes. A primeira parte mostra como ocorre a instanciao da janela de cadastro de clientes: um objeto
presenterInstanceobtmoobjetowindowInstanceatravsdecriaoexplcita(comooperadornew)ouinjetadoviaIoC.Emseguida,oobjetopresenterInstance
inicializaoModel,quenocasocompostoporumacoleodeobjetosCliente.Finalmente,oobjetopresenterInstanceexibeajanela.(Parte1)
Ajanelaficaaguardandoousurioinserirumnovocliente.Quandoousurioclicanoboto?Inserir?,oobjetopresenterInstanceexecutaocdigoresponsvelpor
liberar os campos para que o usurio digite os dados do novo cliente, atravs de chamadas aos mtodos definidos na interface CadastroClienteView, que
implementadapeloobjetowindowInstance.(Parte2)
Paraconfirmarocadastro,ousuriopressionaoboto?Confirmar?.Emseguida,oobjetopresenterInstancecriaumanovainstnciadaclasseClienteepreenche
seusatributos,deacordocomosvaloresdigitadosnajanela.Depois,oPresenteradicionaesseclientenalistadeclientescadastradoseatualizaaView.(Parte3)
Paraaplicarosconceitosvistosataqui,vamoscriarumaaplicaodeexemploutilizandoopatternMVP.
Aplicativo de Demonstrao
Asimagensabaixodemonstramonossoaplicativoemfuncionamento:
Figura4?Janeladecadastrodeclientes
Figura5?Inserindoumnovocliente
Figura6?Novoclientecadastradonosistema
Figura7?Removendoumclientecadastrado
Aaplicaodeexemplobastantesimples,masmostracomoaplicaropatternecomoutilizloparatornarodesenvolvimentodeaplicaesrichclientmenos
traumtico.
Ferramentas utilizadas
Para criao desse exemplo, aconselho a utilizao da IDE NetBeans, devido a grande facilidade de criao de interfaces grficas com Swing. Neste programa
tambmusaremosoframeworkSpringpara?colar?oscomponentesdaaplicaosemquesejanecessrioescrevercdigoparaisso.
Criando o Model
InicieumnovoprojetonoNetBeanscomqualquernome.Emseguida,crieumaclassechamadaCliente,nopacoteorg.javafree.mvp.model.Essaclassesero
nossoModel.
Cliente.java
packageorg.javafree.mvp.model;
publicclassCliente{
privateLongid;
privateStringnome;
privateStringtelefoneResidencial;
privateStringtelefoneComercial;
privateStringtelefoneCelular;
privateStringemail;
publicCliente(){}
publicCliente(Longid,Stringnome,StringtelefoneResidencial,StringtelefoneComercial,StringtelefoneCelular,Stringemail){
setId(id);
setNome(nome);
setTelefoneResidencial(telefoneResidencial);
setTelefoneComercial(telefoneComercial);
setTelefoneCelular(telefoneCelular);
setEmail(email);
}
//MtodosGeteSet
publicObjectclone(){
returnnewCliente(this.id,this.nome,this.telefoneResidencial,this.telefoneComercial,this.telefoneCelular,this.email);
}
publicbooleanequals(Objectobj){
if(objinstanceofCliente){
Clientec=(Cliente)obj;
returnc.getId().equals(id);
}
returnfalse;
}
}
Criando a View
CrieumnovoJFramechamadoCadastroClienteWindow,nopacoteorg.javafree.mvp.gui.cadastro.
Crieumlayoutparecidocomafiguraabaixo:
Figura8?Layoutdaaplicao
EstainterfacecompostaporseteJLabel,seisJTextField,seisJButton,umJScrollPaneeumJTable:
Classe
Objetos
lbClienteId,lbClienteNome,lbClienteTelResidencial,lbClienteTelComercial,lbClienteTelCelular,lbClienteEmail,
JLabel
lbClientesCadastrados
JTextField txtClienteId,txtClienteNome,txtClienteTelResidencial,txtClienteTelComercial,txtClienteTelCelular,txtClienteEmail
JButton
btnInserir,btnRemover,btnAlterar,btnConfirmar,btnCancelar,btnSair
JScrollPane spClientesCadastrados
JTable
tableClientesCadastrados
ParapermitirqueoPresenterinterajacomaViewsemsaberoseutipo,precisamoscriarumainterface,quedeveserimplementadapelanossaView.Assim,ns
noestaremosprendendooPresenteraumanicaView.
Aindanopacoteorg.javafree.mvp.gui.cadastro,crieumaclassechamadaCadastroClienteView.
CadastroClienteView.java
packageorg.javafree.mvp.gui.cadastro;
publicinterfaceCadastroClienteView{
//GetseSetsdosatributosquerepresentamomodel
publicvoidsetId(Longid);
publicLonggetId();
publicvoidsetNome(Stringnome);
publicStringgetNome();
//...
publicvoidpackAndShow();
publicvoidclearFields();
publicintlinhaSelecionadaTableClientes();
publicvoidenableTxtClienteId(booleanarg);
publicvoidenableTxtClienteNome(booleanarg);
//...
publicvoidsetClientesTableModel(ClientesTableModelmodel);
publicClientesTableModelgetClientesTableModel();
publicvoidrefreshTableClientes();
//Mtodosparaconfiguraroslistenersquecompealgicadeapresentao
publicvoidsetInserirActionListener(ActionListenerlistener);
publicvoidsetRemoverActionListener(ActionListenerlistener);
publicvoidsetAlterarActionListener(ActionListenerlistener);
//...
Modifique a classe CadastroClienteWindow, fazendo que ela implemente a interface CadastroClienteView. Adicione o seguinte cdigo na classe
CadastroClienteWindow:
publicclassCadastroClienteWindowimplementsCadastroClienteView{
//...
publicvoidsetId(Longid){
this.txtClienteId.setText(id.toString());
}
publicLonggetId(){
returnnewLong(this.txtClienteId.getText());
}
publicvoidsetNome(Stringnome){
this.txtClienteNome.setText(nome);
}
publicStringgetNome(){
returnthis.txtClienteNome.getText();
}
//...
publicvoidenableTxtClienteId(booleanarg){
this.txtClienteId.setEditable(arg);
}
publicvoidenableTxtClienteNome(booleanarg){
this.txtClienteNome.setEditable(arg);
}
//...
publicintlinhaSelecionadaTableClientes(){
returnthis.tableClientesCadastrados.getSelectedRow();
}
publicvoidpackAndShow(){
this.pack();
this.setVisible(true);
}
publicvoidclearFields(){
Component[]componentes=this.getContentPane().getComponents();
for(inti=0;i<componentes.length;i++){
if(componentes[i]instanceofJTextField){
JTextFieldfield=(JTextField)componentes[i];
field.setText("");
}
}
}
publicvoidsetClientesTableModel(ClientesTableModelmodel){
this.tableClientesCadastrados.setModel(model);
//ConfiguraascolunasdaJTable
TableColumnModelcolumnModel=this.tableClientesCadastrados.getColumnModel();
columnModel.getColumn(0).setHeaderValue("ID");
columnModel.getColumn(0).setPreferredWidth(10);
columnModel.getColumn(1).setHeaderValue("Nome");
columnModel.getColumn(1).setPreferredWidth(200);
columnModel.getColumn(2).setHeaderValue("Email");
columnModel.getColumn(2).setPreferredWidth(200);
}
publicClientesTableModelgetClientesTableModel(){
return(ClientesTableModel)this.tableClientesCadastrados.getModel();
}
publicvoidrefreshTableClientes(){
this.tableClientesCadastrados.updateUI();
}
publicvoidsetInserirActionListener(ActionListenerlistener){
this.btnInserir.addActionListener(listener);
}
publicvoidsetRemoverActionListener(ActionListenerlistener){
this.btnRemover.addActionListener(listener);
}
publicvoidsetAlterarActionListener(ActionListenerlistener){
this.btnAlterar.addActionListener(listener);
}
//...
}
Ainda no pacote org.javafree.mvp.gui.cadastro, crie uma nova classe chamada ClientesTableModel. Esta classe ser necessria para renderizar o JTable com a
listadetodososclientescadastradosnosistema.
ClientesTableModel.java
packageorg.javafree.mvp.gui.cadastro;
publicclassClientesTableModelextendsAbstractTableModel{
privateListclientes;
publicClientesTableModel(Listclientes){
this.clientes=clientes;
}
publicObjectgetValueAt(introwIndex,intcolumnIndex){
Clientecliente=clientes.get(rowIndex);
if(cliente!=null){
switch(columnIndex){
case0:returncliente.getId();
case1:returncliente.getNome();
case2:returncliente.getEmail();
}
}
returnnull;
}
publicintgetRowCount(){
if(clientes!=null){
returnthis.clientes.size();
}
return0;
}
publicintgetColumnCount(){
//Id,Nome,Email
return3;
}
publicClientegetCliente(introw){
if(row>=0){
returnthis.clientes.get(row);
}
returnnull;
}
}
Criando o Presenter
AgoradefiniremosaclassePresenter,queserresponsvelpelalgicadeapresentaodonossoaplicativo.CrieumaclassechamadaCadastroClientePresenter,
nopacoteorg.javafree.mvp.presenter.cadastro.
CadastroClientePresenter.java
packageorg.javafree.mvp.presenter.cadastro;
publicclassCadastroClientePresenter{
privateClientecliente;
privateListmodel;
privateCadastroClienteViewview;
publicvoidcreateView(){
this.novoCliente();
this.setUpViewListeners();
this.habilitarEdicao(false);
//...
view.packAndShow();
}
publicvoidsetUpViewListeners(){
//Implementadoposteriormente
}
publicvoidupdateModelFromView(){
cliente.setId(view.getId());
cliente.setNome(view.getNome());
//...
}
publicvoidupdateModelFromJTable(){
ClientesTableModeltbModel=view.getClientesTableModel();
cliente=tbModel.getCliente(view.linhaSelecionadaTableClientes());
if(cliente!=null){
this.updateViewFromModel();
view.enableBtnAlterar(true);
view.enableBtnRemover(true);
}
else{
view.enableBtnAlterar(false);
view.enableBtnRemover(false);
}
this.updateViewFromModel();
}
publicvoidupdateViewFromModel(){
if(cliente!=null){
view.setId(cliente.getId());
view.setNome(cliente.getNome());
view.setTelefoneResidencial(cliente.getTelefoneResidencial());
view.setTelefoneComercial(cliente.getTelefoneComercial());
view.setTelefoneCelular(cliente.getTelefoneCelular());
view.setEmail(cliente.getEmail());
}
else{
view.clearFields();
}
}
publicvoidnovoCliente(){
cliente=newCliente();
}
publicvoidadicionarCliente(){
this.updateModelFromView();
this.model.add((Cliente)cliente.clone());
view.refreshTableClientes();
}
publicvoidalterarCliente(){
this.updateModelFromView();
view.refreshTableClientes();
}
publicbooleanremoverCliente(){
this.updateModelFromView();
booleanb=this.model.remove(cliente);
view.refreshTableClientes();
returnb;
}
publicvoidhabilitarEdicao(booleanarg){
view.enableTxtClienteId(arg);
view.enableTxtClienteNome(arg);
view.enableTxtClienteTelResidencial(arg);
view.enableTxtClienteTelComercial(arg);
view.enableTxtClienteTelCelular(arg);
view.enableTxtClienteEmail(arg);
}
publicCadastroClienteViewgetView(){
returnview;
}
publicvoidsetView(CadastroClienteViewview){
this.view=(CadastroClienteView)view;
}
publicObjectgetModel(){
returnmodel;
}
publicvoidsetModel(Objectmodel){
if(modelinstanceofList){
this.model=(List)model;
}
}
}
Para definir os eventos disparados pela View, criaremos duas classes no pacote org.javafree.mvp.presenter.cadastro: ClientesWindowActionListeners e
ClientesWindowMouseListener.
A classe ClientesWindowActionListener contm todas as classes necessrias para tratar os eventos de ao na View, enquanto a classe
ClientesWindowMouseListenertrataoseventosdemouse.Segueabaixoocdigodasduasclasses:
ClientesWindowActionListeners.java
packageorg.javafree.mvp.presenter.cadastro;
publicclassClientesWindowActionListeners{
staticclassAlterarActionListenerimplementsActionListener{
privateCadastroClientePresenterpresenter;
publicAlterarActionListener(CadastroClientePresenterpresenter){
this.presenter=presenter;
}
publicvoidactionPerformed(ActionEventevt){
presenter.habilitarEdicao(true);
CadastroClienteViewview=(CadastroClienteView)presenter.getView();
view.enableBtnCancelar(true);
view.enableBtnConfirmar(true);
//...
}
}
staticclassCancelarActionListenerimplementsActionListener{
privateCadastroClientePresenterpresenter;
publicCancelarActionListener(CadastroClientePresenterpresenter){
this.presenter=presenter;
}
publicvoidactionPerformed(ActionEventevt){
CadastroClienteViewview=(CadastroClienteView)presenter.getView();
view.clearFields();
presenter.habilitarEdicao(false);
view.enableBtnCancelar(false);
view.enableBtnConfirmar(false);
//...
}
}
staticclassConfirmarActionListenerimplementsActionListener{
privateCadastroClientePresenterpresenter;
publicConfirmarActionListener(CadastroClientePresenterpresenter){
this.presenter=presenter;
}
publicvoidactionPerformed(ActionEventevt){
presenter.habilitarEdicao(false);
CadastroClienteViewview=(CadastroClienteView)presenter.getView();
view.enableBtnCancelar(false);
view.enableBtnConfirmar(false);
//...
}
}
staticclassInserirActionListenerimplementsActionListener{
privateCadastroClientePresenterpresenter;
publicInserirActionListener(CadastroClientePresenterpresenter){
this.presenter=presenter;
}
publicvoidactionPerformed(ActionEventevt){
presenter.novoCliente();
CadastroClienteViewview=(CadastroClienteView)presenter.getView();
presenter.habilitarEdicao(true);
view.clearFields();
view.enableBtnAlterar(false);
view.enableBtnCancelar(true);
//...
}
}
staticclassRemoverActionListenerimplementsActionListener{
privateCadastroClientePresenterpresenter;
publicRemoverActionListener(CadastroClientePresenterpresenter){
this.presenter=presenter;
}
publicvoidactionPerformed(ActionEventevt){
if(JOptionPane.showConfirmDialog((Component)presenter.getView(),"Desejaremover?","Pergunta",JOptionPane.YES_NO_OPTION,JOptionPane.QUES
CadastroClienteViewview=(CadastroClienteView)presenter.getView();
presenter.removerCliente();
view.clearFields();
view.enableBtnAlterar(false);
view.enableBtnRemover(false);
}
}
}
staticclassSairActionListenerimplementsActionListener{
publicvoidactionPerformed(ActionEventevt){
System.exit(0);
}
}
}
ClientesWindowMouseListener.java
packageorg.javafree.mvp.presenter.cadastro;
publicclassClientesWindowMouseListener{
staticclassTableClientesMouseListenerextendsMouseAdapter{
privateCadastroClientePresenterpresenter;
publicTableClientesMouseListener(CadastroClientePresenterpresenter){
this.presenter=presenter;
}
publicvoidmouseClicked(MouseEvente){
presenter.updateModelFromJTable();
CadastroClienteViewview=(CadastroClienteView)presenter.getView();
view.enableBtnCancelar(false);
view.enableBtnConfirmar(false);
view.enableBtnInserir(true);
}
}
}
A criao da camada de lgica de apresentao est quase concluda. Agora que temos as classes que tratam os eventos da View, vamos voltar classe
CadastroClientePresentereimplementaromtodosetUpViewListeners()comomostradoabaixo:
publicvoidsetUpViewListeners(){
view.setInserirActionListener(newInserirActionListener(this));
view.setRemoverActionListener(newRemoverActionListener(this));
view.setAlterarActionListener(newAlterarActionListener(this));
view.setCancelarActionListener(newCancelarActionListener(this));
view.setConfirmarActionListener(newConfirmarActionListener(this));
view.setBtnSairActionListener(newSairActionListener());
view.setTableClientesMouseListener(newTableClientesMouseListener(this));
}
ParaconcluiroPresenter,nsprecisamosdefinirofluxodeoperaesdonossoaplicativo.Vejaaimagem
Figura9?FluxodoscomandosdeIncluireAlterarclientes
Comomostradonaimagem,aoperaodeconfirmao(quefeitaemumnicolocal),devesaberseousurioestinserindoumclientenosistemaouseest
modificandoumclientejcadastrado.
Paraevitartestesdotipo
if(operacao==inserir){
//Faaumacoisa
}
elseif(operao==alterar){
//Faaoutracoisa
}
elseif(etc...)
vamosimplementarestafuncionalidadeutilizandoopadroStrategy.Assim,quandoousuriopressionarobotoInserir,a?estratgia?executadapeloboto
Confirmarinseriroclientenosistema.Damesmaforma,seousuriodecidiralterarumcliente,aestratgiadobotoConfirmarseralterarosdadosdocliente.
Paraconseguiresseefeito,vamoscriarumainterfacechamadaStrategy,dentrodopacoteorg.javafree.mvp.presenter.cadastro.
Strategy.java
packageorg.javafree.mvp.presenter.cadastro;
publicinterfaceStrategy{
publicvoidexecute();
}
VolteclasseCadastroClientePresentereinsira,nofinaldocdigodaclasse,oseguintecdigo:
privateclassInsertStrategyimplementsStrategy{
publicvoidexecute(){
adicionarCliente();
}
}
privateclassUpdateStrategyimplementsStrategy{
publicvoidexecute(){
alterarCliente();
}
}
Agora,vamoscriardoisobjetosquerepresentamessasoperaes.Estesdoisobjetosdevemestarvisveisparaasclassestratadorasdeeventos,permitindoa
definiodofluxodaaplicao.
//Constantesdeindicaodeoperao,paracontrolaroqueoboto'confirmar'faz
publicfinalStrategyINSERT_STRATEGY=newInsertStrategy();
publicfinalStrategyUPDATE_STRATEGY=newUpdateStrategy();
privateStrategyoperacao=INSERT_STRATEGY;
//...
publicvoidsetOperacao(Strategyoperacao){
this.operacao=operacao;
}
publicStrategygetOperacao(){
returnoperacao;
}
EstamosquaseterminandoonossoPresenter.AbranovamenteaclasseClientesWindowActionListenersemodifiqueocdigo,comomostradonotrechoabaixo:
//?
staticclassAlterarActionListenerimplementsActionListener{
//...
publicvoidactionPerformed(ActionEventevt){
presenter.setOperacao(presenter.UPDATE_STRATEGY);
//...
}
}
//...
staticclassConfirmarActionListenerimplementsActionListener{
//...
publicvoidactionPerformed(ActionEventevt){
presenter.getOperacao().execute();
//...
}
}
//...
staticclassInserirActionListenerimplementsActionListener{
//...
publicvoidactionPerformed(ActionEventevt){
presenter.setOperacao(presenter.INSERT_STRATEGY);
//...
}
}
Juntando as partes
A nossa aplicao est praticamente finalizada. S resta agora criar o arquivo de configurao do Spring. Crie um arquivo chamado applicationContext.xml no
CLASSPATHdaaplicao.Configureseucontedoparaalistagemexibidaabaixo:
<?xmlversion="1.0"encoding="UTF8"?>
<!DOCTYPEbeansPUBLIC"//SPRING//DTDBEAN//EN"
"http://www.springframework.org/dtd/springbeans.dtd">
<beans>
<!Modeldaaplicao,quecontmumacoleodeClientes>
<beanid="model"class="java.util.ArrayList"singleton="true"/>
<!Classequeencapsulaalgicadeapresentao>
<beanid="presenter"class="org.javafree.mvp.presenter.cadastro.CadastroClientePresenter"singleton="false">
<propertyname="view">
<reflocal="view"/>
</property>
<propertyname="model">
<reflocal="model"/>
</property>
</bean>
<!Classeresponsvelporrenderizarosdadosgraficamente>
<beanid="view"class="org.javafree.mvp.gui.cadastro.CadastroClienteWindow"singleton="false">
<propertyname="clientesTableModel">
<reflocal="clientesTableModel"/>
</property>
</bean>
<!ModeloquemostradadosdeumalistadeclientesemumcomponenteJTable>
<beanid="clientesTableModel"class="org.javafree.mvp.gui.cadastro.ClientesTableModel"singleton="false">
<constructorarg>
<reflocal="model"/>
</constructorarg>
</bean>
</beans>
Parafinalizaracriaodonossoaplicativo,crieaclasseMain,nopacoteorg.javafree.mvp.application.
Main.java
packageorg.javafree.mvp.application;
publicclassMain{
publicstaticvoidmain(String[]args){
getPresenter().createView();
}
publicstaticCadastroClientePresentergetPresenter(){
BeanFactoryfactory=newClassPathXmlApplicationContext("./applicationContext.xml");
return(CadastroClientePresenter)factory.getBean("presenter");
}
}
Aaplicaoestfinalizada.Snoseesqueadeadicionarosarquivosspring.jarecommonslogging.jarnasLibrariesdoprojeto.
Concluso
Seformoscompararduasaplicaes,umadelasseguindoopadroMVPeoutrano,inevitvelacomparaoentreocdigoescrito:aaplicaoqueutilizao
MVPtemmaislinhasdecdigoemaisclassesdoqueaplicaoquenoutilizaoMVP.Euparticularmentenoconsideroissoumadesvantagem,poisjustamentea
quebra do cdigo em vrias classes torna a aplicao mais fcil de entender e de expandir, alm de permitir maior reutilizao e melhorar a testabilidade do
cdigo.
Referncias
MartinFowlerhttp://www.martinfowler.com/eaaDev/ModelViewPresenter.html
IBM?sTaligentftp://www6.software.ibm.com/software/developer/library/mvp.pdf
MVChttp://en.wikipedia.org/wiki/Modelviewcontroller
MVCMeetsSwinghttp://www.javaworld.com/javaworld/jw041998/jw04howto.html
Links
NetBeanshttp://www.netbeans.org
SpringFrameworkhttp://www.springframework.org
comentrios:1
TpicosRelacionados
[Resolvido]PassarvalorSpringMVC>funoJavascript?
UncaughtError:java.lang.reflect.InvocationTargetException
AjudacomPadroMVC
TeladeLoginnosistema
ImagemnoabrenapaginaJSP[RESOLVIDO]
DUVIDASCOM2COMBOBOXRELACIONADAS[]
Parametros[]
[Youtube]CanalVarallos
Erro:Onomedacolunaendereconaovalido
Dvidassobreimplementaoumnovoprojeto(MVC/MVPououtrasigla)
Dvidaemumcdigo.Precisandodeajuda!
ProblemaemsetarcamposformatadosemJava
NoCosigoresolveresteExercciojavasounovonarea.
TDDintroduo
ForumJavaFreecommensagensdesucessotodaszuadas
DvidaJavaBeans+JSP
ImagemnocarreganoJSP(ComSpring)[RESOLVIDO]
Jtablenocarrega[RESOLVIDO]
Problema:ButtonSomaButton=(Button)this.findViewById(R.id.SomaButton)
Grficonoaparece(jsf+primefaces)
PadrodeProjeto
ProblemacomSplashScreen
RSSNotcias
RSSFrum