piratas-ar / pirate-crew

Herramienta para aceptar adhesiones al partido.
0 stars 0 forks source link

Crear componente para envío de emails. #1

Closed seykron closed 10 years ago

seykron commented 10 years ago

Tiene que ser reutilizable

Un patrón que funciona bastante bien en JavaScript para escribir componentes reutilizables se llama module pattern. La implementación que yo suelo usar para NodeJS es esta:

module.exports = function Component(arg) {
  // Private interface
  var doSomethingPrivate = function () {
    console.log(arg);
  };

  // Public interface
  return {
    foo: {
      doSomethingPrivate();
    }
  };
};

var instance = new Component("bar");
instance.foo(); // prints "bar" in the console.

Esta implementación soporta herencia y polimorfismo.

Tiene que soportar templates configurables

Como vamos a usarlo para mandar distintos tipos de notificaciones por email, tenemos que poder pasarle el path a un template y un objeto para expandir los placeholders del template. Hay que ver si ya se puede reutilizar handlebars, que es el motor que está configurado para express.

Hasta ahora el mailer más completo y sencillo que vi para node es nodemailer, sugiero que usemos ese como base de nuestro mailer.

exos commented 10 years ago

Ya fue eso, hay que usar AMD[0], yo me chorié el factory de Backbone[1] y ahora lo uso siempre, es asi:

(function (root, factory) {

if (typeof define === 'function' && define.amd) {
    define(['exports'], function (exports) {
        return factory(root, exports);
    });
} else if (typeof exports !== 'undefined') {
    factory(root, exports);
} else {
    root.NombreDelModulo = factory(root, {});
}

})(this, function (root, NombreDelModulo) {

var _noConflict = root.NombreDelModulo;

NombreDelModulo.noConflict = function () {
    root.NombreDelModulo = _noConflict;
    return NombreDelModulo;
}

.....

return NombreDelModulo;

});

De ese modo detecta:

seykron commented 10 years ago

¿Por qué meterías todo ese overhead si se puede resolver con un patrón de diseño?

El module pattern tiene todas estas ventajas:

Respecto a AMD, tengo varias críticas:

P.D.: genial que se haya dado este debate :)

exos commented 10 years ago

El 14 de mayo de 2014, 2:00, seykron notifications@github.com escribió:

¿Por qué meterías todo ese overhead si se puede resolver con un patrón de diseño?

wtf?

[exos@hexodica ~]$ time { let a=0; while [ $a -lt 1000 ]; do node amd.js ; let a=a+1; done }

real 0m22.803s user 0m18.780s sys 0m3.140s [exos@hexodica ~]$ time { let a=0; while [ $a -lt 1000 ]; do node noamd.js ; let a=a+1; done }

real 0m22.800s user 0m18.580s sys 0m3.240s

amd.js: http://paste.kde.org/pfrdgdrtk y noamd.js: http://paste.kde.org/pscgrfzte

Aparte lo que vos posteaste no es un patron de diseño ni nada parecido, estas exportando a una variable que nisiquiera sabés si está definida, no es crear un nuevo scope!!!

El patron de diseño module-pattern en todo caso, y en la mas común de la práctica sería:

(function (exports) {

// Aca si hay un verdadero scope independiente!!!

exports = {...}

})(exports);

Lo que yo postié en realidad usa varios patrones de diseño, combinando el module-pattern (pero bien aplicado) con la inyección de dependencias.

El module pattern tiene todas estas ventajas:

  • Es agnóstico de cualquier framework.

El que mostré yo sirve para node.js, browser sin framework (o mejor dicho javascript nativo) y herramientas como requirejs, si por ejemplo quieiera usar require.js no funcionaría...

  • No genera dependencias duras, por lo que el orden de carga de los archivos puede ser aleatorio.

Justamente AMD viene de "Async" :P, igualmente el orden de carga SIEMPRE importa, esto en cualquier lenguaje que se te ocurra, y AMD resuelve esa parte para que no tengas que pensarla vos...

  • Gracias al punto anterior se pueden generar bundles sin tener problemas de dependencias de includes, lo que facilita mucho el empaquetado y la distribución.

r.js mi_package_amd_folder -o mipackage.js <- mas fácil de empaquetar imposible...

rs.js: https://github.com/jrburke/r.js/

  • Si hablamos de diseño de frameworks, no es muy buena práctica hacer que los clientes dependan de otro framework como AMD.

AMD no es un framework, como dije ese factoty lo podés usar desde JS nativo.

  • El problema de resolución de dependencias es un problema técnico que a mi criterio está por afuera del diseño de un componente; es configuration management, no arquitectura.

WTF2

  • El module pattern ordena muchísimo el código, soporta herencia por mixins y si es necesario polimorfismo. Para trabajar en equipo esto suma mucho porque baja a barrera de adaptación de nuevos miembros ya que es JavaScript nativo.

null

  • Se pueden escribir unit tests sin depender de AMD.

Exacto!

Respecto a AMD, tengo varias críticas:

  • Agrega una dependencia dura a la librería AMD. Esto es terrible porque asume que AMD a priori está en el ambiente (en ambientes que no son de browsers esto es bastante problemático).

if (typeof define && define.amd) <- no me suena a asumir...

  • La resolución de dependencias está atada a la modularización, y esto tiene consecuencias bastante feas: la más jodida a mi criterio es que no se pueden resolver dependencias transitivas en un browser, así que sí o sí tiene que delegarlo al server. Esto de por sí ya le resta valor al intento de resolver dependencias de AMD.

WTF3

  • Tu infraestructura está atada a una librería de terceros, lo que es bastante peligroso. La mayoría de las libs que resuelven infraestructura en JavaScript (ej: Backbone) están pensadas para resolver escenarios muy limitados (y en general los escenarios fáciles que no ameritan una librería), si necesitás correrte de esos escenarios el código se vuelve bastante inmantenible. Los límites de estos frameworks aparecen rápido cuando trabajás en proyectos medianos-grandes dentro de un equipo de desarrollo.

Lidero equipos de desarrollo, hace años, creeme que trabajar con código espaguetti es un dolor de huevos que usar estas librerias, en todo caso, el camino que siguen las librerias hechas para JS es el de la extensión facilitada, por ejemplo backbone que mencionaste no es un framework final, sino una libreria extensible que sirve de base (o columna vertebral, para tu aplicacion), no es raro que se utilize:

var MiModelo = Backbone.Model.extend({ ... <- mi extensión del componente Module. });

  • Para mi gusto, resuelve problemas que no existen o que pueden resolverse usando patrones de diseño con JavaScript nativo.

No entiendo a que te referis con esto, justamente "exports" es algo muy de node.js y no es para nada nativo, algo que corregiría eso seria:

(function (exports) { .... exports = miModulo; })(exports || this.miModulo);

P.D.: genial que se haya dado este debate :)

Si, posta.

— Reply to this email directly or view it on GitHubhttps://github.com/piratas-ar/pirate-crew/issues/1#issuecomment-43042387 .

Exos ~ Programador, hacker y filósofo web: http://blog.exodica.com.ar Linked'in: http://www.linkedin.com/in/ogexos Twitter: @exos, Indeti.ca: @exos Tels: [+54 11] 6385-EXOS (3967) - [+54 9 11] 6133-2442

-----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/IT d-- s++:* a- C+++$ UBL+++$ P(-) L+++$ !E--- W+++$ !N !o K-? !w--- !O !M-- V? PS+++@ !PE Y+(++) PGP++ !t--- !5 X++ R(+) tv--(!) b- DI D-- G e@h>++ r--- y*>+++++ ------END GEEK CODE BLOCK------