¿Hay patrones de diseño innecesarios en lenguajes dinámicos como Python?

98

Empecé a leer el libro de patrones de diseño de GoF. Algunos patrones parecen muy similares con solo diferencias conceptuales menores.

¿Crees que de los muchos patrones algunos son innecesarios en un lenguaje dinámico como Python (por ejemplo, porque están sustituidos por una característica dinámica)?

Gerenuk
fuente
1
Una especie de pregunta interesante, ya que implica que la elección del idioma puede sustituir efectivamente a las construcciones de código.
joshin4colours
3
No es una respuesta, pero es relevante: pensé que los patrones de diseño de GoF eran tan relevantes para algunos principios generales que se pueden extraer de ellos como para los patrones específicos. No me refiero a la idea de un patrón (aunque eso es ciertamente significativo), sino más bien al permiso para usar las clases de ciertas maneras que violan los principios ingenuos de OOP. Por ejemplo, hay muchos patrones en los que "la forma" claramente no se "dibuja a sí misma", o al menos delega algún aspecto del trabajo en otro objeto. Creo que esa lección es importante en cualquier idioma que admita OOP.
Steve314
Pregunta muy interesante Desearía poder +5 en lugar de +1.
MathAttack
1
Eche un vistazo también a Are Patrones de diseño que faltan características del lenguaje y Patrones de diseño que faltan características del lenguaje en c2. Ni siquiera es un problema de "lenguaje dinámico". El ejemplo más simple es el patrón iterador que es trivial en python, perl (e incluso Java, no dinámico).

Respuestas:

92

Peter Norvig demuestra que 16 de los 23 patrones de diseño encontrados en el libro GOF son invisibles o más simples en lenguajes dinámicos (se enfoca en Lisp y Dylan).

Desde que mencionó Python, hay una buena presentación de Alex Martelli sobre el tema. También relacionado con Python, hay una buena publicación de blog que muestra seis patrones de diseño en Python idiomático .

También mantengo un repositorio de github con implementaciones (por otras personas) de los patrones de diseño más comunes en Python .

sakisk
fuente
¡Excelente! Esa sería una respuesta correcta :) Desearía que todos hubieran comprendido la pregunta con claridad.
Gerenuk
2
Según Norvig, 2 de los 16 (intérprete e iterador) son "invisibles o más simples" debido a las macros (que Python no tiene).
mjs
1
no está claro para mí que todos estos patrones no sean necesarios porque lisp es dinámico, sino más bien por otras características, como ser un lenguaje funcional fuerte
jk.
Los iteradores @mjs son una característica integrada de Python.
sakisk
1
Esta gran respuesta puede ser incluso ligeramente mejorar cambiando los títulos de enlace algo sin sentido demuestra , presentación y depósito - que son mucho mejor que aquí , pero, ya sabes ... :-)
Lobo
59

No se necesitan patrones de diseño. En cualquier idioma.

Tiendo a encontrar un montón de código escrito por personas que leen sobre patrones de diseño y luego piensan que deberían usarlos por todas partes. El resultado es que el código real queda enterrado bajo toneladas de interfaces, envoltorios y capas y es bastante difícil de leer. Ese es un enfoque incorrecto para los patrones de diseño.

Existen patrones de diseño para que tenga un repertorio de expresiones idiomáticas útiles a mano cuando se encuentre con un problema. Pero nunca debe aplicar ningún patrón antes de identificar el problema. Keep It Simple Stupid siempre debe ser el principio superior de gobierno.

También ayuda pensar en los patrones de diseño como un concepto para pensar sobre el problema en lugar de un código específico para escribir. Y sobre gran parte de la plantilla como solución alternativa a Java que carece de funciones gratuitas y objetos de función estándar que usa en la mayoría de los otros lenguajes que los tienen (como Python, C #, C ++, etc.).

Podría decir que tengo un patrón de visitante, pero en cualquier idioma con funciones de primera clase, será solo una función que toma una función. En lugar de la clase de fábrica, generalmente solo tengo una función de fábrica. Podría decir que tengo una interfaz, pero solo son un par de métodos marcados con comentarios, porque no habría ninguna otra implementación (por supuesto, en Python una interfaz siempre es solo comentarios, porque es de tipo pato). Todavía hablo del código como el uso del patrón, porque es una forma útil de pensarlo, pero en realidad no escribo todo hasta que realmente lo necesito.

Así que aprende todos los patrones como conceptos . Y olvida las implementaciones específicas. La implementación varía, y debería variar, en el mundo real, incluso solo en Java.

Jan Hudec
fuente
28
Su declaración de apertura está simplificando demasiado al extremo. Es cierto que los patrones tienen su costo, por lo que no deben usarse a ciegas, solo por el simple hecho de hacerlo. Pero en el lugar correcto, pueden ser de gran ayuda. Y sí, son específicos del idioma: algunos patrones son innecesarios en algunos idiomas porque el idioma en sí admite un mejor enfoque. Pero eso todavía está bastante lejos de su reclamo inicial.
Péter Török
2
Btw Visitor no se reemplaza por completo por funciones de orden superior: es una solución para implementar el envío doble en un lenguaje que no lo admite de forma nativa (como C # y C ++). (Y de hecho se debe utilizar con moderación - Considero que es uno de los patrones más misteriosos y costosos cuyo uso es mi humilde opinión tan difícil de justificar que yo nunca he usado hasta ahora.)
Péter Török
14
Bueno, nunca necesitas un patrón. Lo que necesitas es resolver un problema . Si no conoce ningún patrón para ello, aún puede resolverlo, requerirá más reflexión y puede encontrar una solución que coincida con algún patrón o uno que no lo haga. Conocer los patrones simplemente lo hace más fácil.
Jan Hudec
3
@Gerenuk: Sí, pero el punto es que los patrones no son específicos del idioma, son para tu cabeza. A menudo encuentra que algunos patrones se realizan mucho más fácilmente y usando diferentes herramientas en Python, pero generalmente existe el mismo concepto.
Jan Hudec
44
@ PéterTörök: el visitante no se reemplaza por nada. El punto es que el mismo concepto podría implementarse usando diferentes herramientas en diferentes casos, pero todavía lo considero el mismo patrón.
Jan Hudec
13

El patrón de fábrica abstracto no es necesario en un lenguaje de tipo pato como Python, ya que está prácticamente integrado en el lenguaje.

vartec
fuente
10
bueno, todavía necesitas diferentes fábricas. Simplemente no necesita la definición de interfaz.
Stefano Borini
1
Si tienes una clase, ya tienes una fábrica. Las clases son objetos de primera clase y pueden pasarse a todas partes y simplemente llamarse para crear un objeto (a diferencia de Java). No necesitas crear nada más. Si desea algo que no sea el constructor predeterminado, simplemente cree un lambda / invocable de algún tipo que envuelva el constructor de alguna manera.
spookylukey
13

El único que viene a la mente es el patrón Singleton.

Dado que Python no te obliga a usar clases para todo , solo puedes usar una estructura de datos global. Esa estructura de datos global podría ser administrada por una instancia, pero no tiene que controlar la creación de instancias de esa clase, solo crea la instancia en la importación y la deja así.

En su mayoría, Singletons en python se reemplazan con un módulo. Los módulos en python son, por su propia naturaleza, Singletons; el intérprete de python crea estos una sola vez.

Todos los demás patrones en Patrones de diseño que he usado en Python en un momento u otro, y encontrará ejemplos de ellos en toda la biblioteca estándar de Python y en el propio Python.

Martijn Pieters
fuente
2
¿No es eso realmente un antipatrón en estos días?
Den
16
El Singleton es un antipatrón . En todos los idiomas Fue creado para resolver varios problemas no relacionados y no es una buena combinación para ninguno (tenga en cuenta que incluso Java tiene miembros estáticos, que existen una vez por clase, por lo que no necesita una instancia para eso).
Jan Hudec
1
Y en Python nunca nos molestamos porque nunca hubo un problema que resolver.
Martijn Pieters
1
"Python no te obliga a usar objetos para todo" No es cierto. Simplemente no es desagradable como en Java, pero aún así, en Python todo es un objeto. Incluso el módulo es un objeto.
vartec
3
@Darthfett: Soy muy consciente de cómo lenfunciona; Guido hizo una elección explícita aquí . Mi punto es mostrar que Python no es un lenguaje POO puro; Es un lenguaje pragmático. Me gusta de esa forma.
Martijn Pieters
8

Los patrones de diseño son para el programador, no para el lenguaje. Los programadores tienden a usar patrones que les ayudan a dar sentido al problema en cuestión. Ningún patrón de diseño es estrictamente necesario, pero puede ser útil para simplificar lo que está tratando de hacer.

Python, y el tipeo de pato específicamente, proporciona un fin en torno a muchos patrones y prácticas comunes, y muchas de las restricciones impuestas por algunos patrones (privacidad, inmutabilidad, etc.) solo se mantienen en la medida en que el programador acepta no romperlos. . Pero aún así, ellos no trabajan todo el tiempo que el programador le sigue el juego. Una puerta sigue siendo una puerta, incluso si está enmarcada por paredes imaginarias.

Python se considera un lenguaje "multi-paradigma"; puedes usar los patrones que quieras. Esto es intencional Proporciona jerarquías de clase complejas, por ejemplo, a pesar de que son completamente innecesarias y un poco artificiales. Pero para algunas personas esa abstracción particular es útil. No porque el problema lo exija, sino porque el programador sí. Ahí vas.

tylerl
fuente
Eso es ciertamente interesante. Entonces, ¿qué patrones en particular quiere decir que uno podría olvidar, porque hay mejores formas en Python?
Gerenuk
4

El libro original de "Patrones de diseño" documentó y nombró algunos modismos comunes útiles en lenguajes orientados a objetos imperativos como C ++ y Smalltalk. Pero Smalltalk es un lenguaje de tipo dinámico, por lo que no puede ser estrictamente una cuestión de ser dinámico.

Sin embargo, la respuesta a su pregunta sigue siendo "sí": algunos de estos patrones de diseño serán irrelevantes para los lenguajes modernos de tipo dinámico. En términos más generales, habrá diferentes patrones de diseño en diferentes idiomas, especialmente en diferentes tipos de idiomas.

Para reiterar: un "patrón de diseño" es simplemente un nombre para un lenguaje de programación: una solución común a un problema frecuente. Diferentes idiomas requieren diferentes modismos, porque lo que es un problema para un idioma puede ser trivial para otro. En este sentido, los patrones de diseño tienden a señalar debilidades en los idiomas a los que se aplican.

Por lo tanto, puede buscar otras características que hagan que los lenguajes dinámicos modernos (o los antiguos como Lisp) sean más potentes, lo que hace que algunos de estos patrones de diseño clásicos sean irrelevantes.

tormenta
fuente
1

Los patrones de diseño son formas de resolver problemas particulares. Si no se resuelve un problema, no sirve de nada el patrón para resolverlo.

La gente está tratando de adaptar patrones de diseño en todas partes como si fuera una buena práctica tener patrones de diseño en su proyecto. Eso es al revés. ¿Se encuentra con un problema que se puede resolver con un patrón de fábrica? Bueno. Adaptarlo. No busque su código e intente encontrar el lugar correcto para implementar un singleton (o fábrica, o fachada, o lo que sea ...).

¿Quizás Python tiene sus propios patrones de diseño que no están disponibles para las personas Java y .NET (debido a la naturaleza de estos lenguajes)?

Andrzej Bobak
fuente
1

Yo diría que los patrones siempre dependen del idioma. El hecho de que la mayoría de los patrones de Python se parezcan a los definidos en GoF se debe a la OOP de Python, ya que dicho OOP no es como la OOP (no hay dos lenguajes que definan los objetos y su manipulación sea 100% similar).

Por lo tanto, no hay duda de que algunos patrones no serán aplicables "tal cual", algunos podrían no tener sentido y hay algunos patrones que podrían ser significativos para Python.

Para volver exactamente a su pregunta: los patrones solo son necesarios si los necesita . No tiene que usarlos si no los necesita (como ya dijo Jan Hudec).

Además, hay muchos más patrones que los mencionados en GoF. Ver en wikipedia otros patrones

estani
fuente