{"id":3703,"date":"2014-11-07T09:51:28","date_gmt":"2014-11-07T11:51:28","guid":{"rendered":"http:\/\/blog.turbosite.com.br\/?p=3703"},"modified":"2014-11-07T09:51:28","modified_gmt":"2014-11-07T11:51:28","slug":"javascript-e-padrao-de-modulo","status":"publish","type":"post","link":"https:\/\/www.turbosite.com.br\/blog\/javascript-e-padrao-de-modulo\/","title":{"rendered":"JavaScript e Padr\u00e3o de M\u00f3dulo"},"content":{"rendered":"<p>Continuando a postagem anterior\u00a0<a title=\"JavaScript IIFE como cont\u00eainer de c\u00f3digos\" href=\"https:\/\/www.turbosite.com.br\/blog\/javascript-iife-como-conteiner-de-codigos\/\">JavaScript IIFE como cont\u00eainer de c\u00f3digos<\/a>, compartilhamos aqui\u00a0mais um artigo do blog <a href=\"http:\/\/desenvolvimentoparaweb.com\/javascript\/javascript-module-pattern-padrao-modulo\/\">Desenvolvimento Para Web<\/a>. A equipe da <a href=\"https:\/\/www.turbosite.com.br\/\">Turbosite<\/a>\u00a0repassa seu conhecimento sobre\u00a0<strong class=\"single__fake-title\">JavaScript Module Pattern\u00a0(Padr\u00e3o de M\u00f3dulo)<\/strong>, um padr\u00e3o de desenvolvimento bastante comum para Javascript. As pr\u00f3ximas linhas abaixo abrangem deste o estudo\u00a0b\u00e1sico ao avan\u00e7ado desse padr\u00e3o.<\/p>\n<p>&nbsp;<\/p>\n<h2>Anonymous Closures (Closures An\u00f4nimos)<\/h2>\n<p><strong>Anonymous Closures<\/strong> s\u00e3o o construto fundamental em Module Pattern que tornam tudo isso poss\u00edvel e s\u00e3o uma das melhores caracter\u00edstica de JavaScript: \u00e9 poss\u00edvel criar uma fun\u00e7\u00e3o an\u00f4nima e execut\u00e1-la imediatamente. Todo o c\u00f3digo que \u00e9 executado dentro da fun\u00e7\u00e3o esta no escopo do closure (algo como \u201cfechamento\u201d), o que proporciona privacidade e estado durante toda a vida da aplica\u00e7\u00e3o.<\/p>\n<div class=\"wp_syntax\">\n<pre class=\"lang:js decode:true\">(function () {\n    \/\/ Todas vari\u00e1veis e fun\u00e7\u00f5es est\u00e3o somente neste escopo\n    \/\/ e ainda mant\u00eam acesso a todos os globais\n}());<\/pre>\n<\/div>\n<p>Observe a <code>()<\/code> em torno da fun\u00e7\u00e3o an\u00f4nima. Isto \u00e9 requerido pela linguagem, uma vez que declara\u00e7\u00f5es que come\u00e7am com a fun\u00e7\u00e3o de token s\u00e3o sempre considerados declara\u00e7\u00f5es de fun\u00e7\u00e3o. Incluir <code>()<\/code> cria uma express\u00e3o de fun\u00e7\u00e3o.<\/p>\n<p>&nbsp;<\/p>\n<h2>Global Import<\/h2>\n<p>JavaScript tem um recurso conhecido como <strong>implied globals<\/strong> (globals impl\u00edcitas). Sempre que um nome \u00e9 usado, o interpretador volta pela cadeia de escopo em busca de uma declara\u00e7\u00e3o de vari\u00e1vel (<code>var<\/code>) para esse nome. Se nada for encontrado, a vari\u00e1vel \u00e9 assumida como global; se \u00e9 usado em um assignmente, o global \u00e9 criado se n\u00e3o existir. Isso significa que o uso ou a cria\u00e7\u00e3o de vari\u00e1veis \u200b\u200bglobais em um closure an\u00f4nimo \u00e9 f\u00e1cil. Infelizmente, isso leva a c\u00f3digo dif\u00edcil de gerir, j\u00e1 que n\u00e3o \u00e9 \u00f3bvio (para humanos) que as vari\u00e1veis \u200b\u200bs\u00e3o globais em um determinado arquivo.<\/p>\n<p>Felizmente, o recurso de fun\u00e7\u00e3o an\u00f4nima fornece uma alternativa f\u00e1cil a isso. Ao passar globais como par\u00e2metros para a fun\u00e7\u00e3o an\u00f4nima, que os importa para o c\u00f3digo. Eis um exemplo:<\/p>\n<div class=\"wp_syntax\">\n<pre class=\"lang:js decode:true\">(function ($, YAHOO) {\n    \/\/ Agora se tem acesso \u00e0s globais jQuery (como \"$\") e YAHOO nesse c\u00f3digo\n}(jQuery, YAHOO));<\/pre>\n<p>&nbsp;<\/p>\n<\/div>\n<h2>Module Export<\/h2>\n<p>\u00c0s vezes, voc\u00ea n\u00e3o quer apenas usar globais, mas quer declar\u00e1-los. \u00c9 poss\u00edvel fazer isso facilmente ao export\u00e1-los, usando o valor de retorno da fun\u00e7\u00e3o an\u00f4nima. Se o fizer, completar\u00e1 o Padr\u00e3o de M\u00f3dulo b\u00e1sico. Veja um exemplo completo:<\/p>\n<div class=\"wp_syntax\">\n<pre class=\"lang:js decode:true\">var MODULE = (function () {\n    var my = {},\n             privateVariable = 1;\n\u00a0\n    function privateMethod() {\n        \/\/ ...\n    }\n\u00a0\n    my.moduleProperty = 1;\n    my.moduleMethod = function () {\n        \/\/ ...\n    };\n\u00a0\n    return my;\n}());<\/pre>\n<\/div>\n<p>Observe que foi declarado um m\u00f3dulo global chamado <code>MODULE<\/code> com duas propriedades p\u00fablicas: um m\u00e9todo chamado <code>MODULE.moduleMethod<\/code> e uma vari\u00e1vel chamada <code>MODULE.moduleProperty<\/code>. Al\u00e9m disso, ele mant\u00e9m o estado interno privada usando o closure da fun\u00e7\u00e3o an\u00f4nima \u2014 e tamb\u00e9m \u00e9 poss\u00edvel importar globais necess\u00e1rios usando o padr\u00e3o mostrado anteriormente.<\/p>\n<p>&nbsp;<\/p>\n<h2>Augmentation<\/h2>\n<p>Uma limita\u00e7\u00e3o do Module Pattern at\u00e9 agora \u00e9 que o m\u00f3dulo inteiro deve estar em um arquivo. Quem j\u00e1 trabalhou em uma grande base de c\u00f3digo entende o valor de divis\u00e3o de c\u00f3digo em v\u00e1rios arquivos. Felizmente, existe uma boa solu\u00e7\u00e3o:\u00a0<strong>Augmentation<\/strong> (Amplia\u00e7\u00e3o). Em primeiro lugar, \u00e9 preciso importar o m\u00f3dulo; ent\u00e3o, s\u00e3o adicionadas novas propriedades e; por fim, ele \u00e9 exportado.<\/p>\n<p>Aqui est\u00e1 um exemplo de uso de Augmentation:<\/p>\n<div class=\"wp_syntax\">\n<pre class=\"lang:js decode:true\">var MODULE = (function (my) {\n    my.anotherMethod = function () {\n        \/\/ M\u00e9todo adicionado...\n    };\n    return my;\n}(MODULE));<\/pre>\n<p>\u00c9 usada a palavra-chave <code>var<\/code> novamente para consist\u00eancia, apesar de n\u00e3o ser estritamente necess\u00e1rio. Ap\u00f3s este c\u00f3digo ser executado, o m\u00f3dulo ter\u00e1 ganho um novo m\u00e9todo p\u00fablico chamado <code>MODULE.anotherMethod<\/code>. Este arquivo \u201campliado\u201d tamb\u00e9m manter\u00e1 seu pr\u00f3prio estado interno privado e importa\u00e7\u00f5es.<\/p>\n<p>&nbsp;<\/p>\n<\/div>\n<h2>Loose Augmentation<\/h2>\n<p>Enquanto o exemplo acima requer a cria\u00e7\u00e3o inicial do m\u00f3dulo em primeiro lugar e a amplia\u00e7\u00e3o acontecer depois disso, isso nem sempre \u00e9 necess\u00e1rio. Uma das melhores coisas que um aplicativo JavaScript pode fazer em rela\u00e7\u00e3o a desempenho \u00e9 carregar scripts de forma ass\u00edncrona. \u00c9 poss\u00edvel criar m\u00f3dulos flex\u00edveis de v\u00e1rias partes que podem se carregar em qualquer ordem com o <strong>Loose Augmentation<\/strong> (Amplia\u00e7\u00e3o Fraca). Cada arquivo deve ter a seguinte estrutura:<\/p>\n<div class=\"wp_syntax\">\n<pre class=\"lang:js decode:true\">var MODULE = (function (my) {\n    \/\/ Adiciona recursos...\n    return my;\n}(MODULE || {}));<\/pre>\n<\/div>\n<p>Neste padr\u00e3o, a instru\u00e7\u00e3o <code>var<\/code> \u00e9 sempre necess\u00e1ria. Note que a importa\u00e7\u00e3o vai criar o m\u00f3dulo se ele ainda n\u00e3o existir. Isto significa que voc\u00ea pode usar uma ferramenta como <a href=\"http:\/\/labjs.com\/\">LABjs<\/a> e carregar todos os seus arquivos de m\u00f3dulo em paralelo, sem a necessidade de bloquear.<\/p>\n<p>&nbsp;<\/p>\n<h2>Tight Augmentation<\/h2>\n<p><strong>Tight Augmentation<\/strong> (Amplia\u00e7\u00e3o Forte) \u00e9 excelente, mas coloca algumas limita\u00e7\u00f5es no m\u00f3dulo, dentre as quais se destaca a impossibilidade de poder substituir as propriedades do m\u00f3dulo de maneira segura. Tamb\u00e9m n\u00e3o \u00e9 poss\u00edvel usar as propriedades do m\u00f3dulo de outros arquivos durante a inicializa\u00e7\u00e3o \u2014 embora seja poss\u00edvel em tempo de execu\u00e7\u00e3o ap\u00f3s a inicializa\u00e7\u00e3o. Loose Augmentation implica numa ordem estabelecida de carregamento, mas permite substitui\u00e7\u00f5es.<\/p>\n<p>Eis um exemplo simples (ampliando o m\u00f3dulo-exemplo original):<\/p>\n<div class=\"wp_syntax\">\n<pre class=\"lang:js decode:true\">var MODULE = (function (my) {\n    var old_moduleMethod = my.moduleMethod;\n\u00a0\n    my.moduleMethod = function () {\n        \/\/ sobrescrita de m\u00e9todo com acesso ao antigo atrav\u00e9s de old_moduleMethod foi \n    };\n\u00a0\n    return my;\n}(MODULE));<\/pre>\n<p><code>MODULE.moduleMethod<\/code> foi substitu\u00eddo, mas manteve uma refer\u00eancia para o m\u00e9todo original, caso fosse necess\u00e1rio.<\/p>\n<p>&nbsp;<\/p>\n<\/div>\n<h2>Cloning and Inheritance (Clonagem e Heran\u00e7a)<\/h2>\n<p>Dentre os Padr\u00f5es de Module Pattern, talvez este seja a op\u00e7\u00e3o mais flex\u00edvel. Ele permite que algumas composi\u00e7\u00f5es elegantes, mas que vem \u00e0 custa da flexibilidade: propriedades que s\u00e3o objetos ou fun\u00e7\u00f5es n\u00e3o ser\u00e3o duplicadas e existir\u00e3o como um objeto com duas refer\u00eancias. Mudando uma, mudar\u00e1 a outra. Isso pode ser corrigido para objetos com um processo de clonagem recursiva, mas, provavelmente, n\u00e3o pode ser fixado para fun\u00e7\u00f5es \u2014 exceto, talvez, com <code>eval()<\/code>.<\/p>\n<pre class=\"lang:js decode:true\">var MODULE_TWO = (function (old) {\n    var my = {},\n           key;\n&amp;nbsp;\n    for (key in old) {\n        if (old.hasOwnProperty(key)) {\n            my[key] = old[key];\n        }\n    }\n&amp;nbsp;\n    var super_moduleMethod = old.moduleMethod;\n    my.moduleMethod = function () {\n        \/\/ sobrescreve m\u00e9todo ao clonar, acesso ao super atrav\u00e9s de super_moduleMethod\n    };\n&amp;nbsp;\n    return my;\n}(MODULE));<\/pre>\n<p>&nbsp;<\/p>\n<h2>Cross-File Private State (Estado Privado Entre-Arquivos)<\/h2>\n<p>Uma limita\u00e7\u00e3o grave de dividir um m\u00f3dulo em v\u00e1rios arquivos \u00e9 que cada arquivo mant\u00e9m seu pr\u00f3prio estado privado e n\u00e3o tem acesso ao estado privado dos outros arquivos. Mas isso pode ser corrigido. Aqui est\u00e1 um exemplo de um m\u00f3dulo com Amplia\u00e7\u00e3o Fraca que vai manter o estado privado em todos as amplia\u00e7\u00f5es:<\/p>\n<div class=\"wp_syntax\">\n<pre class=\"lang:js decode:true\">var MODULE = (function (my) {\n    var _private = my._private = my._private || {},\n        _seal = my._seal = my._seal || function () {\n            delete my._private;\n            delete my._seal;\n            delete my._unseal;\n        },\n        _unseal = my._unseal = my._unseal || function () {\n            my._private = _private;\n            my._seal = _seal;\n            my._unseal = _unseal;\n        };\n\u00a0\n        \/\/ Acesso permanente a _private, _seal e _unseal\n\u00a0\n        return my;\n}(MODULE || {}));<\/pre>\n<\/div>\n<p>Qualquer arquivo pode definir propriedades em sua vari\u00e1vel local <code>_private<\/code> e esta ser\u00e1 imediatamente dispon\u00edvel para os outros. Uma vez que este m\u00f3dulo foi completamente carregado, o aplicativo deve chamar <code>MODULE._seal()<\/code>, que ir\u00e1 impedir o acesso externo ao interno <code>_private<\/code>.<\/p>\n<p>Se este m\u00f3dulo fosse ampliado novamente, mais \u00e0 frente na vida aplicativo um dos m\u00e9todos internos, em qualquer arquivo, pode chamar <code>_unseal()<\/code> antes de carregar o novo arquivo e <code>_seal()<\/code> novamente depois de ter sido executado.<\/p>\n<p>&nbsp;<\/p>\n<h2>Subm\u00f3dulo<\/h2>\n<p>O padr\u00e3o de Module Pattern <strong>Subm\u00f3dulo<\/strong> (Sub-module) \u00e9 considerado pela maioria como o mais simples. H\u00e1 muitos bons casos para a cria\u00e7\u00e3o de subm\u00f3dulos. \u00c9 como criar m\u00f3dulos regulares:<\/p>\n<div class=\"wp_syntax\">\n<pre class=\"lang:js decode:true \">MODULE.sub = (function () {\n    var my = {};\n    \/\/ ...\n    return my;\n}());<\/pre>\n<\/div>\n<p>Embora isso possa parecer bastante \u00f3bvio, vale a pena ser mencionado em um artigo desse tipo, haja vista que subm\u00f3dulos t\u00eam todas as capacidades avan\u00e7adas de m\u00f3dulos normais, incluindo amplia\u00e7\u00e3o e estado privado.<\/p>\n<p>&nbsp;<\/p>\n<h2>Conclus\u00e3o<\/h2>\n<p>A maioria dos Padr\u00f5es Avan\u00e7ados de Module Pattern podem ser combinados uns com os outros para criar padr\u00f5es mais \u00fateis. N\u00e3o raramente \u00e9 poss\u00edvel encontrar, em aplica\u00e7\u00f5es mais complexas, a combina\u00e7\u00e3o de Amplia\u00e7\u00e3o Fraca, Estado Privado e Subm\u00f3dulos.<\/p>\n<p>No decorrer do artigo, n\u00e3o se mencionou a respeito de performance, mas uma nota r\u00e1pida sobre isso seria: Module Pattern \u00e9 bom para performance! Ele passa por minifica\u00e7\u00e3o muito bem, o que faz com que o download seja mais r\u00e1pido. Usar Loose Augmentation permite downloads paralelos, f\u00e1ceis e sem bloqueios. O tempo de inicializa\u00e7\u00e3o \u00e9, provavelmente, um pouco mais lento do que outros m\u00e9todos, mas o custo-benef\u00edcio vale a pena. Desempenho em tempo de execu\u00e7\u00e3o n\u00e3o deve sofrer penalidades desde que globais sejam importados corretamente e, provavelmente, h\u00e1 aumento de velocidade em subm\u00f3dulos, encurtando a cadeia de refer\u00eancia com vari\u00e1veis \u200b\u200blocais.<\/p>\n<p>Para fechar sobre Module Patterns, aqui est\u00e1 um exemplo de um subm\u00f3dulo que se carrega dinamicamente a seu parent (criando-se se ele n\u00e3o existe) \u2014 o estado privado foi deixado de fora para que o exemplo fique mais conciso, mas incluir isso seria simples.<\/p>\n<div class=\"wp_syntax\">\n<pre class=\"lang:js decode:true \">var UTIL = (function (parent, $) {\n    var my = parent.ajax = parent.ajax || {};\n\u00a0\n    my.get = function (url, params, callback) {\n        \/\/ Um pouquinho de trapa\u00e7a... xD\n        return $.getJSON(url, params, callback);\n    };\n\u00a0\n    \/\/ etc\n\u00a0\n    return parent;\n}(UTIL || {}, jQuery));<\/pre>\n<p>Este padr\u00e3o de c\u00f3digo permite que toda uma base de c\u00f3digos complexa hier\u00e1rquica seja completamente carregada em paralelo, com sub-m\u00f3dulos e tudo o mais.<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>A equipe da Turbosite repassa seu conhecimento sobre JavaScript Module Pattern (Padr\u00e3o de M\u00f3dulo), abrangendo deste o estudo b\u00e1sico ao avan\u00e7ado desse padr\u00e3o.<\/p>\n","protected":false},"author":1,"featured_media":3705,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,15],"tags":[362,363,364],"class_list":["post-3703","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dicas","category-javascript","tag-javascript-avancado","tag-javascript-module-pattern","tag-javascript-padrao-de-modulo"],"_links":{"self":[{"href":"https:\/\/www.turbosite.com.br\/blog\/wp-json\/wp\/v2\/posts\/3703","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.turbosite.com.br\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.turbosite.com.br\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.turbosite.com.br\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.turbosite.com.br\/blog\/wp-json\/wp\/v2\/comments?post=3703"}],"version-history":[{"count":0,"href":"https:\/\/www.turbosite.com.br\/blog\/wp-json\/wp\/v2\/posts\/3703\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.turbosite.com.br\/blog\/wp-json\/wp\/v2\/media\/3705"}],"wp:attachment":[{"href":"https:\/\/www.turbosite.com.br\/blog\/wp-json\/wp\/v2\/media?parent=3703"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.turbosite.com.br\/blog\/wp-json\/wp\/v2\/categories?post=3703"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.turbosite.com.br\/blog\/wp-json\/wp\/v2\/tags?post=3703"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}