¿La progtwigción funcional reemplaza los patrones de diseño de GoF?

Desde que empecé a aprender F # y OCaml el año pasado, he leído una gran cantidad de artículos que insisten en que los patrones de diseño (especialmente en Java) son soluciones para las características que faltan en los idiomas imperativos. Un artículo que encontré hace un reclamo bastante fuerte :

La mayoría de las personas que he conocido han leído el libro Patrones de diseño de la Banda de los Cuatro. Cualquier progtwigdor que se respete a sí mismo le dirá que el libro es independiente del idioma y que los patrones se aplican a la ingeniería del software en general, independientemente del idioma que use. Este es un noble reclamo. Desafortunadamente, está muy lejos de la verdad.

Los lenguajes funcionales son extremadamente expresivos. En un lenguaje funcional, uno no necesita patrones de diseño porque el lenguaje es probablemente de tan alto nivel, terminas progtwigndo en conceptos que eliminan patrones de diseño en conjunto.

Las principales características de la progtwigción funcional incluyen funciones como valores de primera clase, currying, valores inmutables, etc. No me parece obvio que los patrones de diseño de OO se aproximen a cualquiera de esas características.

Además, en los lenguajes funcionales que soportan OOP (como F # y OCaml), me parece obvio que los progtwigdores que usan estos lenguajes usarían los mismos patrones de diseño disponibles para cada otro lenguaje OOP. De hecho, en este momento utilizo F # y OCaml todos los días, y no hay diferencias notables entre los patrones que uso en estos lenguajes frente a los patrones que uso cuando escribo en Java.

¿Hay algo de cierto en la afirmación de que la progtwigción funcional elimina la necesidad de patrones de diseño OOP? De ser así, ¿podría publicar o vincular un ejemplo de un patrón de diseño OOP típico y su equivalente funcional?

La publicación de blog que citó exagera un poco su afirmación. FP no elimina la necesidad de patrones de diseño. El término “patrones de diseño” simplemente no se usa ampliamente para describir lo mismo en lenguajes FP. Pero ellos existen. Los lenguajes funcionales tienen muchas reglas de mejores prácticas de la forma “cuando encuentras el problema X, usa un código que se parece a Y”, que es básicamente lo que es un patrón de diseño.

Sin embargo, es correcto que la mayoría de los patrones de diseño específicos de OOP son prácticamente irrelevantes en los lenguajes funcionales.

No creo que deba ser particularmente controvertido decir que los patrones de diseño en general solo existen para corregir defectos en el lenguaje. Y si otro idioma puede resolver el mismo problema trivialmente, ese otro idioma no necesitará un patrón de diseño para él. Es posible que los usuarios de ese idioma ni siquiera sepan que el problema existe , porque, bueno, no es un problema en ese idioma.

Esto es lo que The Gang of Four tiene que decir sobre este tema:

La elección del lenguaje de progtwigción es importante porque influye en el punto de vista de uno. Nuestros patrones asumen características de lenguaje de nivel Smalltalk / C ++, y esa elección determina qué se puede implementar y qué no se puede implementar fácilmente. Si asumimos los lenguajes de procedimiento, podríamos haber incluido patrones de diseño llamados “Herencia”, “Encapsulación” y “Polimorfismo”. Del mismo modo, algunos de nuestros patrones son compatibles directamente con los lenguajes orientados a objetos menos comunes. CLOS tiene múltiples métodos, por ejemplo, que disminuyen la necesidad de un patrón como Visitor. De hecho, hay suficientes diferencias entre Smalltalk y C ++ para indicar que algunos patrones se pueden express más fácilmente en un idioma que en el otro. (Véase Iterador, por ejemplo).

(Lo anterior es una cita del libro Introducción a los patrones de diseño, página 4, párrafo 3)

Las principales características de la progtwigción funcional incluyen funciones como valores de primera clase, currying, valores inmutables, etc. No me parece obvio que los patrones de diseño de OO se aproximen a cualquiera de esas características.

¿Cuál es el patrón de comando, si no es una aproximación de las funciones de primera clase? 🙂 En un lenguaje FP, simplemente pasaría una función como argumento a otra función. En un lenguaje OOP, debe cerrar la función en una clase, la cual puede instanciar y luego pasar ese objeto a la otra función. El efecto es el mismo, pero en OOP se llama patrón de diseño y requiere mucho más código. ¿Y cuál es el patrón de fábrica abstracto, si no es currying? Pase los parámetros a una función de a poco a la vez, para configurar qué tipo de valor escupirá cuando finalmente lo llame.

Entonces sí, varios patrones de diseño de GoF se vuelven redundantes en los lenguajes de FP, porque existen alternativas más potentes y fáciles de usar.

Pero, por supuesto, todavía hay patrones de diseño que no son resueltos por los lenguajes de FP. ¿Cuál es el equivalente FP de un singleton? (Ignorando por un momento que los singletons son generalmente un patrón terrible de usar)

Y funciona en ambos sentidos también. Como dije, FP también tiene sus patrones de diseño, las personas simplemente no suelen pensar en ellos como tales.

Pero es posible que haya encontrado mónadas. ¿Qué son, sino un patrón de diseño para “tratar con el estado global”? Ese es un problema tan simple en los lenguajes OOP que no existe un patrón de diseño equivalente allí.

No necesitamos un patrón de diseño para “incrementar una variable estática” o “leer de ese socket”, porque es justo lo que hace .

En los lenguajes funcionales (puros), los efectos secundarios y el estado mutable son imposibles, a menos que trabajes con el “patrón de diseño” de la mónada o con cualquiera de los otros métodos para permitir lo mismo.

Además, en los lenguajes funcionales que soportan OOP (como F # y OCaml), me parece obvio que los progtwigdores que usan estos lenguajes usarían los mismos patrones de diseño disponibles para cada otro lenguaje OOP. De hecho, en este momento utilizo F # y OCaml todos los días, y no hay diferencias notables entre los patrones que uso en estos lenguajes frente a los patrones que uso cuando escribo en Java.

Tal vez porque todavía estás pensando imperativamente? Muchas personas, después de lidiar con idiomas imperativos durante toda su vida, tienen dificultades para renunciar a ese hábito cuando intentan un lenguaje funcional. (He visto algunos bashs bastante divertidos en F #, donde literalmente cada función era solo una cadena de declaraciones ‘let’, básicamente como si hubieras tomado un progtwig C, y reemplazaste todos los puntos y comas con ‘let’. :))

Pero otra posibilidad podría ser que simplemente no se haya dado cuenta de que está resolviendo problemas trivialmente, lo que requeriría patrones de diseño en un lenguaje OOP.

Cuando usa currying o pasa una función como argumento a otro, deténgase y piense cómo lo haría en un lenguaje OOP.

¿Hay algo de cierto en la afirmación de que la progtwigción funcional elimina la necesidad de patrones de diseño OOP?

Sí. 🙂 Cuando trabaja en un lenguaje FP, ya no necesita los patrones de diseño específicos de OOP. Pero aún necesita algunos patrones de diseño generales, como MVC u otras cosas no específicas de OOP, y necesita un par de nuevos “patrones de diseño” específicos de FP. Todos los idiomas tienen sus defectos, y los patrones de diseño son generalmente la forma en que trabajamos a su alrededor.

De todos modos, puede que le resulte interesante probar con los lenguajes FP “más limpios”, como ML (mi favorito personal, al menos para fines de aprendizaje), o Haskell, donde no tiene la muleta OOP para recurrir cuando se enfrentan a algo nuevo


Como era de esperar, algunas personas se opusieron a mi definición de patrones de diseño como “corregir fallas en un idioma”, así que aquí está mi justificación: como ya se dijo, la mayoría de los patrones de diseño son específicos de un paradigma de progtwigción, o incluso de un lenguaje específico. A menudo, resuelven problemas que solo existen en ese paradigma (ver mónadas para FP o fábricas abstractas para OOP). ¿Por qué no existe el patrón abstracto de fábrica en FP? Porque el problema que trata de resolver no existe allí. Entonces, si existe un problema en los lenguajes de OOP, que no existe en los lenguajes de FP, entonces claramente eso es una deficiencia de los lenguajes de OOP. El problema puede ser resuelto, pero su lenguaje no lo hace, pero requiere un montón de código repetitivo para evitarlo. Idealmente, nos gustaría que nuestro lenguaje de progtwigción elimine mágicamente todos los problemas. Cualquier problema que todavía existe es, en principio, una deficiencia del lenguaje. 😉

¿Hay algo de cierto en la afirmación de que la progtwigción funcional elimina la necesidad de patrones de diseño OOP?

La progtwigción funcional no es lo mismo que la progtwigción orientada a objetos. Los patrones de diseño orientados a objetos no se aplican a la progtwigción funcional. En cambio, tiene patrones de diseño de progtwigción funcional.

Para la progtwigción funcional, no leerá los libros de patrones de diseño de OO, leerá otros libros sobre patrones de diseño de PF.

lenguaje agnóstico

No totalmente. Solo es independiente del idioma con respecto a los lenguajes OO. Los patrones de diseño no se aplican a los lenguajes de procedimiento en absoluto. Apenas tienen sentido en un contexto de diseño de base de datos relacional. No se aplican al diseñar una hoja de cálculo.

un patrón de diseño de OOP típico y su equivalente funcional?

Lo anterior no debería existir. Es como pedir un trozo de código de procedimiento reescrito como código OO. Ummm … Si traduzco el Fortran original (o C) a Java, no he hecho nada más que traducirlo. Si lo reescribo totalmente en un paradigma OO, ya no se verá como el Fortran o C original: será irreconocible.

No hay un mapeo simple desde OO Design hasta Functional Design. Son formas muy diferentes de ver el problema.

La progtwigción funcional (como todos los estilos de progtwigción) tiene patrones de diseño. Las bases de datos relacionales tienen patrones de diseño, OO tiene patrones de diseño, la progtwigción de procedimientos tiene patrones de diseño. Todo tiene patrones de diseño, incluso la architecture de los edificios.

Los patrones de diseño, como concepto, son una forma intemporal de construcción, independientemente de la tecnología o el dominio del problema. Sin embargo, los patrones de diseño específicos se aplican a dominios y tecnologías de problemas específicos.

Todos los que piensen en lo que están haciendo descubrirán patrones de diseño.

Los comentarios de Brian sobre el estrecho vínculo entre el lenguaje y el patrón van al punto,

La parte que falta de esta discusión es el concepto de modismo. El libro de Coplien, “Advanced C ++” fue una gran influencia aquí. Mucho antes de que descubriera a Christopher Alexander y la Columna sin nombre (y usted tampoco puede hablar con sensatez sobre los patrones sin leer a Alexander), habló sobre la importancia de dominar el idioma para aprender verdaderamente un idioma. Utilizó una copia de cadena en C como ejemplo, mientras que (* de ++ = * a ++); Puedes ver esto como una curita de una característica de idioma faltante (o característica de la biblioteca), pero lo que realmente importa es que es una unidad de pensamiento o expresión más grande que cualquiera de sus partes.

Eso es lo que intentan hacer los patrones y los lenguajes, para permitirnos express nuestras intenciones de manera más sucinta. Cuanto más ricas son las unidades de pensamiento, más complejos son los pensamientos que puedes express. Tener un vocabulario rico y compartido en una variedad de escalas -desde la architecture del sistema hasta la manipulación de bits- nos permite tener conversaciones más inteligentes y pensamientos sobre lo que deberíamos estar haciendo.

También podemos, como individuos, aprender. Cuál es el punto entero del ejercicio. Todos podemos entender y usar cosas que nunca podríamos pensar de nosotros mismos. Los idiomas, los marcos, las bibliotecas, los patrones, los modismos, etc. tienen su lugar en el intercambio de la riqueza intelectual.

El libro GOF se vincula explícitamente con OOP, el título es Patrones de diseño: elementos del software reutilizable orientado a objetos (énfasis mío).

Patrones de diseño en progtwigción dinámica por Peter Norvig tiene una cobertura cuidadosa de este tema general, aunque sobre los idiomas ‘dynamics’ en lugar de ‘funcional’ (hay superposición).

Aquí hay otro enlace sobre este tema: http://blog.ezyang.com/2010/05/design-patterns-in-haskel/

En su publicación del blog, Edward describe los 23 patrones originales de GoF en términos de Haskell.

Cuando intenta ver esto en el nivel de “patrones de diseño” (en general) y “FP versus OOP”, las respuestas que encontrará serán turbias en el mejor de los casos.

Sin embargo, profundice en ambos ejes y tenga en cuenta los patrones de diseño específicos y las características específicas del lenguaje, y las cosas se vuelven más claras.

Así, por ejemplo, algunos patrones específicos, como Visitor , Strategy , Command y Observer, definitivamente cambian o desaparecen cuando se usa un lenguaje con tipos de datos algebraicos y coincidencia de patrones , cierres , funciones de primera clase , etc. Algunos otros patrones del libro GoF aún ‘quedarse’, sin embargo.

En general, diría que, con el tiempo, los patrones específicos se están eliminando con nuevas características del lenguaje (o simplemente creciente en popularidad). Este es el curso natural del diseño del lenguaje; a medida que los idiomas se vuelven de más alto nivel, las abstracciones que antes solo podían mencionarse en un libro utilizando ejemplos ahora se convierten en aplicaciones de una característica de idioma o biblioteca en particular.

(Aparte: aquí hay un blog reciente que escribí, que tiene otros enlaces a más discusión sobre FP y patrones de diseño).

La presentación de Norvig alude a un análisis que hicieron de todos los patrones de GoF, y dicen que 16 de los 23 patrones tenían implementaciones más simples en lenguajes funcionales, o simplemente eran parte del lenguaje. Entonces, presumiblemente, al menos siete de ellos eran a) igualmente complicados ob) no estaban presentes en el idioma. Desafortunadamente para nosotros, ¡no están enumerados!

Creo que está claro que la mayoría de los patrones “creacionales” o “estructurales” en GoF son simplemente trucos para hacer que los sistemas de tipos primitivos en Java o C ++ hagan lo que quieran. Pero el rest es digno de consideración sin importar en qué idioma programe.

Uno podría ser Prototipo; si bien es una noción fundamental de JavaScript, debe implementarse desde cero en otros idiomas.

Uno de mis patrones favoritos es el patrón Objeto nulo: representa la ausencia de algo como un objeto que hace un tipo apropiado de nada. Esto puede ser más fácil de modelar en un lenguaje funcional. Sin embargo, el verdadero logro es el cambio de perspectiva.

Diría que cuando tienes un lenguaje como Lisp con su soporte para macros, entonces puedes construir tus propias abstracciones específicas de dominio, abstracciones que a menudo son mucho mejores que las soluciones de modismos generales.

E incluso las soluciones de patrón de diseño OO son específicas del idioma. Los patrones de diseño son soluciones a problemas comunes que su lenguaje de progtwigción no resuelve para usted. En Java, el patrón Singleton resuelve el problema de uno de algo (simplificado). En Scala, tiene una construcción de nivel superior llamada Object además de Class. Es instanciado perezosamente y solo hay uno. No tiene que usar el patrón de Singleton para obtener un Singleton. Es parte del lenguaje.

Como han dicho otros, hay patrones específicos de progtwigción funcional. Creo que la cuestión de deshacerse de los patrones de diseño no es tanto una cuestión de cambiar a funcional, sino una cuestión de características de lenguaje .

Eche un vistazo a cómo Scala elimina el “patrón de singleton”: simplemente declara un objeto en lugar de una clase. Otra característica, la coincidencia de patrones, ayuda a evitar el clunkiness del patrón de visitante. Ver la comparación aquí: http://andymaleh.blogspot.com/2008/04/scalas-pattern-matching-visitor-pattern.html

Y Scala, como F #, es una fusión de OO-funcional. No sé sobre F # pero probablemente tiene este tipo de características.

Los cierres están presentes en el lenguaje funcional, pero no necesitan estar restringidos a ellos. Ellos ayudan con el patrón del delegador.

Una observación más. Esta pieza de código implementa un patrón: es un clásico y es tan elemental que normalmente no lo consideramos un “patrón”, pero seguro:

 for(int i = 0; i < myList.size(); i++) { doWhatever(myList.get(i)); } 

Los lenguajes imperativos como Java y C # han adoptado lo que es esencialmente una construcción funcional para lidiar con esto: "foreach".

Los patrones son formas de resolver problemas similares que se ven una y otra vez, y luego se describen y documentan. Entonces, no, FP no va a reemplazar patrones; sin embargo, FP podría crear nuevos patrones y hacer que algunos patrones actuales de “mejores prácticas” sean “obsoletos”.

Los Patrones de diseño de GoF están codificando recetas de soluciones para lenguajes OO que son descendientes de Simula 67, como Java y C ++.

La mayoría de los “males” tratados por los patrones de diseño son causados ​​por:

  • clases tipadas estáticamente, que especifican objetos pero que no son en sí mismos objetos;
  • restricción al envío único (solo el argumento más a la izquierda se usa para seleccionar un método, los argumentos restantes se consideran solo como estáticos: si tienen tipos dynamics, depende del método resolverlos con enfoques ad-hoc);
  • distinción entre llamadas a funciones regulares y llamadas a funciones orientadas a objetos, lo que significa que las funciones orientadas a objetos no se pueden pasar como argumentos funcionales donde se esperan las funciones normales y viceversa; y
  • distinción entre “tipos de base” y “tipos de clase”.

No hay ninguno de estos patrones de diseño que no desaparezca en el sistema de objetos Common Lisp, aunque la solución está estructurada esencialmente de la misma manera que en el patrón de diseño correspondiente. (Además, ese sistema de objetos precede al libro GoF por más de una década. Common Lisp se convirtió en un estándar ANSI el mismo año en que el libro se publicó por primera vez).

En lo que respecta a la progtwigción funcional, el hecho de que los patrones se apliquen depende de si el lenguaje de progtwigción funcional dado tiene algún tipo de sistema de objetos, y si está modelado después de que los sistemas de objetos se benefician de los patrones. Ese tipo de orientación a objetos no se combina bien con la progtwigción funcional, porque la mutación de estado está en la parte frontal y central.

La construcción y el acceso no mutante son compatibles con la progtwigción funcional, por lo que los patrones que tienen que ver con el acceso de abstracción o la construcción podrían ser aplicables: patrones como Factory, Facade, Proxy, Decorator, Visitor.

Por otro lado, los patrones de comportamiento como Estado y Estrategia probablemente no se apliquen directamente en la POO funcional porque la mutación del estado está en su núcleo. Esto no significa que no se apliquen; quizás de alguna manera se apliquen en combinación con los trucos disponibles para simular el estado mutable.

Me gustaría incluir un par de documentos excelentes pero algo densos de Jeremy Gibbons: “Patrones de diseño como progtwigs generics de tipo de datos de orden superior” y “La esencia del patrón iterador” (ambos disponibles aquí: http: // www. comlab.ox.ac.uk/jeremy.gibbons/publications/ ).

Ambos describen cómo las construcciones idiomáticas funcionales cubren el terreno que está cubierto por patrones de diseño específicos en otros entornos (orientados a objetos).

No puede tener esta discusión sin mencionar los sistemas de tipo.

Las principales características de la progtwigción funcional incluyen funciones como valores de primera clase, currying, valores inmutables, etc. No me parece obvio que los patrones de diseño de OO se aproximen a cualquiera de esas características.

Esto se debe a que estas características no abordan los mismos problemas que OOP … son alternativas a la progtwigción imperativa. La respuesta FP a OOP se basa en los sistemas tipo de ML y Haskell … específicamente tipos de sum, tipos de datos abstractos, módulos ML, clases de tipos Haskell.

Pero, por supuesto, todavía hay patrones de diseño que no son resueltos por los lenguajes de FP. ¿Cuál es el equivalente FP de un singleton? (Ignorando por un momento que los singletons son generalmente un patrón terrible de usar)

Lo primero que hacen las clases tipo es eliminar la necesidad de singletons.

Podría revisar la lista de 23 y eliminar más, pero no tengo tiempo para hacerlo ahora mismo.

Creo que solo dos GoF Design Patterns están diseñados para introducir la lógica de progtwigción funcional en el lenguaje OO natural. Pienso en Estrategia y Comando. Algunos de los otros patrones de diseño GoF se pueden modificar mediante progtwigción funcional para simplificar el diseño y mantener el propósito.

Esencialmente, !

  • Cuando un patrón elude las características que faltan (funciones de orden superior, manejo de flujo …) esa última facilidad facilita la composición .
  • La necesidad de volver a escribir la implementación de los patrones una y otra vez puede verse como un olor a lenguaje .

Además, esta página (AreDesignPatternsMissingLanguageFeatures) proporciona una tabla de traducción “patrón / función” y algunas buenas discusiones, si está dispuesto a excavar.

OOP y los patrones de GoF tratan con los estados. OOP modela la realidad para mantener el código base lo más cerca posible de los requisitos de la realidad. Los patrones de diseño de GoF son patrones que se identificaron para resolver problemas atómicos del mundo real. Manejan el problema del estado de una manera semántica.

Como en la progtwigción funcional real no existe ningún estado, no tiene sentido aplicar los patrones GoF. No hay patrones de diseño funcionales de la misma manera que hay patrones de diseño GoF. Cada patrón de diseño funcional es artificial en contraste con la realidad ya que las funciones son constructos de las matemáticas y no de la realidad.

Las funciones carecen del concepto de tiempo, ya que siempre devuelven el mismo valor sea cual sea el tiempo actual, a menos que el tiempo sea parte de los parámetros de la función, lo que hace que sea realmente difícil prrocesar “solicitudes futuras”. Los lenguajes híbridos mezclan esos conceptos, hacen que los lenguajes no sean verdaderos lenguajes de progtwigción funcionales.

Los lenguajes funcionales están aumentando solo por una cosa: las restricciones naturales actuales de la física. Los procesadores de hoy están limitados en su velocidad de procesamiento de instrucciones debido a las leyes físicas. Usted ve un estancamiento en la frecuencia del reloj, pero una expansión en los núcleos de procesamiento. Es por eso que el paralelismo de instrucciones se vuelve cada vez más importante para boost la velocidad de las aplicaciones modernas. Como la progtwigción funcional, por definición, no tiene ningún estado y, por lo tanto, no tiene efectos secundarios, es seguro procesar las funciones de forma segura en paralelo.

Los patrones de GoF no son obsoletos. Son al menos necesarios para modelar los requisitos del mundo real. Pero si usa un lenguaje de progtwigción funcional, debe transformarlos en sus equivalentes híbridos. Finalmente, no tiene posibilidad de hacer solo progtwigs funcionales si usa la persistencia. Para los elementos híbridos de su progtwig, sigue existiendo la necesidad de utilizar patrones GoF. Cualquier otro elemento que sea puramente funcional no es necesario usar patrones GoF porque no hay estado.

Debido a que el patrón GoF no es necesario para la progtwigción funcional real, eso no significa que los principios SÓLIDOS no se deben aplicar. Los principios SOLID están más allá de cualquier paradigma de lenguaje.

La progtwigción funcional no reemplaza los patrones de diseño. Los patrones de diseño no pueden ser reemplazados.

Los patrones simplemente existen; surgieron con el tiempo. El libro de GoF formalizó algunos de ellos. Si salen a la luz nuevos patrones, los desarrolladores usan lenguajes de progtwigción funcionales que son cosas emocionantes, y tal vez haya libros escritos sobre ellos también.

En el nuevo libro de 2013 llamado “Patrones de progtwigción funcional- en Scala y Clojure”, el autor Michael.B. Linn hace un trabajo decente al comparar y proporcionar reemplazos en muchos casos para los patrones GoF y también discute los patrones funcionales más nuevos como ‘recursividad final’, ‘memoización’, ‘secuencia diferida’, etc.

Este libro está disponible en Amazon. Me pareció muy informativo y alentador cuando provenía de un fondo OO de un par de décadas.

En la Progtwigción Funcional, los patrones de diseño tienen un significado diferente, de hecho, la mayoría de los patrones de diseño OOP son innecesarios en la progtwigción funcional debido al mayor nivel de abstracción y HOF utilizados como bloques de construcción.

El principio de un HOF significa que las funciones se pueden pasar como argumentos a otras funciones. y las funciones pueden devolver valores.

Creo que cada paradigma tiene un propósito diferente y, como tal, no se puede comparar de esta manera.

No he oído que los patrones de diseño GoF sean aplicables a todos los idiomas. He oído que son aplicables a todos los idiomas OOP . Si usa la progtwigción funcional, el dominio de los problemas que resuelve es diferente de los lenguajes OO.

No utilizaría el lenguaje funcional para escribir una interfaz de usuario, pero uno de los lenguajes OO como C # o Java facilitaría este trabajo. Si estuviera escribiendo un lenguaje funcional, no consideraría usar OO Design Patterns.

OOP y FP tienen diferentes objectives, OOP pretende encapsular las complejidades / partes móviles de los componentes de software y los objectives de FP para minimizar la complejidad y las dependencias de los componentes de software. Sin embargo, estos 2 paradigmas no son necesariamente 100% contradictorios y podrían aplicarse conjuntamente para obtener el beneficio de ambos mundos. Incluso con un lenguaje que no admite nativamente progtwigción funcional como C #, podría escribir código funcional si comprende los principios de FP, de la misma manera podría aplicar los principios de OOP usando F # si comprende los principios de OOP, patrones y mejores prácticas. Haría la elección correcta en función de la situación y el problema que trate de resolver, independientemente del lenguaje de progtwigción que utilice.

Como decía la respuesta aceptada, OOP y FP tienen todos sus patrones específicos.

Sin embargo, hay algunos patrones que son tan comunes que todas las plataformas de progtwigción que puedo pensar deberían tener. Aquí hay una lista (incompleta):

  • Adaptador. Apenas puedo pensar en una plataforma de progtwigción útil que sea tan completa (y cumplida en sí misma) que no necesite hablar con el mundo. Si va a hacerlo, definitivamente se necesita un adaptador.

  • Fachada. Cualquier plataforma de progtwigción que pueda manejar código fuente grande debería poder modularse. Si tuviera que crear un módulo para otras partes del progtwig, querrá ocultar las partes “sucias” del código y darle una interfaz agradable.

  • Interprete. En general, cualquier progtwig solo hace dos cosas: analizar entrada e imprimir salida. Las entradas del mouse deben analizarse y los widgets de la ventana deben imprimirse. Por lo tanto, tener un intérprete incorporado le da al progtwig poder adicional para personalizar cosas.

Además, noté en un lenguaje FP típico, Haskell, que hay algo similar a los patrones GoF, pero con diferentes nombres. En mi opinión, esto sugiere que estuvieron allí porque hay algunos problemas comunes que resolver tanto en el lenguaje PF como en el POO.

  • Monad transformador y decorador. El primero solía agregar capacidad adicional a una mónada existente, la última agrega capacidad adicional a un objeto existente.