A versão em PDF do endereço de download ppt: http://www.slideshare.net/jibyjohnc/jqqQuerysummit-largescale-javascript-application-architecture
Nota: Durante o processo de agrupamento, descobri que os pensamentos do autor eram repetidos, então ele excluiu alguns deles. Se o seu inglês for bom, leia o PPT inglês diretamente.
A seguir, estão os principais capítulos deste artigo:
1. O que é "JavaScript Large Program"?
2. Considere a arquitetura do programa atual
3. Consideração de longo prazo
4. Brainstorm
5. Arquitetura sugerida
5.1 Padrão de design
5.1.1 Teoria do módulo
5.1.1.1 Visão geral
5.1.1.2 Modo de módulo
5.1.1.3 Tamanho da face automática do objeto
5.1.1.4 Módulo Commonjs
5.1.2 Modo de fachada
5.1.3 Modo mediador
5.2 Aplique à sua arquitetura
5.2.1 fachada - abstração do núcleo
5.2.2 Mediador - núcleo do programa
5.2.3 trabalhando de perto
6. Publicar Pub/Sub -Extensão: Eventos de Registro Automático
7. Perguntas e respostas
8. Agradecimentos
O que é "JavaScript Large Program"?
Antes de começarmos, vamos definir o que é um grande site JavaScript. Muitos especialistas experientes em desenvolvimento de JS também foram desafiados. Algumas pessoas dizem que mais de 100.000 linhas de código JavaScript são consideradas grandes, e algumas pessoas dizem que o código JavaScript deve ter mais de 1 MB de tamanho. De fato, nenhum deles está correto, porque a quantidade de código não pode ser medida como o número de códigos instalados. Muitos código JS triviais podem exceder facilmente 100.000 linhas.
Minha definição de "grande" é a seguinte. Embora possa não estar correto, deve estar relativamente próximo:
Pessoalmente, acho que grandes programas JavaScript devem ser muito importantes e incorporar muitos esforços de destaque de desenvolvedores para processar dados pesados e exibi -los no navegador.
Revise a arquitetura do programa atual
Não posso enfatizar o quão importante é esse problema. Muitos desenvolvedores experientes costumam dizer: "Os padrões criativos e de design existentes funcionam muito bem no meu projeto de tamanho médio anterior, por isso deve ser bom usá-los novamente em um programa um pouco maior, certo?", É verdade em certos programas, mas não se esqueça que, como é um programa grande, geralmente deve haver grandes preocupações que precisam ser quebradas e prestam atenção. Explico brevemente como leva tempo para revisar a arquitetura do programa que está em execução há muito tempo. Na maioria dos casos, a arquitetura atual do programa JavaScript deve ficar assim (observe que é uma arquitetura JS, não o que todos costumam chamar de ASP.NET MVC):
widgets personalizados
modelos
visualizações
Controladores
modelos
Bibliotecas/kits de ferramentas
um núcleo de aplicativo.
Você também pode encapsular o programa apenas em vários módulos ou usar outros padrões de design, o que é ótimo, mas se essas estruturas representarem completamente sua arquitetura, pode haver alguns problemas em potencial. Vamos dar uma olhada em alguns pontos importantes:
1. Quantas coisas em sua arquitetura podem ser retiradas e reutilizadas imediatamente?
Existem alguns módulos separados que não dependem de outro código? É independente? Se eu for para a base de código que você está usando e selecione alguns códigos de módulo do módulo e coloque -os em uma nova página, ele pode ser usado imediatamente? Você pode dizer que o princípio está ok. Eu sugiro que você planeje por um longo tempo. Se sua empresa desenvolveu muitos programas importantes antes, de repente um dia alguém disse que o módulo de bate -papo neste projeto é bom, vamos retirá -lo e colocá -lo em outro projeto. Você pode usá -lo sem modificar o código?
2. Quantos módulos o sistema precisa confiar em outros módulos?
Todos os módulos do sistema estão firmemente acoplados? Antes de fazer essa pergunta como preocupação, explicarei primeiro. Não é que todos os módulos não devam ter nenhuma dependência. Por exemplo, uma função de granulação fina pode ser estendida da função base. Meu problema é diferente dessa situação. Estou falando sobre as dependências antes de diferentes módulos funcionais. Em teoria, todos os diferentes módulos funcionais não devem ter muitas dependências.
3. Se algo der errado com uma parte do seu programa, as outras partes ainda funcionarão?
Se você criar um programa semelhante ao Gmail, poderá descobrir que muitos módulos no Gmail são carregados dinamicamente, como o módulo de bate -papo, que não é carregado ao inicializar a página e, mesmo que ocorra um erro após o carregamento, outras partes da página podem ser usadas normalmente.
4. Você pode testar seus módulos de uma maneira muito simples?
Cada um dos seus módulos pode ser usado em sites grandes com milhões de usuários, ou mesmo vários sites o usam; portanto, seus módulos precisam suportar o teste, ou seja, seja dentro ou fora da arquitetura, eles devem ser capazes de ser testados de maneira muito simples, incluindo a maioria das afirmações que podem ser passadas em ambientes diferentes.
Consideração de longo prazo
Ao estruturar grandes programas, o mais importante é ter o futuro. Você não pode apenas considerar a situação um mês ou um ano depois. Você deve considerar a possibilidade de mudanças em um longo período de tempo? Os desenvolvedores geralmente ligam o código de operações da DOM e programam com muita força, embora às vezes tenham encapsulado a lógica separada em diferentes módulos. Pense no motivo pelo qual não é muito bom a longo prazo.
Um colega meu disse uma vez que uma arquitetura precisa pode não ser adequada para cenários futuros e, às vezes, está correto, mas quando você precisa fazê -lo, pagará muito dinheiro. Por exemplo, pode ser necessário optar por substituir o dojo, jQuery, Zepto e Yui por determinados motivos de desempenho, segurança e design. Neste momento, há um problema. A maioria dos módulos tem dependências, que exigem dinheiro, tempo e pessoas, certo?
Não há problema em alguns sites pequenos, mas sites grandes precisam fornecer um mecanismo mais flexível sem se preocupar com vários problemas entre vários módulos. Isso economiza dinheiro e tempo.
Para resumir, você pode agora ter certeza de que pode substituir algumas bibliotecas de classe sem reescrever todo o programa? Caso contrário, o que vamos falar abaixo é mais adequado para você.
Muitos desenvolvedores experientes de JavaScript deram algumas notas importantes:
Justin Meyer, autor de JavaScriptMVC, disse:
O maior segredo para a construção de grandes programas é que você nunca crie grandes programas, mas divide os programas em pequenos módulos para tornar cada pequeno módulo testável, considerável e depois integrá -los ao programa.
Sites JavaScript de alto desempenho, autor Nicholas, Zakas:
"A chave é reconhecer desde o início que você não tem idéia de como isso crescerá. Quando você aceita que não sabe tudo, começa a projetar o sistema defensivamente. Você identifica as principais áreas que podem mudar, o que geralmente é muito fácil quando você dedicar um pouco de tempo a ele. -
Muitos problemas de texto são muito problemáticos. Para resumir, tudo pode ser alterado, por isso deve ser abstrato.
JQuery Fundamentals Autor Rebecca Murphey:
Quanto mais próxima a conexão entre cada módulo for, menos reutilizável será e maior a dificuldade de alterá -la.
As vistas importantes acima são os elementos centrais da construção da arquitetura e precisamos lembrar delas o tempo todo.
Brainstorm
Vamos brainstorm. Precisamos de uma arquitetura vagamente acoplada, sem dependências entre os módulos, cada módulo e o programa se comunica e, em seguida, a camada intermediária assume e processa as mensagens correspondentes.
Por exemplo, se tivermos um JavaScript construindo um programa de padaria on -line, um módulo envia uma mensagem que pode ser "existem 42 rodadas que precisam ser entregues". Utilizamos camadas diferentes para processar mensagens enviadas pelo módulo e fazemos o seguinte:
Os módulos não acessam diretamente o núcleo do programa
Os módulos não ligam diretamente ou afetam outros módulos
Isso nos impedirá de cometer erros em todos os módulos devido a erros em um determinado módulo.
Outro problema é a segurança. A situação real é que a maioria das pessoas não acha que a segurança interna é um problema. Dizemos em nossos corações que os programas são construídos por mim. Eu sei quais são públicos e privados. Não há problema com a segurança, mas você tem uma maneira de definir qual módulo acessar o núcleo do programa? Por exemplo, existe um módulo de bate -papo que eu não quero que ele chame o módulo de administrador, ou não quero que ele ligue para um módulo com permissões de gravação de DB, porque existe uma fragilidade entre eles e é fácil causar ataques XSS. Cada módulo não deve ser capaz de fazer tudo, mas o código JavaScript na maioria das arquiteturas atualmente tem esse problema. Forneça uma camada intermediária para controlar qual módulo pode acessar essa parte autorizada, ou seja, o módulo pode atingir apenas a maior parte da parte que autorizamos.
Arquitetura sugerida
O foco do nosso artigo é que desta vez a arquitetura que propomos usa padrões de design que todos somos conhecidos: módulo, fachada e mediador.
Diferentemente dos modelos tradicionais, a fim de dissociar cada módulo, deixamos apenas o módulo publicar alguns eventos de eventos. O modo mediador pode ser responsável por assinar mensagens de mensagem desses módulos e, em seguida, controlar a resposta de notificação. Os usuários do modo de fachada restringem as permissões de cada módulo.
A seguir, são apresentadas as peças para a qual precisamos prestar atenção:
1 padrão de design
1.1 Teoria do módulo
1.1.1 Visão geral
1.1.2 Modo de módulo
1.1.3 Tamanho da face automática do objeto
1.1.4 Módulo Commonjs
1.2 Modo de fachada
1.3 Modo mediador
2 Aplique à sua arquitetura
2.1 fachada - abstração do núcleo
2.2 Mediador - núcleo do programa
2.3 Trabalhe juntos
Teoria modal
Todos podem ter usado o código modular mais ou menos. O módulo faz parte de uma arquitetura completa e robusta do programa. Cada módulo é criado para uma finalidade separada. Voltando ao Gmail, vamos dar um exemplo. O módulo de bate -papo parece ser uma parte separada, mas na verdade possui muitos submódulos separados. Por exemplo, o módulo de expressão dentro é realmente um submódulo separado, que também é usado na janela para enviar e -mails.
Outra é que os módulos podem ser carregados, excluídos e substituídos dinamicamente.
No JavaScript, temos várias maneiras de implementar módulos. Todos estão familiarizados com os padrões de módulos e os literais de objeto. Se você já estiver familiarizado com eles, ignore esta seção e pule diretamente para a parte do Commonjs.
Modo de módulo
O padrão do módulo é um padrão de design relativamente popular. Pode encapsular variáveis, métodos e estados privados através de aparelhos. Ao envolver esses conteúdos, geralmente objetos globais não podem ser acessados diretamente. Nesse padrão de design, apenas uma API é retornada e todos os outros conteúdos são encapsulados como privados.
Além disso, esse padrão é semelhante às expressões de função auto-executada. A única diferença é que o módulo retorna um objeto, enquanto a expressão de função auto-executada retorna uma função.
Como todos sabemos, o JavaScript não deseja que outros idiomas tenham modificadores de acesso e não podem declarar modificadores públicos privados e privados para cada campo ou método. Então, como implementamos esse padrão? Isso é retornar um objeto, incluindo alguns métodos públicos, que têm a capacidade de chamar objetos internos.
Dê uma olhada no código abaixo. Este código é um código auto-executivo. A Declaração inclui um BatteryModule de Objeto Global. A matriz do cesto é privada, para que todo o seu programa não possa acessar esta matriz privada. Ao mesmo tempo, retornamos um objeto, que contém 3 métodos (como Additem, GetItemCount, Gettotal). Esses três métodos podem acessar a matriz de cesto particular.
var BasketModule = (function () {var Basking = []; // PrivatereTurn {// exposto ao public addItem: function (valores) {basking.push (valores);}, getItemCount: function () {return bket.length;}, gettotal: function () {var q = this.getItemCount (), pin; } retornar p;}}} ());Observe também que o objeto que retornamos é atribuído diretamente ao BasketModule, para que possamos usá -lo como o seguinte:
// BasketModule é um objeto com propriedades que também podem ser MethodsBasketModule.additem ({Item: 'pão', preço: 0.5}); bestaodule.additem ({item: 'manteiga', preço: 0.3}); console.log (bestaModule.getItemCount ()); console.log (bestaModule.gettotal ()); // No entanto, o seguinte não funcionará: console.log (bestaModule.basket); // (indefinido como não dentro do objeto retornado) console.log (cesto); // (existe apenas dentro do escopo do fechamento)Então, como isso em várias bibliotecas de classes populares (como dojo, jQuery)?
Dojo
O Dojo tenta usar o dojo.declare para fornecer métodos de declaração de estilo de classe. Podemos usá -lo para implementar o padrão do módulo. Por exemplo, se você deseja declarar um objeto de cesta no espaço de nome da loja, pode fazer isso:
// Tradicional Wayvar Store = Window.Store || {}; store.basket = store.basket || {}; // usando dojo.setObjectdojo.setObject ("store.basket.object", (function () {var cesta = []; function privatemethod () {console.log (cesto);} return {publicMethod: function () {privemethod ();}}; ());É muito poderoso quando combinado com dojo.provide.
Yui
O código a seguir é a implementação original de Yui:
Yahoo.store.basket = function () {// variáveis "privadas": var myPrivatevar = "Eu posso ser acessado apenas no yahoo.store.basket."; // Método "privado": var myPrivatemethod = function () {yahoo.log ("Eu posso ser acessado apenas em yahoo.store.basket"); } return {mypublicProperty: "Sou uma propriedade pública"., MyPublicMethod: function () {yahoo.log ("Sou um método público"); // Na cesta, posso acessar vars e métodos "privados": yahoo.log (myPrivatevar); Yahoo.log (myprivatemethod ()); // O escopo nativo do MyPublicMethod é a loja, para que possamos // acessar membros públicos usando "this": yahoo.log (this.mypublicProperty); }};} ();jQuery
Existem muitas implementações do padrão do módulo no jQuery. Vamos dar uma olhada em um exemplo diferente. Uma função da biblioteca declara uma nova biblioteca. Então, ao criar a biblioteca, o método init é executado automaticamente no document.ready.
Biblioteca da função (módulo) {$ (function () {if (module.init) {module.init ();}}); Return módulo;} var mylibrary = biblioteca (function () {return {init: function () { /*implementação* /}};} ());Tamanho da face automática do objeto
A medição de auto-face do objeto é declarada nos aparelhos e a nova palavra-chave não é necessária ao usá-la. Se você não se importa muito com o público/privado dos campos de atributo em um módulo, pode usar esse método, mas observe que esse método é diferente do JSON. Tamanho do objeto Auto-face: var item = {name: "Tom", valor: 123} json: var item = {"name": "tom", "value": 123}.
var myModule = {myProperty: 'algum valor', // Os literais de objeto podem conter propriedades e métodos. // Aqui, outro objeto é definido para configuração // propósitos: myconfig: {usecaching: true, idioma: 'en'}, // um método muito básico mymethod: function () {console.log ('eu posso funcionalidade HAZ?'); }, // Sair um valor com base na configuração atual mymethod2: function () {console.log ('cache é:' + (this.myconfig.usecaching)? 'Habiled': 'desativado'); }, // substitui a configuração atual myMethod3: function (newConfig) {if (typeof newConfig == 'object') {this.myConfig = newConfig; console.log (this.myconfig.language); }}}; myModule.mymethod (); // Eu posso HAZ funcionalidademodule.mymethod2 (); // saídas habilitedmymodule.mymethod3 ({idioma: 'fr', usecaching: false}); // frCommonjs
Não vou falar sobre a introdução de Commonjs aqui. Muitos artigos já o introduziram antes. O que queremos mencionar aqui é que existem dois parâmetros importantes exportações e exigem no padrão Commonjs. As exportações representam o módulo a ser carregado e requerem meios que esses módulos carregados precisam confiar em outros módulos e também precisam ser carregados.
/*Exemplo de alcançar a compatibilidade com a AMD e o Standard Commonjs, colocando o Boilerplate em torno do formato padrão do módulo CommonJS:*/(function (define) {define (function (requer, exports) {// Conteúdo do módulo var var de dep1 = requer ("dep1"); exportedFunction = () ()}; define == "function"? Definir: function (Factory) {Factory (requer, exporta)});Existem muitas implementações de carregamento de módulos padrão do CommonJS. O que eu prefiro é requerjs. Pode carregar módulos e módulos de dependência relacionados muito bem? Vamos dar um exemplo simples. Por exemplo, se você precisar converter a imagem em código ASCII, primeiro carregamos o módulo do codificador e, em seguida, obtemos seu método codetoascii. Teoricamente, o código deve ser o seguinte:
var codetoascii = requer ("codificador"). codetoascii; exports.encodesomesource = function () {// Após outras operações, depois ligue para o codetoascii}No entanto, o código acima não funciona, porque a função CodeTOASCII não é usada para anexar ao objeto da janela, portanto não pode ser usado. É isso que a melhoria do código precisa fazer:
define (function (requer, exporta, módulo) {var codetoascii = requer ("codificador"). codetoascii; exports.encodesomesource = function () {// Processe e depois chama codetoasciii}});O CommonJS tem um grande potencial, mas como o tio não está muito familiarizado com ele, não vou apresentá -lo muito.
Modo de fachada
O modelo de fachada ocupa um papel importante na arquitetura deste modelo. Muitas bibliotecas ou estruturas de classe JavaScript são refletidas neste modelo. A maior função é incluir a API do alto nível para ocultar implementações específicas. Isso significa que apenas expomos as interfaces e podemos tomar as decisões das implementações internas por nós mesmos, o que também significa que o código de implementação interno pode ser facilmente modificado e atualizado. Por exemplo, hoje você usa o jQuery para implementá -lo e amanhã deseja alterar o YUI, o que é muito conveniente.
No exemplo a seguir, podemos ver que fornecemos muitos métodos privados e, em seguida, expômos uma API simples para permitir que o mundo exterior execute e chama métodos internos:
var módulo = (function () {var _private = {i: 5, get: function () {console.log ('Valor atual:' + this.i);}, set: function (val) {this.i = val;}, run: function () {console.log ('runn');}, jump: function (), {function () {console.log ('runn');}, function: {) {function () {console.log ('runn');}, function. função (args) {_private.set (args.val);A diferença entre a fachada e o que estamos falando abaixo é que a fachada fornece apenas funções existentes, enquanto os mediadores podem adicionar novas funções.
Modo mediador
Antes de falar sobre o modiador, vamos dar um exemplo. O sistema de controle de vôo do aeroporto, que é a lendária torre, tem poder absoluto. Pode controlar a decolagem e o tempo de pouso e o local de qualquer aeronave. A aeronave e a aeronave não podem se comunicar antes, o que significa que a torre é o núcleo do aeroporto e o mediador é equivalente a esta torre.
O mediador é usado para ter vários módulos em um programa e você não deseja que cada módulo tenha dependências, o modo mediador pode alcançar o objetivo do controle centralizado. Nos cenários reais, o mediador encapsula muitos módulos que eles não querem fazer, permitindo que eles sejam conectados através dos mediadores e também os acoplassem vagamente, para que eles precisem se comunicar através dos mediadores.
Então, quais são as vantagens do modo mediador? Isso é dissociação. Se você tiver um bom entendimento do padrão de observador antes, será relativamente simples entender o diagrama mediador abaixo. A figura a seguir é um diagrama de padrões de mediador de alto nível:
Pense bem, cada módulo é um editor e o mediador é um editor e um assinante.
O módulo 1 transmite uma coisa real para o mediador, dizendo que algo precisa ser feito
Depois que o mediador captura a mensagem, inicie imediatamente o módulo 2 que precisa ser usado para processar a mensagem. Após a conclusão do processamento do Módulo 2, retorne as informações ao mediador.
Ao mesmo tempo, o mediador também inicia o Módulo 3 e faz login automaticamente no Módulo 3 ao receber a mensagem de retorno do módulo 2.
Pode -se observar que não há comunicação entre os módulos. Além disso, o mediador também pode implementar a função de monitorar o status de cada módulo. Por exemplo, se houver um erro no módulo 3, o mediador poderá desejar temporariamente apenas outros módulos, reiniciar o Módulo 3 e continuar a executar.
Olhando para trás, podemos ver que a vantagem do mediador é que o módulo pouco acoplado é controlado pelo mesmo mediador. O módulo precisa apenas transmitir e ouvir eventos, e não há necessidade de conexão direta entre os módulos. Além disso, vários módulos podem ser usados para processamento de informações por vez, o que também nos facilita para adicionar novos módulos à lógica de controle existente no futuro.
É certo que, como todos os módulos não podem se comunicar diretamente, pode haver um ligeiro declínio no desempenho em tudo de forma relativamente, mas acho que vale a pena.
Vamos usar uma demonstração simples com base na explicação acima:
var mediator = (function () {var assinscribe = function (canal, fn) {if (! mediator.channels [canal]) mediator.channels [canal] = []; mediator.channels [canal] .push ({context: this, callback: fn}); retorno; Array. Inscreva -se: Inscreva -se, FUNCHEN (OBJ)Depois, existem 2 módulos chamados:
// pub/sub em um mediador centralizado mediador.name = "tim"; mediator.subscribe ('namechange', function (arg) {console.log (this.name); this.name = arg; console.log (this.name);}); mediator.publish ('Namechange', 'David'); // Tim, David // Pub/sub Via Mediador de terceiros var obj = {nome: 'sam'}; mediator.installto (obj); obj.subScribe ('namechange', function (arg) {console.log (this.name); this.name = arg; console.log (.name); obj.publish ('namechange', 'John'); // Sam, JohnFachada de aplicação: a abstração do núcleo do aplicativo
Uma fachada funciona como um resumo do núcleo do aplicativo e é responsável pela comunicação entre o mediador e o módulo. Cada módulo só pode se comunicar com o núcleo do programa através desta fachada. A responsabilidade como resumo é garantir que esses módulos possam ser fornecidos com uma interface consistente a qualquer momento, o que é semelhante ao papel do controlador do SendBox. Todos os componentes do módulo se comunicam com os mediadores através dele, então a fachada precisa ser confiável e confiável. Ao mesmo tempo, como uma função para fornecer uma interface ao módulo, a fachada precisa desempenhar outro papel, ou seja, controle de segurança, ou seja, para determinar qual parte do programa pode ser acessada por um módulo. Os componentes do módulo só podem chamar seus próprios métodos e não podem acessar nenhum conteúdo não autorizado. Por exemplo, um módulo pode transmitir DataValidationCompletEdWritETODB, onde as verificações de segurança precisam garantir que o módulo tenha permissões de gravação no banco de dados.
Em suma, o mediador só pode executar o processamento de informações após a detecção de autorização da fachada.
Mediador de aplicação: o núcleo do aplicativo
O mediador trabalha como um papel central para o aplicativo, vamos falar brevemente sobre suas responsabilidades. O trabalho mais central é gerenciar o ciclo de vida do módulo. Quando esse núcleo captura qualquer informação, ele precisa julgar como o programa lida - ou seja, para decidir qual módulo iniciar ou parar. Quando um módulo inicia, ele deve ser capaz de executar automaticamente, sem o núcleo do aplicativo para decidir se deve ser executado (por exemplo, se deve ser executado quando o DOM estiver pronto), para que o próprio módulo precise determinar.
Você pode ter uma pergunta: em que circunstâncias um módulo parará? Quando o programa detecta que um módulo falha ou comete um erro, o programa precisa tomar uma decisão para impedir que o método no módulo continue a executar para que o componente possa ser reiniciado, com o principal objetivo de melhorar a experiência do usuário.
Além disso, o núcleo deve ser capaz de adicionar ou excluir dinamicamente módulos sem afetar outras funções. Um exemplo comum é que um módulo não está disponível no início do carregamento da página, mas depois que o usuário opera, ele precisa carregar dinamicamente o módulo e executá -lo. Assim como a função de bate -papo no Gmail, deve ser fácil entender com o objetivo de otimização de desempenho.
O manuseio de erros de exceção também é tratado pelo núcleo do aplicativo. Além disso, quando cada módulo transmite informações, ele também transmite quaisquer erros para o núcleo para que o núcleo do programa possa interromper/reiniciar esses módulos de acordo com a situação. Esta também é uma parte muito importante da arquitetura pouco acoplada. Não precisamos alterar manualmente nenhum módulo. Podemos fazer isso usando publicar/assinar através do mediador.
Montar
Cada módulo contém várias funções no programa. Quando eles têm informações a serem processadas, emitem informações notificando o programa (essa é sua principal responsabilidade). A seção de controle de qualidade seguinte mencionou que os módulos podem confiar em alguns métodos de operação da ferramenta DOM, mas não devem depender de outros módulos do sistema. Um módulo não deve prestar atenção ao seguinte conteúdo:
1. Qual objeto ou módulo assina as informações publicadas por este módulo
2. Esses objetos são objetos ou objetos do lado do servidor
3. Quantos objetos se inscreveram em suas informações
O núcleo da aplicação de abstração da fachada evita a comunicação direta entre os módulos. Ele assina informações de cada módulo e também é responsável pela detecção de autorização, garantindo que cada módulo tenha sua própria autorização separada.
O Mediator (Core de Application) usa o modo mediador para desempenhar o papel de Publish/Subscribe Manager, responsável pelo gerenciamento de módulos e execução do módulo de partida/parada, e pode carregar dinamicamente e reiniciar módulos com erros.
O resultado dessa arquitetura é que não há dependência entre os módulos, devido a aplicações pouco acopladas, elas podem ser facilmente testadas e mantidas, cada módulo pode ser facilmente reutilizado em outros projetos ou pode ser adicionado dinamicamente e excluído sem afetar o programa.
Publicar Pub/Sub -Extensão: Registro de Eventos Automáticos
Em relação ao registro automático de eventos, certas especificações de nomeação precisam ser seguidas. Por exemplo, se um módulo publicar um evento chamado MessageUpdate, todos os módulos com o método MessageUpdate serão executados automaticamente. Existem benefícios e vantagens e desvantagens. Para métodos específicos de implementação, você pode ver outra postagem minha: a versão Magic atualizada da JQuery Custom Binding.
QA
1. É possível não usar fachada ou modo de sandbox similar?
Embora o esboço da arquitetura propõe que a fachada possa implementar funções de verificação de autorização, é realmente totalmente possível que os mediadores possam fazê -lo. O que a arquitetura de luz precisa fazer é quase a mesma, ou seja, desacoplar e garantir que cada módulo se comunique diretamente com o núcleo do aplicativo.
2. Você melhorou que o módulo não pode ser diretamente dependente. Isso significa que ele não pode confiar em nenhuma biblioteca de terceiros (como o jQuery).
Este é realmente um problema de dois lados. Como mencionamos acima, um módulo pode ter alguns submódulos ou módulos básicos, como classes básicas de ferramentas de operação DOM, etc. Nesse nível, podemos usar a biblioteca de terceiros, mas verifique se podemos substituí-los facilmente.
3. Gosto dessa arquitetura e quero começar a usar essa arquitetura. Existem amostras de código que podem ser usadas para se referir?
Eu pretendo criar um exemplo de código para sua referência, mas antes disso, você pode se referir ao JavaScript modular de Andrew Burgees.
4. É viável se o módulo precisar se comunicar diretamente com o núcleo do aplicativo?
Tecnicamente, não há razão para que os módulos não possam se comunicar diretamente com o núcleo do aplicativo agora, mas para a maioria das experiências de aplicativos, ainda não é permitido. Como você escolheu essa arquitetura, você deve cumprir as regras definidas pela arquitetura.
Agradecimentos
Agradecemos a Nicholas Zakas pelo post original, para resumir as idéias, a Andree Hansson for Technical Review, a Rebecca Murphey, Justin Meyer, John Hann, Peter Michaux, Paul Irish e Alex Sexton, todos eles forneceram muitas informações relacionadas a esta sessão.