Menos é mais, quanto mais simples melhor
É, este é um dos tópicos do manifesto deste site.
Eu queria na verdade falar sobre 3 deles, mas este tópico tem o foco principal neste post. Parece uma frase simples, mas no desenvolvimento esta frase poderia evitar muitos e muitos problemas.
Numa conversa com um colega de trabalho meu da Agência, o Danilo, percebi que MUITOS plugins existentes para jQuery tem quase o mesmo tamanho ou é maior que a própria biblioteca!!!Na maioria das vezes desnecessariamente.
Isto porque na tentativa de facilitar o uso do código e pensar (ou tentar pensar) em todas as ocasiões possíveis, o desenvolvedor acaba codificando MUITO MAIS do que deveria.
Eu precisei fazer um esquema para fazer upload de múltiplos arquivos e utilizei um plugin para fazê-lo. Acabei precisando fazer uma gambiarra para fazer funcionar, porque não existia uma opção no plugin para o propósito.
Quando fui abrir o código-fonte para tentar estender o plugin, me deparei com um monstro de tantos KB. Fazia de tudo, abria modal, dava piruetas etc.
Trocentas linhas de código para fazer uma coisinha simples: mandar múltiplos arquivos ao submeter o formulário.Eu usei apenas um dos quinhentos métodos daquele plugin, imagina o que foi baixado para a página só para aquele funcionamento mais o jQuery!.
Mais tarde acabei fazendo uma versão minha deste código, apenas usando Javascript, e ainda assim ficou MUITO menor que a versão que utilizava jQuery…absurdo.
Pensando nisso, resolvi fazer uma implementação simples, rápida e estensível de um script antigo que o Elcio fez de máscaras, este aqui, e mostrar a minha forma, de usar os tópicos 2, 4 e 5 do manifesto do ClientSide, para resolver um problema simples, de forma simples, reaproveitando o código e usando um pouco de orientação a objetos em Javascript.
Pensei então em um objeto do tipo JSM, guardando algumas variáveis, sendo uma delas (JSM.add) para estender o objeto com novas máscaras, a outra (JSM.methods) para armazenar todos os métodos de mascaramento existentes no objeto e a outra uma pseudo-classe.
1 2 3 4 5 6 7 | function JSM (form){ return new JSM.Class(form) } JSM . add = function(json){ JSM.methods[json.name] = json.method } JSM . methods = {} |
JSM é uma função, mas é uma função que tem atrelada a ela outras variaveis, e retorna uma instância de uma “classe”, a JSM.Class, passando como parâmetro a string contendo o name do formulário.
A pseudo-classe:
1 2 3 4 5 6 7 8 9 10 11 12 13 | JSM . Class = function(form){ //Private: var form = document[form] //Public: this.inputs = {} this.form = function(){return form} this.test = function(object, mask){ var fn = JSM.methods[mask] setTimeout( function(){ object.value = fn( object.value ) },1 ) } } |
Assim, sempre que eu pensar em estender a classe, eu vou estender JSM.Class. Ela que vai armazenar o escopo do objeto retornado. É um padrão que eu tenho adotado em alguns projetos meus.
O método add é uma abstração da forma como é estendido o objeto na adição de máscaras novas, o desenvolvedor não precisa pensar em como foi montado o objeto JSM para estendê-lo corretamente, basta utilizar este método auxiliar que abstrai esta complexidade.
Então se eu quisesse estender o objeto com uma máscara nova eu faria:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | JSM.add({ "name":"telefone", "method": function(v){ //Remove tudo o que não é dígito v=v.replace(/\D/g,"") //Coloca parênteses em volta dos dois primeiros dígitos v=v.replace(/^(\d\d)(\d)/g,"($1) $2") //Coloca hífen entre o quarto e o quinto dígitos v=v.replace(/(\d{4})(\d)/,"$1-$2") return v } }) |
O desenvolvedor utilizaria esse método dando um nome e fornecendo um método que pega o valor, trata e retorna o novo valor mascarado, sem se preocupar no funcionamento do objeto.
Adicionado este método já poderia usar na instância do objeto JSM assim:
JSM("formulario").mask({ "campoTelefone" : "telefone" })
É mais rápido e mais fácil pegar os elementos pelo nome nos formulários, então o parâmetro do JSM é um name, do formulário, “campoTelefone” é o name de um input text deste formulário e telefone é a mascara que queremos utilizar no campo.
O JSM quebra a string da máscara quando esta tem um “|” (pipe), ou seja, na chamada da função você pode adicionar duas ou mais máscaras para o mesmo campo se necessário:
JSM("formulario").mask({ "campoTelefone" : "leech|digitos" })
- “Você esqueceu de fornecer um método para definir um maxlength!!”
Isto não é a função do objeto, é função do html, portanto, deve estar definido na própria tag! Simplifique.
Não fiz o objeto percorrer o html para achar uma classe conveniente e fazer o mascaramento, porque não é o papel dele, ele deve apenas mascarar, esta é sua função.
Se quiser fazer um microformato para ele, usando uma classe Css para este funcionamento, deve montar uma outra aplicação com este propósito, importando e utilizando o objeto JSM.
Eu queria mostrar, uma maneira simples de solucionar um problema de cada vez, com um objeto encapsulado. É muito fácil desacoplar os métodos adicionados para as máscaras e colocar em arquivos separados e mesmo outros métodos que estendam a classe JSM.Class, importando naquela página apenas os métodos que precisa utilizar, ou então utilizando as partes em uma aplicação terceira que faça outras coisas mais…
Eu uso muito namespaces, modularizando meu projeto. Portanto, se eu quisesse fazer uma extensão da classe com alguma frescura que não necessariamente seja algo de útil, eu faria outro arquivo para importar, usando namespace: Ex: JSM.frescura.js.
Entenderam? Sacaram a parada? Postei o código inteiro, com todas as máscaras que vi do site do Elcio e com suas explicações aqui para quem quiser.
Abraço.
Entry Details
Publicado em 23/06/2009 às 05:06 em Boas práticas, Básico, Javascript

Deixe um comentário