Novo sistema de classes Ext 4.0

Sorry, this entry is only available in Português.

Iniciando uma série de posts sobre o novo Ext 4.0 não poderia começar por nada além do código mais básico do Ext, o sistema de classes. Pela primeira vez na história, a grande refatoração iniciou desde os fundamentos do framework, melhorando 100% o código anterior. As classes estão melhor estruturadas, com uma divisão mais clara entre atributos estáticos, objetos de configuração e métodos. Estão também mais fáceis de desenvolver, testar e executar. E com certeza melhores de manter.

JavaScript é uma linguagem orientada em prototipagem, sem classes. Assim, por natureza, uma das características mais marcantes da linguagem é a flexibilidade. É possível obter um mesmo resultado por diferentes maneiras, em diferentes estilos de codificação e técnicas. Essa característica, entretanto, vêm com o preço da imprevisibilidade. Sem uma estrutura unificada, código Javascript pode ser muito difícil de entender, manter e reutilizar.

Programação baseada em classes, em outro extremo, continua como o modelo mais popular de POO. Linguagens baseadas em classes geralmente requerem forte tipagem, provêm encapsulamento, e possuem padrões e convenções de código. Por geralmente fazer desenvolvedores aderirem a um grande número de princípios, o código escrito tende a ser mais previsível, extensível, e escalável ao longo do tempo. Entretanto, elas não possuem a mesma capacidade dinâmica encontrada em linguagens como Javascript.

Cada abordagem possui seus prós e contras, mas será que podemos ter os prós de ambas ao mesmo tempo, enquanto conciliamos os contras? A resposta é sim, e nós implementamos a solução no Ext JS 4.

- Ext JS Documentation, Class System

Convenção de Código

Para manter um padrão de codificação foram publicadas as convenções de código que devem ser adotadas pelos programadores Ext. Isto não torna o código mais rápido, mas com certeza o torna melhor, mais fácil de dar manutenção e de entender. Vou tentar citar as principais, uma lista completa e detalhada encontra-se no guia Class System.

Classes

Devem conter somente caracteres alfanuméricos, sendo que números devem ser evitados, a menos que pertençam a termo técnico.

Btti.util.Base64 é aceitável

As classes devem ser organizadas em pacotes, mantendo somente 1 nome para o pacote de mais alto nível. Só o pacote de mais alto nível e o nome da classe devem ser CamelCase, o restante é minúsculo

Btti.data.SQLProxy

Btti.Viewport

Acrônimos também devem seguir o padrão CamelCase

Ext.data.JsonProxy ao invés de Ext.data.JSONProxy

MyCompany.util.HtmlParser ao invés de MyCompary.parser.HTMLParser

Arquivos Fonte

O nome das classes mapeiam diretamente para o caminho aonde os arquivos são armazenados, como resultado deve existir somente 1 classe por arquivo. Exemplo:

Ext.util.Observable é armazenado em path/to/src/Ext/util/Observable.js

Btti.pedidos.Listagem é armazenado em path/to/src/Btti/pedidos/Listagem.js

aonde path/to/src é o diretório de classes da sua aplicação. Todas as classes devem estar em um único diretório e devem ser apropriadamente divididas em namespace, para melhor desenvolvimento, manutenção, e facilidades em implantações.

Métodos e Variáveis

Funcionam de forma análoga a classes, porém no padrão camelCase.

encodeUsingMd5()

getHtml() ao invés de getHTML()

var isGoodName

var base64Encoder

var xmlReader

Propriedades

Seguem o mesmo padrão de métodos e variávels, exceto quando é uma propriedade estática de uma classe, que são constantes. Estas são escritas todas em maiúsculo:

Ext.MessageBox.YES = "Yes"

Btti.Viewport.THEME = 'btti-verde'

Estrutura das Classes

A maneira antiga de declarar classes gerava códigos similares a este:

Ext.ns('Btti.grid');

Btti.grid.ListagemBase = Ext.extend(Ext.grid.GridPanel,{
		
	/** @readonly **/
	totalRegistros: 20,
	
	 /** @cfg {Boolean} usaPaginacao Indica se o grid usa ou não paginação */
    usaPaginacao: true,	
		
	initComponent: function()
	{
		if(this.usaPaginacao)
		{
			this.bbar = new Ext.PagingToolbar({
				store: this.store,
				pageSize: this.totalRegistros	
			});
		}
		
		Btti.grid.ListagemBase.superclass.initComponent.call(this);
	}
});
Ext.reg('btti.listagembase', Btti.grid.ListagemBase);

Este código define uma classe Btti.grid.ListagemBase que serve como facilitador na criação de grids com paginação. Basta definir usaPaginacao true ou false, para criar o toolbar. Em complemento existe uma propriedade totalRegistros que é um valor padrão somente-leitura que nenhum desenvolvedor deveria sobreescrever. Apesar de funcionar bem, existem alguns inconvenientes com este modelo

Primeiro, Btti.grid deve existir antes de associarmos ListagemBase a ele. Isso requer que usemos Ext.namespace() (ou o atalho Ext.ns()) para criar o namespace. Ainda, Ext.grid.GridPanel deve existir/estar carregado antes mesmo de iniciar este código. Mas Ext.grid.GridPanel pode ter dependências, e estas dependências possuírem outras dependências, o que nos força a carregar todo o framework em ext-all.js ao invés de somente os códigos que necessitamos. E ainda, não existe uma separação clara entre propriedades da classe que não devem ser manipuladas (como totalRegistros), e configurações do usuário (como usaPaginacao).

No Ext 4 tudo isso é resolvido, e resume-se nisto:

Ext.define('Btti.grid.ListagemBase',{
	
	extend: 'Ext.grid.Panel',
	alias: ['btti.listagembase'],
	
	/** @readonly **/
	totalRegistros: 20,
	
	config:{
		
		/** @cfg {Boolean} usaPaginacao Indica se o grid usa ou não paginação */
    	usaPaginacao: true
    		
	},
	
	initComponent: function()
	{
		if(this.config.usaPaginacao)
		{
			this.dockedItems = this.dockedItems||[]; 
			this.dockedItems.push({
		        xtype: 'pagingtoolbar',
		        dock: 'bottom',
		        itemId: 'paginacao',
		        store: this.store
		   	});
		}
		
		this.callParent();
	},
	
	applyUsaPaginacao: function(usaPaginacao)
	{
		if(usaPaginacao === true)
		{
			this.addDocked({
				xtype: 'pagingtoolbar',
				dock: 'bottom',
           		itemId: 'paginacao',
           		store: this.store,
				pageSize: this.totalRegistros	
			});
		}
		else
		{
			this.removeDocked(this.getDockedComponent('paginacao'));
		}
	}
	
});

O nome da classe, e também de quem ela extende, são strings. Isso evita erros caso o namespace ainda não tenha sido inicializado, ou a classe extendida não tenha sido carregada. O Ext trata de iniciar e carregar tudo, desde que a estrutura proposta nas convenções seja seguida.

Propriedades configuráveis pelo usuário (config options) agora estão reservadas em config. Além de ficar melhor estruturado, o Ext ainda cria automaticamente métodos setUsaPaginacao e getUsaPaginacao. E se algum código precisar ser executado ao alterar o valor da configuração, como no meu exemplo que é adicionar e remover o toolbar de paginação conforme a propriedade muda, pode ser implementado um método apply, como em applyUsaPaginacao

Outros detalhes que possam chamar a atenção:

  • Redundâncias foram eliminadas, como Ext.grid.GridPanel para Ext.grid.Panel, Ext.PagingToolbar para Ext.toolbar.Paging, Ext.tree.TreePanel para Ext.tree.Panel, etc…

  • Toolbars em componentes são considerados dockedItems. Eles podem ser ancorados em qualquer posição (topo, base, esquerda e direita), e podem existir vários, um adjacente ao outro.

  • Invocar o método da classe pai agora é um simples this.callParent(); ao invés de Btti.grid.ListagemBase.superclass.initComponent.call(this);.

Conclusão

Achei essas alterações as melhores da nova versão. Ficou bom demais escrever classes agora, pois tudo fica muito bem estruturado e fácil de manipular. Sem contar na conveniência de ter muito código automatizado pelo Ext.

Também achei ótimo publicar as convenções de desenvolvimento. Tenho certeza que muitos desenvolvedores possuem opiniões diferentes, e talvez contrariem as convenções. Caso vá por este caminho, tenha em mente que muitas facilidades e automatizações possam não estar disponíveis para o seu código, e suas próprias convenções.

Muitas das informações aqui publicadas foram extraídas do guia oficial Class System, publicado na documentação do Ext JS 4.0. Se vocês quiserem mais detalhes, este é o lugar para procurar.

Forte abraço, até a próxima.

LinkedInDeliciousPinterestTumblrEmailShare