¿Qué queda igual? ¿Que cambios?
Los patrones son los mismos. Las técnicas del lenguaje cambian.
¿Existen principios rectores como SOLID,
Si. De hecho, siguen siendo los principios rectores. Nada cambia.
o patrones canónicos (quizás completamente nuevos) que un principiante de lenguaje dinámico debería saber?
Algunas cosas son únicas. Principalmente el impacto es que las técnicas de implementación cambian.
Un patrón es, bueno, un patrón . No es una ley No es una subrutina. No es una macro Es solo una buena idea que se repite porque es una buena idea.
Las buenas ideas no pasan de moda ni cambian dramáticamente.
Otras notas. Python no está "débilmente escrito". Está más fuertemente tipado que Java o C ++ porque no hay operación de conversión. [Sí, hay una manera de eludir la clase asociada con un objeto, pero no es el tipo de cosa que se hace excepto para demostrar un punto exigente y legalista.]
También. La mayoría de los patrones de diseño se basan en diferentes formas de explotar el polimorfismo.
Mire el estado o comando o recuerdo como ejemplos. Tienen jerarquías de clase para crear estados polimórficos, comandos o recuerdos de cambios de estado. Nada cambia significativamente cuando haces esto en Python. Los cambios menores incluyen la relajación de la jerarquía de clases precisa porque el polimorfismo en Python depende de métodos comunes, no de antepasados comunes.
Además, algunos patrones son simplemente un intento de lograr una unión tardía. La mayoría de los patrones relacionados con la fábrica son un intento de permitir un cambio fácil a una jerarquía de clases sin recompilar todos los módulos de C ++ en la aplicación. Esta no es una optimización tan interesante en un lenguaje dinámico. Sin embargo, una Fábrica como una forma de ocultar detalles de implementación todavía tiene un gran valor.
Algunos patrones son un intento de conducir el compilador y el enlazador. Singleton , por ejemplo, existe para crear globales confusos pero al menos encapsularlos. Las clases de Python Singleton no son una perspectiva agradable. Pero los módulos de Python ya son singletons, por lo que muchos de nosotros solo usamos un módulo y evitamos tratar de meternos con una clase Singleton .
Peter Norvig asumió esta misma pregunta en 1998, lea http://norvig.com/design-patterns/ppframe.htm para obtener un conjunto de cosas detalladas que notó, y http://c2.com/cgi/wiki?AreDesignPatternsMissingLanguageFeatures para discusión adicional sobre el punto.
La versión corta es que cuando su idioma tiene más funciones, los patrones de diseño repetitivos tienden a ser más simples, a menudo hasta el punto de ser invisibles. Descubrió que esto era cierto para la mayoría de los patrones de diseño que el GoF había identificado.
fuente
La programación en un lenguaje dinámico orientado a objetos utiliza muchos de los mismos patrones y principios, pero existen ciertos ajustes y diferencias debido al entorno:
Reemplace las interfaces con Duck Typing : donde Gang of Four le indicaría que use una clase base abstracta con funciones virtuales puras, y usaría una interfaz en Java, en un lenguaje dinámico, solo necesita una comprensión. Dado que puede usar cualquier objeto en cualquier lugar, y funcionará bien si implementa los métodos que realmente se llaman, no necesita definir una interfaz formal. Puede valer la pena documentar uno, para que quede claro lo que realmente se requiere.
Las funciones también son objetos : hay muchos patrones que tratan de separar la decisión de la acción; Comando, estrategia, cadena de responsabilidad, etc. En un lenguaje con funciones de primera clase, a menudo es razonable simplemente pasar una función en lugar de crear objetos con
.doIt()
métodos. Estos patrones se transforman en "usar una función de orden superior".VENDIDO : el principio de segregación de interfaz tiene el mayor éxito aquí, debido a que no hay interfaces. Aún debe considerar el principio, pero no puede volver a clasificarlo en su código. Solo la vigilancia personal lo protegerá aquí. En el lado positivo, el dolor causado por violar este principio se reduce mucho en entornos dinámicos comunes.
"... en mi propio Particular ... ¡Idioma!" - Cada idioma tiene buenas prácticas y malas prácticas, y tendrá que aprenderlas y seguirlas, si desea el mejor código en esos idiomas. Un patrón iterador perfectamente escrito puede reírse en un lenguaje con comprensiones de listas incorporadas, por ejemplo.
fuente
En mi experiencia, algunos patrones siguen siendo útiles en Python, e incluso más fáciles de configurar que en lenguajes más estáticos. Algunos patrones OTOH simplemente no son necesarios, o incluso mal vistos, como el patrón Singleton. Utilice una variable o función de nivel de módulo en su lugar. O usa el patrón Borg.
En lugar de configurar un patrón de creación, a menudo es suficiente pasar un invocable que crea objetos. Esa podría ser una función, un objeto con un
__call__
método o incluso una clase, ya que no haynew()
en Python, solo una invocación de la clase en sí:El patrón de estado y estrategia comparte una estructura muy similar en lenguajes como C ++ y Java. Menos en Python. El patrón de estrategia permanece más o menos igual, pero el patrón de estado se vuelve innecesario. El patrón de estado en lenguajes estáticos simula el cambio de clase en tiempo de ejecución. En Python, puede hacer exactamente eso: cambiar la clase de un objeto en tiempo de ejecución. Mientras lo haga de forma controlada y encapsulada, debería estar bien:
Los patrones que dependen del Despacho de tipo estático no funcionarán, o funcionarán de manera muy diferente. No tiene que escribir tanto código de placa de caldera, por ejemplo, Patrón de visitante: en Java y C ++ debe escribir un método de aceptación en cada clase visitable, mientras que en Python puede heredar esa funcionalidad a través de una clase mixin, como Visitable:
Muchas situaciones que requieren la aplicación de un Patrón en un lenguaje estático no lo hacen tanto en Python. Muchas cosas se pueden resolver con otras técnicas, como funciones de orden superior (decoradores, fábricas de funciones) o metaclases.
fuente
__class__
para implementar una fábrica en Python ?