(Spanish) PyCon Argentina 2012 - Design Patterns en Python
Herramientas que ofrece Python para solucionar problemas utilizando las herramientas dinámicas que el lenguaje nos provee
Ejemplos en http://github.com/dlitvakb/charla_patterns
en tiempo de compilación • Referencias tipadas • Objetos con interfaces inmutables Tipado dinámico • El tipo a través del uso y no de su definición • Una referencia como nombre a un objeto y no contiene informacion de tipo • La interfaz del objeto puede mutar y enriquecerse
contratos vs duck-typing El duck-typing define que un objeto es de un tipo si sabe responder a los mensajes esperados. Ej: Si se ve como un pato, come como un pato, nada como un pato y hace cuak, entonces es un pato.
y Clases como objetos de primer nivel • Métodos Mágicos ◦ Interceptores ◦ Implementores ◦ Introspección ◦ Constructores • Contextos • Herencia Múltiple
problemas cuyas soluciones tienen algo en común, al analizarlo, nos damos cuenta que si bien todas las soluciones son diferentes, utilizan estrategias similares para resolver dicha problemática. Entonces, los patrones de diseño, son generalizaciones a soluciones para problemas comunes en el diseño de sistemas. Para explicar los patrones vamos a mencionar 4 puntos clave: • Problema que resuelve • Uso tradicional • Aplicabilidad • Implementación ejemplo
la interacción entre los objetos del sistema • Comportamiento ◦ Relacionados con el comportamiento que permiten lograr • Creacionales ◦ Relacionados con la instanciación (o no) de nuevos objetos en el sistema
Adapter como el Facade son patrones utilizados para normalizar las interfaces de los objetos del sistema, por lo general adaptando interfaces de sistemas externos a interfaces amigables para nuestro sistema y viceversa. Su uso tradicional, es a través de crear subclases de los objetos que intentamos adaptar e implementar las interfaces de nuestro sistema haciendo uso de su interfaz. Estos patrones son aplicables cuando necesitamos interactuar con sistemas legacy o servicios externos Ejemplo: patrones/estructurales/adapter_facade.py
patrón utilizado para intermediar de forma transparente con un objeto sobre el cual queremos realizar operaciones fuera de su comportamiento normal, sin afectar su actual comportamiento. Su uso tradicional, es a través de la composición de objetos. Es aplicable cuando queremos mediar sobre el comportamiento de un objeto. Por ejemplo loggear todas las llamadas a un método determinado, o cachear todos las llamadas a una base de datos. Ejemplo: patrones/estructurales/proxy.py
es un patrón que sirve para crear distintas familias de objetos enmascarando la clase actual real del objeto Su uso tradicional es a través de la instanciación de clases que heredan de una misma clase padre y respetan una interfaz en común, y dicha instanciación se realiza a través de un método estático en la clase padre Es aplicable cuando tenemos distintas opciones elegibles para la instanciación de determinado tipo de objetos, pero por la configuración de dicho objeto solo una es aplicable. Por ejemplo la creación del objeto DB en SQLAlchemy. Ejemplo: patrones/creacionales/abstract_factory.py
comunmente usado para lograr que un objeto sea iterable como si fuera una colección. Su uso típico es a través de la implementación de una interfaz Iterable, dejando muchas limitaciones con respecto a las posibilidades que un iterable real permite Su aplicabilidad es para casos en los cuales no quiero tener que exponer la estructura interna de un objeto y simplemente iterar sobre el contenido del mismo Ejemplo: patrones/comportamiento/iterator.py
guardar los estados previos de los objetos, para de esta forma poder movernos entre los distintos estados del objeto a través del tiempo. Su uso tradicional es a través de distintas capas de persistencia en el modelo de objetos, ya sea esta persistencia en memoria o en una base de datos. El memento es muy útil en casos como un historial de navegación, una repetición de un juego o un repositorio de los últimos cambios en un editor de texto. Ejemplo: patrones/comportamiento/memento.py
usado para monitorear el estado de un sistema a través del uso de eventos. En el mismo hay 2 participantes el Observador y el Observado. Su uso tradicional es mediante el paso de mensajes de tipo Evento, los cuales tienen un callback asociado. Los observados deben registrarse a los observadores. Este patrón es aplicado para programación orientada a eventos, muy utilizada en programación gráfica. Por ejemplo, un formulario lanza un evento al cliquear en un botón, lo cual hace que el sistema ejecute un callback. Ejemplo: patrones/comportamiento/observer.py
Strategy son patrones que permiten modificar el comportamiento de un objeto en tiempo de ejecución, en el caso del State para representar distintos estados de un objeto y el Strategy permite cambiar los algoritmos que se ejecutan para una acción específica. Su uso tradicional a través de composición de objetos que tienen una interfaz determinada para modelar dicho comportamiento. Su aplicabilidad es muy utilizada en la representación de objetos (reales o abstractos) que mutan en determinadas condiciones, por ejemplo una Persona se comporta distinto cuando es un niño a cuando es un adulto Ejemplo: patrones/comportamiento/state_strategy.py
poderoso para realizar tareas muy difíciles de forma simple, lo cual nos permite acercarnos a problemas que pueden resultar muy complicados en otras tecnologías de formas interesantes e innovadoras. Python nos abre las puertas a la imaginación