Gonzalo Martinez: Patrones Estructurales - Adapter

Los patrones estructurales se refieren a como las clases y objetos son compuestos para formar grandes estructuras. Los patrones de clase estructural usa herencia para componer interfaces o implementaciones. Como un ejemplo simple, considerar como la herencia múltiple mezcla dos o más clases dentro de uno. El resultado es una clase que combina las propiedades de su clase padre. Este patrón es particularmente útil para hacer que bibliotecas de clases desarrolladas independientemente trabajen juntas. Otro ejemplo es la forma de la clase del patrón Adapter. En general, un adaptador hace una interfaz (el adaptado) para ajustarse a otro, así provee una abstracción uniforme de diferentes interfaces. Una clase adaptador logra esto por la herencia privada desde un clase adaptada. El adaptador entonces expresa su interfaz en términos del adaptado.

Adapter

Intento,
Convertir la interfaz de una clase a otra interfaz que el cliente espera. Adapter permite que las clases trabajen juntas que de otro manera no podrían por que sus interfaces son incompatibles.

Motivación
A veces una clase de una caja de herramientas que es diseñada para su reutilización no es reutilizable solo por que sus interfaces no coinciden con la interfaz especifica del dominio que una aplicación requiere.
Considera por ejemplo un editor de dibujo que permite a los usuarios dibujar y organizar los elementos gráficos (lineas, polígonos, texto, etc.) dentro de imágenes y diagramas. La clave del editor de dibujo es el objeto gráfico, que tiene una forma editable y puede dibujarse a si mismo. La interfaz para objetos gráficos es definido por una clase abstracta llamada Shape. El editor define una subclase de Shape por cada tipo de objeto gráfico: un clase LineShape para lineas, una clase PolygonShape para polígonos, y así sucesivamente.

Clases para cada forma elemental de la geometría como LineShape y PolygonShape son bastante fáciles de implementar, porque su dibujo y capacidades de edición son limitados por la herencia. Pero una subclase TextShape que puede mostrar y editar texto es considerablemente más dificil de implementar, desde la edición de texto, incluso lo más básico consiste en la actualización constante de la pantalla y el manejo del buffer. Mientras tanto un producto listo para la interfaz de usuario es el kit de herramientas que deberia estár listo para proveer una sofisticada clase TextView para mostrar y editar texto. Idealmente, nos gustaría reusar TextView para implementar TextShape, pero el kit de herramientas no fue diseñado con la clase Shape en mente. Así que nosotros no podemos usar los objetos TextView y Shape de manera intercambiable.

Como puede una clase existente y no relacionada como TextView trabajar en una aplicación que espera clases con una interfaz diferente e incompatible? Podríamos cambiar la clase TextView tal que sea ajuste a la interfaz de Shape, pero ese no es una opción a menos que nosotros tengamos acceso el código fuente del kit de herramientas. Incluso si lo tuvieramos, no tendría sentido hacer el cambio a TextView; el kit de herramientas no deberia tener que adoptar interfaces especificas del dominio solo para hacer que una aplicación funcione.

En su lugar, definimos TextShape tal que esta adapte la interfaz de TextView a Shape's. Podemos hacer esto en una o dos maneras: (1) por herencia de la interfaz de Shape e implementación de TextView o (2) componiendo una instancia de TextView con una TextShape e implementando TextShape en terminos de la interfaz de TextView. We call TextShape an adapter.

Aplicabilidad
Usa el patron Adapter cuando:

  • quiere usar una clase existente, y su interfaz no coincide con el que usted necesita.
  • quiere crear una clase reutilizable que coopera con clases no relacionadas o imprevistas, es decir, clases que no necesariamente tienen interfaces compatibles.
  • (solo adaptador de objetos) necesitas usar muchas subclases existentes, pero no es práctico adaptar su interfaz por subclaseo cada vez. Un objeto adaptador puede adaptar la intefaz de su clase padre.
Participantes.
Target, define la interfaz especifica del dominio que el cliente usa.
Cliente, colabora con objetos ajustándose a la interfaz del Target.
Adaptee, define una interfaz existente que necesita ser adaptada.
Adapter, adaptar la interfaz del Adaptee a la interfaz de Target.

Ejemplos de uso en Python [0] [1]

Gonzalo Martinez: Patrones Creacionales - Singleton

Intento,
Asegurar que una clase solo tiene una instancia y proveer un punto de acceso global.

Motivacion

      Es importante para algunas clases tener exactamente una sola instancia. Aunque puede haber muchas impresoras en un sistema, debe haber solo una cola de impresión. Debe ser solo un sistema de archivo y un administrador de ventanas. Un filtro digital tendrá un convertidor A/D. Un sistema contable será dedicado a server una compania.
Como podemos asegurar que una clase tiene solo una instancia y que la instancia es facilmente accesible? Una variable global hace a un objeto accessible, pero no te resguarda de instanciar multiples objetos.

Una mejor solución es hacer a la clase responsable de si misma para mantener un registro de una sola instancia. La clase puede asegurar que ninguna otra instancia puede ser creada(interceptando los pedidos para crear nuevos objetos), y puede proveer una manera de acceder a la instancia. Este es el Patrón Singleton.

Aplicabilidad

Usa el patrón Singleton cuando.

  • Debe haber exactamete una instancia de una clase, y esta debe estar accesible a los clientes de un punto de acceso conocido.
  • Cuando la única instancia debería ser extensible por subclaseo, y los clientes deberían ser capaces de usar un instancia extendidad sin modificar su código.
Participantes
Singleton, define una operación de Instance que permite a los clientes acceder a la instancia unica. Instance es una operación de clase (que es, un metodo de clase en Smalltalk y una función miembro estático en C++).
Puede ser responsable por crear la propia única instancia.

Ejemplos del Patrón Singleton [0] [1] 

Gonzalo Martinez: Analizando Quiper - Compará precios descuidados

Quiper[0], es una aplicación móvil desarrollada en la empresa donde trabajo, que se llama Quicuo[1].

Su nombre es principalmente una fusión de la palabra Quicuo y Super. Es una aplicación que permite comparar los precios de todo tipo de productos en los supermercados más grandes del país y en principio funciona bastante bien para los que son de Capital y Gran Buenos Aires.

Aplicación Movil
La aplicación móvil está desarollada en HTML, CSS y Javascript. Con una terrible ayuda de PhoneGap [2] para hacerla multi plataforma. Principalmente fue creada para Android[3] pero con muy pocos cambios puede ser y va a ser generada para IPhone muy pronto.

Backend - API
La API de consulta está desarrollada sobre node.js[4], con expressjs[5] como Framework de desarrollo y sequelize[6] como ORM[7] para las consultas a la base de datos.
Todo esto es servido a tráves de pm2[15] como supervisor de procesos en nodejs y con Nginx[16] como WebServer.

Backend - DB, Extracción y Analisis
La extracción que es parte principal del desarrollo está escrita sobre Python[9], en principio se analizó un Scrappeador profesional pero para los primeros intentos nos pareció un poco complejo así que se optó por hacer un Scrapper propio bien amoldado para nuestro propósito. Por consiguiente, se utilizaron diferentes librerías que son bastante típicas en verdad para esto. BeautifulSoup[10] como parseador de las respuestas HTML para extracción de datos. Mechanize[11] como generador de requests dinamicas y crawler de webs, en principio fue generado todo con Mechanize y luego en algunos casos simples se usó requests[12] una librería con una API mucho más elegante. Además para guardar estos datos de forma más programática se uso SQLObject[13] como ORM en esta etapa.

Finalmente el análisis y unión de datos fue escrito en PHP[14] y se usó su conector para MySQL limpio sin ORM.

Servidores
Básicamente los servidores están en Amazon EC2[17] y por el momento son Dos uno como WebServer para los servicios que corren Nodejs. La Api que consume la app móvil y la Web que todavia no se lanzó.
Y otro server que es el más grande y es el de la DB que tiene MySQL y corre periódicamente la extracción y análisis de datos.
Los servidores fueron ambos desplegados con Ansible [18]

Un crisol de tecnologías libres que unidas generan una aplicación que funciona y cumple su objetivo, principalmente participaron de este proyecto Dos Desarrolladores(principalmente uno para Phonegap css html y js y otro para el Analisis de datos con PHP), un ProjectLeader, el CEO de Quicuo y un SysAdmin/Desarrollador Python (este soy yo).

[0] http://www.quiper.com.ar
[1] http://www.quicuo.com.ar
[2] http://phonegap.com/
[3] https://play.google.com/store/apps/details?id=com.quicuo.quiper
[4] http://nodejs.org/
[5] http://expressjs.com/
[6] http://sequelizejs.com/
[7] http://en.wikipedia.org/wiki/Object-relational_mapping
[8] http://www.mysql.com/
[9] https://www.python.org/
[10] http://www.crummy.com/software/BeautifulSoup/
[11] http://wwwsearch.sourceforge.net/mechanize/
[12] http://docs.python-requests.org/en/latest/
[13] http://sqlobject.org/
[14] http://php.net/
[15] https://github.com/Unitech/pm2
[16] http://nginx.org/
[17] http://aws.amazon.com/es/ec2/
[18] http://www.ansible.com/home

Gonzalo Martinez: Patrones de Diseño - Factory Method y Prototype

Factory Method

Proposito,

      Define una interfaz para crear un objeto, pero permite a las subclases decidir que clases instancia. Factory Method permite a una clase derivar la instanciación a las subclases.

Motivo

    Los Frameworks usan clases abstractas para definir y mantener relaciones entre objetos. Un framework es normalmente responsable por crear estos objetos.
Considerar un framework para aplicaciones que pueda presentar multiples documentos a el usuario. Dos abstracciones claves en este framework son las clases Aplicacion y Documento. Ambas clases son abstractas, y los clientes tienen las subclases de ellas para realizar la implementación especifica de la aplicación. Para crear una aplicación de dibujo, por ejemplo, nosotros definimos las clases DrawingApplication y DrawingDocument. la clase Application es responsable para manejar Documents y los creará como sea requerido - cuando el usuario selección Abrir o nuevo desde un menu, por ejemplo.

El patrón Factory Method ofrece una solución. Este encapsula el conocimiento de que subclase Document crear y mueve este conocimiento por fuera del Framework.

Aplicabilidad

     Usa el patrón Factory Method cuando,

  • Una clase no puede anticipar la clase del objeto que debe crear.
  • Una clase quiere que sus subclases especifiquen el objeto a crear.
  • Las clases delegan la responsabilidad a una o muchas subclases auxiliares, y tu deseas localizar el conocimiento de que subclase auxiliar es la delegada.
Participantes,
  • Product, define la interfaz de objetos que el Factory Method crea.
  • ConcreteProduct, implementa la interfaz de Product.
  • Creator, declara el Factory Method, que retorna un objeto de tipo Product. El creador también puede definir una implementación predeterminada de el Factory method que retorne un objeto ConcreteProduct predeterminado. Puede llamar al Factory Method para crear un objeto Product.
  • ConcreteCreator, sobreescribe el Factory Method para return una instancia de un ConcreteProduct.

Ejemplos de Factory Method en Python.
Estos son dos ejemplos más que interesantes. [0][1]

Prototype

Intento,
       Especificar los tipos de objetos a crear usando una instancia como prototipo. y crear nuevos objeto copiando este.

Motivación,

       Podrías construir un editor para partituras personalizando un framework general para editores gráficos, y agregando nuevos objetos que representen notas, silencios, y pentagramas. El Framework editor podría tener una paleta de herramientas para agregar estos objetos de música a la partitura. La paleta debería también incluir herramientas para seleccionar, mover y otro tipo de manipulación de objetos musicales. 

El framework provee un clase Graphics abstracta para los componentes gráficos, como son las notas y pentagramas. Provee una clase Tools para definir herramientas como esas en la paleta. El Framework también predefine un subclase Graphic-Tool para herramientas que crean instancias de objetos gráficos y agrega estos al documento.

Pero GraphicTool presenta un problema al diseñador del framework. Las clases para notas y pentagramas son especificas de nuestra aplicación, pero la clase GraphicTool pertence al framwork. GraphicTool no sabe como crear instancias de nuestras clases de musica para agregarlas a la partitura. Nosotros podríamos definir subclases de GraphicTool para cada tipo de objeto de música que instancia. Nosotros sabemos que la composición de objetos es una alternativa flexible al subclaseo. La pregunta es, como puede el framework usarlo para parametrizar instancias de GraphicTool por la clase de Graphic que se supone crear?.


La solución está en hacer que GraphicTool cree un nuevo Graphic copiando o "clonando" una instancia de una subclase de Graphic. Nosotros llamamos a esta instancia un prototipo. GraphicTool es parametrizado por el prototipo que debería clonar y agregar a el documento. Si toda Subclase de Graphic soporta una operación Clone, entonces la GraphicTool puede clonar cualquier tipo de Graphic.

Aplicabilidad,

     Usa el patrón Prototype cuando un sistema deberia ser independiente de como sus productos son creados, compestos y representados; and

  • Cuando las clases a instancia son especificadas en tiempo de  ejecución, por ejemplo, por carga dinámica, o
  • para evitar la construcción de una jerarquia de clases de Factories que sean paralelas a la jerarquia de clases de productos, o
  • cuando las instancias de una clase puedan tener una de solo unas pocas combinaciones diferentes de estado. Esta deberia ser más conveniente para instalar un número correspondiente de prototupos y clonarlos en lugar de instanciar la clase manualmente, cada vez con el estado apropiado.
Participantes
  • Prototype, declara una interfaz para clonarse a si mismo.
  • ConcretePrototype, implementa una operación para clonarse a si mismo.
  • Cliente, crea un nuevo objeto pidiendole a un prototipo que se clone a si mismo.
Ejemplos del Patron Prototype en Python que tiene hasta formas PreConstruidas para este fin.
[2] [3]

Marcos Dione: wrapping-return-by-reference-functions-with-SWIG

At MegaCorp I'm developing in C++, but the APIs are in C. From time to time, we use Python for scripting something using those APIs. We write the bindings in SWIG.

All the functions in the APIs return a status code; it can be OK or many different values for different type of errors. This means that if a function needs to return a value, it actually takes a pointer (not a reference)[1] to such a value and at the end of the function, depending on its success, the value is returned at that address.

Then came the question of wrapping such functions with SWIG. According to the scarce documentation about it one should declare the type (+name if needed) as argout and not much more... except for the first part of the example. See, what numinputs=0 is doing is to make SWIG ignore that type as argument[2], meaning that the wrapper function won't be expecting it. Even so, the body does something, and a very important something. Let's see in my example:

// ignore any input parameter of type PageSetHandle t *
%typemap(in, numinputs=0) PageSetHandle t *pPageSetHandle (PageSetHandle_t temp) {
    $1= &temp;
}

// on the other hand, this is how we convert a PageSetHandle t* to a PyCObject
// and add it to the list of returned values
%typemap(argout) PageSetHandle t * {
    $result= SWIG_Python_AppendOutput ($result, PyCObject_FromVoidPtr (*$1, NULL));
}

In my case the type is PageSetHandle_t. The fact that behind is an actual void * is not important[3], but that messed with my head while trying to understand the problem. What the first part is saying is «look, ignore any parameter of type PageSetHandle_t *, but when you find one, create a temporary variable of the dereferenced type (PageSetHandle_t, in this case), and assign a reference to it to the parameter you're going to pass to the C function». This is extremely important; otherwise, you wouldn't have an address where to store the reference returned by the function. Notice that that temporary variable will be declared in the wrapper's stack and will die when the wrapper finishes, but that's OK because of what we do in the actual conversion code: we create a PyCObject from the dereferencing of the parameter. Here's part of the generated code:

SWIGINTERN PyObject *_wrap_MFaST_PMCreatePageSet(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
  PageSetHandle t *arg3 = (PageSetHandle_t *) 0 ;
  PageSetHandle t temp3 ;

  {
    arg3= &temp3;
  }
  result = MFaST_PMCreatePageSet(arg1,arg2,arg3);
  resultobj = SWIG_NewPointerObj((new FqStatusCode_t(static_cast< const FqStatusCode t& >(result))), SWIGTYPE_p__FqStatusCode_, SWIG_POINTER_OWN |  0 );
  {
    resultobj= SWIG_Python_AppendOutput (resultobj, PyCObject_FromVoidPtr (*arg3, NULL));
  }
  return resultobj;
}

This means that now I can call pm.MFaST_PMCreatePageSet() with only two parameters instead of three, and that both the status and the returned value will be returned in a tuple. Notice again the variables generated by SWIG and how they interact in the body of the typemap(in) and specially in the typemap(argout), where you can't reference the temporary variable, which means you can only dereference the argument (*$1) instead of trying to use the tempvar (temp).


[1] That is, the parameter is declared as int *foo and not int &foo. I think this is a mistake.

[2] I understand what it means now that I saw it in effect. At the beginning it was not clear, mostly because the (int temp) part and the fact that it has code associated.

[3] Except for the part that I will use PyObject_FromVoidPtr() and PyObject_AsVoidPtr() to create Pyhton objects with such values.


python

Roberto Alsina: Nikola Logo Contest!

So you ha­ve de­sign ski­ll­s? Want to make a li­ttle mo­ney whi­le do­ing a good thin­g? ­Then jo­in the con­tes­t! the­re is a 200 US do­llars gua­ran­teed pri­ze, and the con­test wi­ll be ju­dged by a group of Niko­la de­ve­lo­per­s.

So­me gui­dan­ce:

  • The na­me Niko­la co­mes from Niko­la Tes­la, so thi­nk con­cep­ts con­nec­ted to that
    • The Wa­r­­den­­cl­­y­­ffe to­­wer
    • Tes­­la Coils
    • Li­­gh­­tning
    • Ele­c­­tri­­ci­­ty
    • Ea­r­­ly 20­­th cen­­tu­­ry
  • I ho­pe the lo­go wo­rks we­ll in a va­rie­ty of for­ma­ts so, keep it sim­ple. B/W is good.
  • A drawing wi­thout the word Niko­la is good, but a good de­sign wi­th the word in it ­could be good al­so.

The con­test las­ts a week, you ha­ve 4 da­ys for the qua­li­fying roun­d.

And re­mem­be­r: it has to be be­tter than the­se

Gonzalo Martinez: Por que todavia no hay un PaaS en Argentina?

Es necesario que haya un PaaS en Argentina? Hay mercado? que tan buenos son los proveedores que hoy ofrecen algo parecido al IaaS o simplemente VPSs?

Este post va a ser simplemente una opinión y está por consiguiente cargado por mi vagaje, de creencias y/o de ideologia.

Amazon y RackSpace son enormes y son los que hoy se llevan todos los aplausos cuando se habla de IaaS [0] Son empresas que han innovado un montón. Amazon pasó de ser un enorme E-Commerce de libros, a una enorme empresa basada en lo último sobre redes, servidores y servicios de IT. RackSpace tiene otra historia pero hoy son dos de las más grandes y tienen varias ventajas con empresas nacionales razones obvias son que todo el hardware, redes, conexión a la red de internet y todo lo que es "VITAL" se comercializa en la misma moneda de su país de origen (eso obviamente no le quita todos los méritos de innovación o de masividad que han generado) pero si les dá una ventaja enorme por sobre cualquier otra empresa local que quiera hacer algo parecido. Hay desarrolladores y buenos ingenieros en argentina? Sin lugar a dudas dense una vuelta por los videos de PyConAr del año pasado[1] y verán un "¿montón de gente?" que hace cosas y que ama lo que hace. Nos faltan ingenieros lo sé, pero a ellos también les falta sino entren a sus Webs y verán que todas estás empresas tienen varios puestos abiertos alrededor del mundo de manera constante. Pero bueno yo creo que su principal ventaja es tener dos cosas una el monopolio de la moneda que ellos mismos imprimen y dos una cultura del esfuerzo y de la creencia firme de que se puede ser de los grandes [2]. Incluso esa idea es tan fuerte que atrae más a los inmigrantes que a los estadounidenses mismos. (Como aquello que cuando lo tenés muy cerca hace tanto ruido que te ensordece pero que desde la lejania te suena bien)

Sin IaaS no hay PaaS? Y básicamente no, por que PaaS es una capa de servicios más por encima de IaaS, conozco o veo buscando por internet muchas empresas de las nuestras que ofrecen todavia Hostings PHP/ASP+ MySQL y esas cosas que son viejisimas. El rango se reduce cuando buscás alguna que ofrezca VPS (ni hablar de los costos o rendimiento)  y el rango es casi nulo cuando se busca directamente infraestructura. Algunas empresas de las grandes (Telecom/IPLAN) seguramente ofrecen algo más parecido al IaaS a empresas grandes pero no hay nada para la otra gran parte del universo del mercado que son las pujantes pero grandes inversoras locales PyMes. Una PyMe o una StartUp técnologica hoy viendo costos no duda en pagar los dolares con su tarjeta más impuestos antes de poner su innovación dorada en los servidoruchos de muchos de los Hostings Locales. Sin ir más lejos "ElServer.com" todavía no puede estabilizar su servicio de correos que siempre anduvo muy mal y estamos hablando de correo no de OpenStack.

Puede haber mercado en la Argentina para esto? No lo sé. Acaso Amazon hizo un analisis de mercado o vió que podía hacerlo y lo hizo? Acaso la gente de Facebook antes de viralizarse se sentó y diagramó un gran plan comercial para ver si se podía o era fáctible ellos hicieron algo mejor algo mucho mejor. Hicieron Algo y ellos mismos construyeron a su alrededor la demanda.

Para finalizar por que no hay PaaS? No hay por que no hay IaaS y no hay IaaS por que todos los servidores, switches, caños de conexión a internet vienen envasados en "dolares". Software para hacerlo no nos falta por que hay miles de muestras opensorce esperando a ser forkeadas OpenStack, OpenNebula, CloudStack, Docker, lxc, Debian, Ubuntu, Fedora, CentOs, Dokku, y cientos de personas o empresas que han compartido un pedazo de su conocimiento.

En fin, yo quiero un PaaS que pueda pagar en pesos. Una locura tal vez? Pero una firme creencia de que llegará.

[0] http://en.wikipedia.org/wiki/Infrastructure_as_a_service#Infrastructure_as_a_service_.28IaaS.29
[1] http://www.youtube.com/results?search_query=PyConAr%202013&sm=3
[2] http://es.wikipedia.org/wiki/Sue%C3%B1o_americano

Gonzalo Martinez: Patrones de Diseño - Builder

Builder

Objetivo, Separa la construcción de un objeto complejo de su representación de modo que el mismo proceso de construcción puede crear diferentes representaciones.

Motivo:

Un lector para el formato de intercambio de documentos RTF (Rich Text Format) debería ser capaz de convertir RTF a muchos formato de texto. El lector puede convertir documentos RTF en texto plano ASCII o en un Widget de texto que pueden ser editados interactivamente. El problema, sin embargo, es que el número de conversiones posible es abierto. Por lo tanto, debe ser fácil de añadir una nueva conversión sin modificar el lector.

Aplicabilidad

Usar el patrón Builder cuando:

  • El algoritmo para crear un objeto complejo deber ser independiente de las partes que conforman el objeto y como están ensambladas.
  • El proceso de construcción debe permitir diferentes representaciones para el objeto que es construido.
Participantes

Builder,
- especifica una interfaz abstracta para crear partes de un objeto Product.
ConcreteBuilder
- construye y ensambla partes del productopara implementar la interfaz Builder.
- define y mantiene un seguimiento de la representación que crea.
- provee una interfaz para obtener el producto
Director
- construye un objeto usando la interfaz del Builder.
Product
- representa el objeto complejo en construcción. El ConcreteBuilder construye la representación interna del producto y define el procesos por el cual este es ensamblado.
- incluye clases que definen las partes constituyentes, inclyendo interfaces para ensamblar las partes en el resultado final.

Ejemplos de Código [0] [1]

La diferencia entre el Builder y el Abstract Factory
La principal diferencia es que el Builder se enfoca en construir un objeto complejo paso a paso. El Abstract Factory hace incapié en la familia de objetos producto (ya sea sencilla o compleja). El Builder retorna el producto como un paso final, pero en cuanto al Abstract Factory el producto es retornado inmediatamente.


[0] http://es.wikipedia.org/wiki/Builder_(patr%C3%B3n_de_dise%C3%B1o)
[1] http://tratandodeentenderlo.blogspot.com.ar/2010/02/patrones-de-diseno-builder.html

Gonzalo Martinez: Patrones de Diseño Creacionales - Abstract Factory

Los patrones de diseño creacionales son aquellos que abstraen el proceso de instanciación. Ellos ayudan a hacer un sistema independiente de como sus objetos son creados, compuestos, y representados. Una patrón creacional de clase usa herencia para variar la clase que es instanciada, mientras un patron creacional de objeto delegará la instanciación a otro objeto.

Los patrones creacionales se vuelven importantes en sistemas que pasan a depender más de la composición de objetos que de la herencia de clases. Como eso sucede, el enfasis cambia de modificar dificilmente un conjunto fijo de comportamientos hacia definir un conjunto pequeño de comportamientos fundamentales que pueden ser compuestos dentro de cualquier numero de los más complejos. Creando así objetos con un comportamiento particular que requiere más que simplemente instanciar una clase.

Abstract Factory

Intenta:
proveer una interfaz para la creación de familias objetos relacionados o dependientes sin especificar sus clases concretas.

Aplicación:

  • Un sistema debería ser independiente de como sus productos son creados, compuestos, y representados.
  • Un sistema debería ser configurado con una de múltiples familias de productos.
  • Una familia de objetos producto relacionados es diseñada para ser usados juntos y necestás hacer cumplir esta restricción.
  • Buscás proveer una biblioteca de clases de productos, y buscas revelar solo sus interfaces, no su implementación.
Participantes:
  • Abstract Factory - declara una interfaz para operaciones que crean objetos producto abstractos.
  • ConcreteFactory - implementa las operaciones para crear objetos producto concretos.
  • AbstractProduct - declara una interfaz para un tipo de objeto producto.
  • ConcreteProduct - define un producto objeto para ser creado por el correspondiente Concrete Factory. - implementa la interfaz del AbstractProduct.
  • Client - usa solo las interfaces declaradas por las clases AbstractFactory y AbstractProduct
Ejemplos de Abstract Factory en Python
[0][1][2]

[0] http://python-3-patterns-idioms-test.readthedocs.org/en/latest/Factory.html#abstract-factories
[1] http://ginstrom.com/scribbles/2007/10/08/design-patterns-python-style/
[2] http://jpython.blogspot.com.ar/2012/09/python-design-pattern-abstract-factory.html




Gonzalo Martinez: Aprendiendo Erlang parte 6 Modulos I

Los módulos son un grupo de funciones reagrupadas en un solo archivo, bajo un nombre. Adicionalmente todas las funciones en erlang deben ser definidas en módulos. Ya has usado modulas tal vez sin darte cuenta. Las BIFs (Built-In Functions) mencionadas en el capitulo anterior hd o tl, en realidad pertenecen al módulo erlang, así como toda la aritmética. lógica u operadores booleanos. Los BIFs del módulo erlang difieren de otros módulos en que son automaticamente importados cuando usas Erlang. Cada una de las otras funciones definidas en un modulo que uses debe ser llamada con la forma Modulo:Funcion(Argumentos).

Lo podés ver por vos mismo:

1> erlang:element(2, {a,b,c}).
b
2> element(2,{a,b,c}).
b
3> lists:seq(1,4).
[1,2,3,4]
4> seq(1,4).
** exception error: undefined shell command seq/2

Aquí la función seq  del modulo lists no fue automáticamente importada mientras que element si lo fue. El error 'undefined shell command' viene desde la shell buscando por un comando shell como f() y no es capaz de encontrarlo. Hay algunas funciones del modulo erlang que no se importan automáticamente, pero tampoco son muy usadas.

Lógicamente, deberías ponet funciones similares dentro de un mismo modulo. Las operaciones comunes sobre listas son mantenidas dentro del modulo lists, mientras que las funciones de entrada y salida (como escribir en una terminal o en un archivo) son agrupadas en el modulo io. Uno de los únicos módulos que no respeta ese patrón es el antes mencionado modulo erlang que tiene funciones de matemática, conversiones, trabajar con multiprocesamiento, o jugar con la configuración de la máquina virtual, etc. Ellos no tienen ningún punto en común solo que son funciones previamente construidas (BIFs). Tu deberías evitar crear módulos como erlang y en su lugar enfocarse en separaciones lógicas limpias.

Declaraciones de Módulos

Cuando escribimos módulos, tu puedes declarar dos tipos de cosas: funciones y atributos. Los atributos son metadatos que describen el módulo en si mismo como es su nombre, las funciones que deberían ser visibles a el mundo exterior, el autor del código y así sucesivamente. Este tipo de metadatos es útil porque le dá indicaciones al compilador sobre como debe hacer su trabajo y también por que este permite a la gente obtener información útil sobre el código compilado sin tener que consultar las fuentes.

Hay una gran variedad de atributos de módulos actualmente usados en el código de Erlang a través del mundo, de hecho, podes incluso declarar tus propios atributos para lo que quieras. Hay algunos atributos predefinidos que aparecerán más frecuentemente que otros en tu código. Todos los atributos de módulo siguen la forma de -Nombre(Atributo).. Solo uno de ellos es necesario para que tu módulo sea compilable.

-module(Nombre).
Este es siempre el primer atributo (y declaración) de un archivo y por una buena razón: este es el nombre del módulo actual, donde el nombre es un atomo. Este es el nombre que usarás para llamar a funciones de otros módulos. Las llamadas son hechas con la forma M:F(A) donde M es el nombre del módulo, F la función, y A los argumentos.
Es hora de escribir código! Nuestro primer módulo será muy simple y poco útil. Abrí tu editor de texto y escribe lo siguiente, y guárdalo baje el nombre userless.erl

-module(useless).

Esta linea de texto es un módulo válido. Realmente! Por supuesto que esto es muy poco útil. Primero vamos a decidir que funciones vamos a exportar de nuestro módulo 'useless'. Para hacer esto, usaremos otro atributo.

-export([Funcion1/Aridad, Funcion2/Aridad, ..., FuncionN/Aridad]).Este es usado para definir que funciones de un módulo puede ser llamadas  desde el mundo exterior. Este toma una lista de funciones con su respectiva aridad. La aridad de una función es un entero que representa cuantos argumentos pueden ser pasados a la función. Esta es una información critica, por que diferentes funciones definidas dentro de un módulo pueden compartir el mismo nombre si y solo sí ellas tienen aridad diferente. Las funciones add(X,Y) y add(X,Y,Z), por lo tanto deberían ser consideradas diferentes y escritas en la forma add/2 y add/3 respectivamente.
Nuestro modulo useless exportará una función útil llamada 'add' que tomará dos argumentos. El siguiente atributo -export puede ser agregado después de la declaración del módulo.

-export([add/2]).

y ahora escribir la función

add(A,B) ->
    A + B.

La sintaxis de una función sigue la forma Nombre(Argumentos) -> Cuerpo. donde el Nombre tiene que ser un átomo y el Cuerpo puede ser uno o más Expresiones Erlang separada por comas.La función finaliza con un punto. Nota que erlang no utiliza la palabra clave 'return' . 'Return' es inutil. En su lugar, la última expresión lógica de una función a ejecutar tendrá su valor retornado al llamador automaticamente sin tener que mencionarlo.

Agrega la siguiente función (por que sí, todo tutorial necesita su ejemplo "Hola Mundo" Incluso en su cuarto cápitulo!)  sin olvidar agregar el atributo -export

%% Mostrar Saludo.
%% io:format/1 es una función estándar para salida de texto.
hello() ->
    io:format("Hola Mundo!~n").

Lo que se observa en esta función es que los comentarios son de una sola línea y comienzan con un signo % (se utiliza %% simplemente como una cuestión de estilo). La función  hello/0 demuestra como llamar funciones de otros módulos dentro de tu módulo. En este caso io:format/1 es la función estándar para escribir texto en pantalla como es escrito en el comentario.

[0] http://es.wikipedia.org/wiki/Aridad