2011-04-21 17 views
11

Estoy construyendo una aplicación grande javascript y que se decantó por Nicholas Zakas' escalable diseño de la arquitectura de aplicaciones: http://developer.yahoo.com/yui/theater/video.php?v=zakas-architectureAyuda con "Arquitectura de aplicaciones JavaScript escalable"

Según su sistema, los módulos son auto-encapsulado y no lo hacen saber el uno del otro ... Sin embargo, he encontrado muchas instancias en mi proyecto donde parecía necesario que los módulos se conocieran unos a otros, porque son en esencia las partes individuales de un todo más grande.

Por ejemplo .. Tengo tres módulos: Cargar, Ventana y Administrador.

Al hacer clic en una opción de carga, se abre una ventana emergente con un formulario de carga. También hay un enlace en la ventana "administrador".

Al hacer clic en el enlace Manager actualiza la ventana emergente para mostrar las herramientas de administración ...

...

Se hizo más sentido para que haga (pseudo código):

upload module: 
    upload option click --> sandbox.notification('need pop up window', [...html markup for form...]) 

manager module: 
    manager link click --> sandbox.notification('need pop up window', [...html markup for admin tools...]) 

window module: 
    sandbox.listen('need pop up window') --> calls createPopUpWindow(passed in html markup ) 

... Sin embargo, esto va en contra de la filosofía porque los módulos de gestor de cargas y son específicamente "solicitando" el módulo de ventana para hacer algo, por lo que saben al respecto ...

Por lo tanto, la única manera que puedo pensar para hacer esto sería:

upload module: 
    upload option click --> sandbox.notification('upload option clicked', [...html markup for form...]) 

manager module: 
    manager link click --> sandbox.notification('manager link clicked', [...html markup for admin tools...]) 

window module: 
    sandbox.listen('upload option clicked') --> calls createPopUpWindow(passed in html markup ) 
    sandbox.listen('manager link clicked') --> calls createPopUpWindow(passed in html markup ) 

.. Pero eso se siente mucho menos intuitiva, y honestamente creo que tiene mi código mucho menos claro, porque mirando la notificación del módulo de carga 'opción de carga presionada', no me dice en absoluto qué se supone que debe suceder cuando se hace clic. Tengo que buscar en todos mis otros archivos los módulos que están escuchándolo ..... Supongo que se puede ver como un beneficio, ya que es posible que varios módulos quieran responder a la 'opción de carga presionada', donde un módulo solo podría abordar la 'ventana emergente de necesidad'.

Pero al seguir ese enfoque, empieza a tener menos sentido para mí tener mi módulo de carga pasando un montón de etiquetas HTML que pertenecen a una ventana emergente que desconoce, y comienza a parecerse a la el módulo de ventana debería estar a cargo de generar ese marcado --- pero una gran parte del marcado es específico de "carga", y el marcado tiene oyentes de evento vinculados a funciones dentro del módulo de carga --- por lo que tener eso en el módulo de ventana no es ' Es realmente lógico ... así que empieza a ser muy confuso en cuanto a cuál es la mejor manera de estructurar todo esto.

También tengo otra situación que es aún más problemática .. Dos módulos: Pista y Contenedor. El contenedor tiene muchas pistas, y originalmente tenía las funciones de seguimiento internamente como parte del módulo de contenedor, pero a medida que la longitud del código en el módulo comenzó a crecer, decidí separarlas en sus propios módulos por el código limpio. . de todos modos, debido a que el recipiente necesita saber acerca de la pistas y ser capaz de hacer referencia a ellos internamente, la única manera de que pudiera configurar esto era hacer:

containerObject = function(name) { 
    this.name      = name; 
    this.video_track    = {'name': 'video', 'markup': sandbox.notification('create-track', 'video')} 
    this.audio_track    = {'name': 'audio_1', 'markup': sandbox.notification('create-track', 'audio')} 
    ....etc.... 
}; 

Así el módulo de pista está haciendo un sandbox.listen ('create-track') y apunta eso a una función que devuelve un nuevo objeto track del tipo dado ..... Tal vez no vale la pena tener track sea su propio módulo ...... Ya que es el único lugar donde estoy asignando un valor basado en una llamada de notificación.

Me encantaría escuchar lo que otros programadores familiarizados con pub/sub arquitectura tienen que decir acerca de este tema ......

Por favor, dame tus pensamientos & consejo.

Gracias.

+0

Una implementación bastante simple que sigue bastante de cerca esta charla se puede encontrar aquí: https://github.com/aranm/scalable-javascript-architecture –

+0

En esta antigua publicación, que me fue muy útil en el pasado para vincular a [t3js] (http://t3js.org/), un "marco de JavaScript minimalista que proporciona la estructura central del código" creado por N. Zakas y su equipo directamente. [Aquí está] (https://www.box.com/blog/introducing-t3-enabling-large-scale-javascript-applications /) una publicación de blog del mismo Zakas que la presentó hace apenas un par de días. Espero que esto también sea útil. – Nobita

Respuesta

11

Hay una serie de patrones que se ocupan de las comunicaciones entre objetos, y ese es su verdadero problema: la comunicación.

Su problema puede ser destilado en:

  1. ¿Quieres funcionalidades a ser dividido en módulos
  2. ¿Quieres módulos sean tan auto-contenido como sea posible, con el menor número de enlaces fuera posible
  3. módulos necesitan trabajar con otros módulos en un "gran esquema de las cosas", sin embargo

No.3 es lo que estaba dando problemas - que desea módulos sean independientes, pero por otra parte NE para comunicarse con otros módulos para que su programa funcione.

Una solución típica será que el módulo abra canales de comunicación "estandarizados" para el mundo exterior. No debe importar (ni importar) cuántos, qué, dónde o qué objetos se encuentran al otro lado de esos canales. Simplemente toma los comandos de los canales de entrada y envía notificaciones a los canales de salida. Un beneficio lateral maravilloso es la capacidad de probar la unidad del módulo con facilidad.

en cuenta que los módulos no deben preocuparse por el otro lado - de la Cuatro W

lo que - no debe preocuparse por lo clases u objetos que está hablando con (o escuchar)

donde - - no debe tener cuidado cuando el otro lado es (servidor o en el mismo navegador?)

el que - no importa qué objeto debería paticular se está comunicando con (el presidente, o simplemente un trabajador)

cuántos - no debería importar cuántos objetos está hablando/escuchando simultáneamente

Luego conecta todo el gráfico con una configuración maestra. Este es el concepto básico detrás de la Inyección de Dependencia.

En cuanto a la instalación de cañerías, hay algunas formas/patrones que se puede hacer esto:

  1. Eventos y manipuladores
  2. publicación/suscripción
  3. COI/DI contenedor
  4. Combo de arriba
Cuestiones relacionadas