Tag Archives: Model 3

Extjs e DWR

Nesse artigo eu pretendo trabalhar dois conceitos principais de uso do Extjs, extensão/customização de componentes e acesso a dados server-side com base em experiência recente em um projeto que desenvolvemos. Esse projeto em questão é um ERP que tinha a necessidade de manter a usabilidade similar a sua versão antiga, feita em Delphi, para o desktop.

Para suprir essa necessidade de usabilidade tivemos que adotar alguns conceitos, como ser totalmente stateless e modificar a arquitetura MVC2 para o MVC3. No server-side trabalhamos com um domain model baseado em Hibernate, Spring e Facades e Services com DWR. Nada de frameworks MVC2, não nos preocupamos com renderização e sim com a API. No lado cliente usamos Extjs com algumas modificações que fiz para integrar de forma suave com o DWR.

Primeiro precisamos entender como o Extjs trabalha com herança. Basicamente há um método no objeto Ext que faz esse trabalho de extensão dos componentes, funciona da seguinte maneira:

//Formato:
var NovoComponente = Ext.extend(velhoComponente, { 
          /* metodos e propriedades que serão reescritas */ 
});

//Exemplo:
var MilfontGridPanel = Ext.extend(Ext.grid.GridPanel, {
        //novo construtor
        constructor: function(config) {
            // Seu preprocessamento vai aqui
        	MilfontGridPanel.superclass.constructor.apply(this, arguments);
            // Seu pos-processamento vai aqui
        },

        NovoMethod: function() {
            // algum novo método que você queira criar para o novo componente
        }
    });

Para esse projeto, criei um Ext.data.DataProxy (como visto no artigo passado) especialista para o DWR, criativamente denominado DWRProxy. A idéia é modificar o comportamento de buscar os dados para usar um Creator do DWR.

Definimos primeiro o objeto e suas propriedades necessárias:

Ext.ux.data.DWRProxy = function(dwr_facade, dwr_filter, dwr_errorHandler){

    Ext.ux.data.DWRProxy.superclass.constructor.call(this);

	/* Propriedade que receberá a classe Java configurada como Creator */
    this.data = dwr_facade;
    /*
	 * Propriedade que receberá uma classe java configurada como converter
	 * que servirá como filtro de busca
	 */

	this.dwr_filter = dwr_filter;

	/**
	 *
	 * Propriedade para fazer paginação, indica que deve cachear a consulta de
	 * total de elementos o controlador [fachada] deve implementar a logica de
	 * negocios adequada, quando for false consulta o total, quando for true
	 * consulta apenas a listagem e repete o total
	 */

	this.dwr_total_cache = false;

	this.dwr_errorHandler = dwr_errorHandler;

};

Após isso extendemos do Ext.data.DataProxy :

Ext.extend(Ext.ux.data.DWRProxy, Ext.data.DataProxy, {

    /**
     * Método Load do Ext.data.DataProxy overrided
     */

    load : function(params, reader, callback, scope, arg) {

	/**
	 * Escopo "this" mapeado para a variável "s" porque dentro do callback do
	 * DWR o escopo "this" não pertence ao objeto Ext.ux.data.DWRProxy.
	 */

	var s = this;

        params = params || {};

        if(params.cache != undefined) {
		this.dwr_total_cache = params.cache;
	}

	if(params.filter != undefined) {
		this.dwr_filter = params.filter;
	}

        var result;

        try {
		this.data(this.dwr_filter, params.start, params.limit, this.dwr_total_cache, {
			callback:function(response) {
                                //aqui passamos o retorno do DWR 
                               // que chamei de response,  para o extjs
				result = reader.readRecords(response);
				callback.call(scope, result, arg, true);
			},
			errorHandler:function(a, e) {
				scope.fireEvent("loadexception", s, arg, null, e);
				s.dwr_errorHandler(a);
			},
			timeout:100000
		});

		this.dwr_total_cache = true;

        } catch(e) {
            this.fireEvent("loadexception", this, arg, null, e);
            callback.call(scope, null, arg, false);
            return;
        }

    }

});

A fachada DWR é uma classe comum, segue um exemplo de uso com Hibernate:

//classe para satisfazer o transporte para o Extjs
public final class DataTransferObject {
    private int total;
    private List results;
    //sets e gets
}

public class AjaxFacade {
    //injeta um repositorio, whatever
    private Repository repository = null;

    public DataTransferObject find(Object filter, int start, int limit, boolean cache, HttpSession session) {
        DataTransferObject dto = new DataTransferObject();
        //verifica se o Proxy está passando true 
        // indicando que está paginando
        if (cache) {
            Integer total = (Integer) session.getAttribute("totalObject");
            dto.setTotal(total);
       } else {
            session.removeAttribute("totalObject");
            Integer total = repository.count(filter);
            dto.setTotal(total);
            session.setAttribute("totalObject", total);
        }
        List retorno = (List) repository.find(filter, start, limit);
        dto.setResults(retorno);
        return dto;
    }


Para o Grid visto no artigo passado, basta instanciar assim no javscript:

var store = new Ext.data.Store({
    proxy: new Ext.ux.data.DWRProxy(
        AjaxFacade.find, 
        {$dwrClassName:"Project"}, 
        errorHandler
    ),
    reader: new Ext.data.JsonReader({
            root: 'results',totalProperty: 'total',id: 'id'
        }, 
        ['id', 'name', 'manager.name', 'manager.address.country']
    )
});

Para entender o {$dwrClassName:”Project”} visite esse post.

Dessa forma o DWR se torna um proxy para todos os componentes do Extjs.

Código fonte da modificação do javascript eu coloquei aqui no github e uma aplicação demo aqui. No próximo vou integrar o DWR com o Rails, aguardem que sai logo… ou não.

Typically chemist’s shop can sale to you with discreet treatments for various soundness problems. There are numerous of safe online pharmacies that will deliver medications to your address. There are divers medicines for each afflictions. Learn more about “viagra manufacturer coupon“. Maybe “viagra discount coupons” is a highly complicated question. Matters, like “coupons for viagra“, are connected numerous types of health problems. If you need to take recipe medications, ask your pharmacist to check your testosterone levels before. Sometimes the treatment options may include erectile malfunction remedies or a suction device that helps get an erection. Keep in mind web-site which is ready to sell erectile dysfunction drugs like Viagra without a prescription is fraudulent. When you purchase from an unknown web-site, you run the risk of getting counterfeit remedies.

MVC Model 3 e camadas

Recebo muitos emails com dúvidas sobre as camadas no que denominei de Model 3 no artigo da revista Java Magazine, edição 54. Esse Post é para esclarecer alguns pontos que ficaram obscuros no artigo.

Fiz um resumo da história do padrão MVC com base nesse artigo do Brian McCallister, e cometi o pecado inenarrável de misturar camadas e MVC na mesma descrição sem especificar claramente a diferença de um para o outro e separar na explicação onde entrava cada um dos conceitos na evolução até chegar no Model 3.

Não vou dar desculpas e a única coisa em minha defesa é que foi o primeiro artigo que, diga-se de passagem, passou por 8 revisões até chegar ao nível que a revista queria, tive que limar bastante e deixar a explicação fácil para iniciantes. Limei bastante, cortei muito e deixei uma parte confusa. Erro crucial que pago até hoje, porque muita gente entra em contato para entender melhor o que eu “quis” dizer.

MVC e Camadas

Sendo sucinto, deixando logo claro que MVC não tem a ver com camadas, são dois conceitos que se “completam” e se misturam frequentemente dependendo da situação. Tem uma excelente explicação sobre isso nesse artigo do Phillip “Shoes” Calçado. No Model 3 eu uso duas camadas físicas na implementação desse conceito, vamos a explicação.

O que é o Model 3

O Model 3 é conhecido nas listas de discussões de tecnologias WEB 2 como Model 2 + 1, alguém que não lembro propôs esse termo para o que estamos fazendo. Apelidei de Model 3 [2+1, criatividade heim!, sou foda nisso] para dizer que fui eu que criei o termo e fazer fama e sucesso, mas é mentira, isso já existe bastante tempo, inclusive não trouxe nenhuma tecnologia nova, apenas como organizar as coisas.

Significa que os Frameworks Model 2 são ajaxificados com Frameworks Javascript ou integrados com tecnologias RIA como XUL e Flex onde parte da responsabilidade de controle e toda a visão é transferida para o lado cliente, ou seja, a camada de apresentação [layer] inteira foge do lado servidor para a camada física [tier] cliente.

Onde entra as camadas e o MVC?

Observe na figura 1 que todo o processamento da camada de apresentação de uma aplicação usando um Framework Model 2 é realizado no lado servidor, em uma mesma camada física. No lado cliente só existe a exibição de uma página renderizada no formato HTML.
Model 2
Figura 1. Model 2.

Na figura 2 temos uma proposta de mudança para o processamento do Model 2, transferindo toda a apresentação para o lado cliente, com visão e parte do controle para uma tecnologia especialista nessa camada física.
Model 3
Figura 2. Separação em camadas do Model 3.

Há duas vantagens claras, melhor usabilidade por parte do usuário [quando bem construída a aplicação] e desafogamento do servidor em tarefas desnecessárias, como transformação em HTML.

Como construímos uma aplicação com Model 3?

Bem, uso DWR como cola entre as camadas físicas distintas, ele faz a transferência de entities de forma transparente na aplicação.

Para visão eu uso o ExtJS que assume toda a renderização na UI e, integrado ao DWR, coordena o controle da aplicação com uma usabilidade melhor do que a forma tradicional.

No lado servidor o Model segue Hibernate + Spring de forma tradicional usando o DWR como fachada entre o domínio e o controle com POJOS apenas.

Tanto na minha palestra quanto na do Handerson no último CCT, vi que muitos presentes não conhecem o DWR e pior, continuam usando Struts para desenvolvimento de novas aplicações. Nos próximos posts vou abordar mais profundamente esse aspecto do desenvolvimento WEB.

Typically chemist’s shop can sale to you with discreet treatments for various soundness problems. There are numerous of safe online pharmacies that will deliver medications to your address. There are divers medicines for each afflictions. Learn more about “viagra manufacturer coupon“. Maybe “viagra discount coupons” is a so complicated matter. Matters, like “coupons for viagra“, are coupled numerous types of health problems. If you need to take formula medications, ask your dispenser to check your testosterone levels before. Sometimes the treatment options may include erectile disfunction remedies or a suction device that helps get an erection. Keep in mind web-site which is ready to sell erectile dysfunction drugs like Viagra without a prescription is fraudulent. When you purchase from an unknown web-site, you run the risk of getting counterfeit remedies.