Diseño funcional. Principios, patrones y prácticas - Robert C. Martin - E-Book

Diseño funcional. Principios, patrones y prácticas E-Book

Robert C. Martin

0,0

Beschreibung

En Diseño funcional, el reputado ingeniero de software Robert C. Martin («Uncle Bob») explica cómo y por qué utilizar la programación funcional para crear sistemas mejores para clientes reales. Martin compara las estructuras de la programación convencional orientada a objetos en Java con las que permiten los lenguajes funcionales, identifica los mejores roles para cada una y muestra cómo crear sistemas mejores utilizándolos correctamente en cada contexto. El enfoque de Martin es pragmático, con una teoría mínima, y se centra en la solución de problemas «desde las trincheras». A través de ejemplos accesibles, los desarrolladores profesionales descubrirán cómo el lenguaje Clojure, rico a nivel semántico y fácil de aprender, puede ayudarles a mejorar la limpieza del código, el diseño, la disciplina y los resultados. Martin examina los conocidos principios SOLID y los patrones de diseño Gang of Four desde una perspectiva funcional, y revela por qué los patrones siguen teniendo un gran valor para los programadores funcionales, y cómo usarlos para conseguir resultados superiores. * Entienda conceptos básicos funcionales: inmutabilidad, datos persistentes, recursividad, iteración, pereza y programas con estado. * Contraste los enfoques funcionales y de objetos a través de casos prácticos elaborados con cuidado. * Explore técnicas de diseño funcional para el flujo de datos. * Use principios SOLID clásicos para escribir mejor código Clojure. * Domine enfoques pragmáticos respecto a las pruebas funcionales, las GUI y la concurrencia. * Aproveche al máximo los patrones de diseño en entornos funcionales. * Cree paso a paso una aplicación de clase empresarial en Clojure.

Sie lesen das E-Book in den Legimi-Apps auf:

Android
iOS
von Legimi
zertifizierten E-Readern

Seitenzahl: 309

Veröffentlichungsjahr: 2024

Das E-Book (TTS) können Sie hören im Abo „Legimi Premium” in Legimi-Apps auf:

Android
iOS
Bewertungen
0,0
0
0
0
0
0
Mehr Informationen
Mehr Informationen
Legimi prüft nicht, ob Rezensionen von Nutzern stammen, die den betreffenden Titel tatsächlich gekauft oder gelesen/gehört haben. Wir entfernen aber gefälschte Rezensionen.



Dedicatoria

A mi familia, mi amor por ella explica todo lo que hago.

En primer lugar, a mi mujer desde hace 50 años, la preciosa joven de 16 años con ojos marrones chispeantes y pelo largo y suelto que me robó el corazón y lo mantiene cautivo desde hace más de medio siglo. Sigue siendo tan hermosa como el día en que la conocí.

Esos ojos marrones chispeantes y su cabello suelto me enamoran cada día. La madre de mis hijos. El ancla de mi vida. Mi único y verdadero amor.

A Angela, mi preciosa y fiel primogénita, cuya sonrisa contagiosa te derrite el corazón y te convence de que todo va bien en el mundo. Una vez le pregunté que quería ser. Su respuesta fue: «¡Divertida!». Ha conseguido, y superado con creces, ese objetivo. Su entusiasmo ilimitado por la vida contagia a todos los que la conocen. Está casada con Matt, un hombre maravilloso, trabajador y honesto (y divertido). Juntos, han convertido la diversión que comparten en un frenesí de trabajo remunerado sobre bicicletas de montaña. Viven en un bosque en lo alto de una colina y han criado a tres hijas guapas, inteligentes y talentosas a las que puedo mimar.

A Micah, mi segundo y apasionado hijo. Ha heredado los chispeantes ojos marrones de su madre. Una vez le pregunté que quería ser. Me dijo: «¡Rico!». Me enorgullece decir que lo ha hecho bastante bien. Dedicó casi una década a trabajar conmigo y, después, fundó su propia empresa de software, que vendió unos años después. Luego pasó un año construyendo una avioneta en su garaje. Ahora dirige otra empresa de software. Gran parte de su éxito se debe a Angelique, la hermosa, trabajadora e inteligentísima mujer con quien se casó. Han criado a dos jovencitos espectaculares.

A Gina, mi tercera hija, una caja de sorpresas. Si es posible que haya una mujer más hermosa que mi mujer, es Gina. Se convirtió en una consumada ingeniera científica y trabajó con sustancias tan agradables como el uranio, el flúor y el hidróxido de sodio concentrado. Se puso cascos de protección, subió por recipientes de reacción y ha dirigido equipos de operarios de plantas químicas. Está casada con Keith, un ingeniero mecánico maravilloso, trabajador y honesto. Los dos intercambian anécdotas de sus aventuras en plantas químicas grandes y complejas. Han traído al mundo a tres (2,9 en el momento de escribir esto) de mis nietos. Hace más de tres años, mientras se enfrentaba a las presiones de la conciliación entre la maternidad, el trabajo y la pandemia, Gina me preguntó si pensaba que un cambio de carrera hacia la ingeniería de software sería posible. ¡Y vaya si fue posible! ¡Está que se sale! Y, por cierto, su experiencia industrial es un factor importante.

A Justin, mi hijo menor, muy competente y seguro. Justin es una persona muy analítica para quien no hay problema que no pueda resolverse, ni reto que no pueda abordarse, ni fallo que no pueda enmendarse. Si le parece que eso suena un poco quijotesco, sepa que también es un pragmatista del más alto nivel. Elige bien sus batallas. Y muestra una tendencia muy molesta a... tener razón. Nos llamó a su madre y a mí en enero de 2020 y nos dijo que se acercaba una pandemia muy grave. Recomendó entrar en las criptomonedas y consiguió unos buenos ahorros con sus especulaciones. Es ingeniero de software por excelencia y, en la actualidad, dirige un equipo de software para una empresa en Austin. Está casado con Ela, una pelirroja pasional cuya inteligencia e integridad solo se ven superados por su valor. Tienen dos hijos preciosos, un niño y una niña, lo que hace que sean la primera de las familias de mis hijos que goza de este particular privilegio.

Qué afortunado es el hombre que tiene un montón de hijos y nietos.

Agradecimientos

Gracias a los diligentes profesionales de Pearson por ayudarme a completar este libro: Julie Phifer, mi editora de toda la vida, siempre dispuesta a ayudarme y a apoyarme, y a sus compañeros, Menka Mehta, Julie Nahil, Audrey Doyle, Maureen Forys, Mark Taber y muchos más. Siempre ha sido un placer trabajar con vosotros y estoy deseando volver a hacerlo en el futuro.

Gracias a Jennifer Kohnke, que ha creado la mayoría de las bonitas ilustraciones de mis libros durante las últimas tres décadas. Allá por 1995, justo antes de la fecha límite de producción, Jennifer, Jim Newkirk y yo trabajamos toda una noche para conseguir que las ilustraciones de mi primer libro tuviesen el formato y la organización que yo quería.

Gracias a Michael Feathers, que me sugirió hace 20 años que investigase la programación funcional. Él estaba aprendiendo Haskell en aquel momento y le entusiasmaban sus posibilidades. Ese entusiasmo me pareció contagioso.

Gracias a Mark Seemann (@ploeh) por sus trabajos siempre perspicaces, sus comentarios agudos y racionales de mis trabajos y también su coraje moral.

Gracias a Stuart Halloway, que escribió el primer libro que leí sobre Clojure. Hace más de una década y media que empecé esta aventura y nunca he mirado atrás. Stuart fue muy amable y me guio en mis primeros experimentos con la programación funcional. También le ofrezco una disculpa por haber hablado una vez, hace tiempo, sin que me tocase.

Gracias a Rich Hickey, que debatió conmigo a principios de los 90 respecto a C++ y el diseño orientado a objetos y después creó y guio de manera magistral el desarrollo de Clojure. Las perspectivas de Rich acerca del software todavía me asombran.

Aunque nunca los he conocido, debo un agradecimiento a Harold Abelson, Gerald Jay Sussman y Julie Sussman por el libro que me inspiró de verdad para dedicarme a la programación funcional. Ese libro, The Structure and Interpretation of Computer Programs (SICP), es quizá el más relevante de todos los libros sobre software que he leído. Está disponible en línea de forma gratuita. Solo hay que buscar «SICP».

Gracias a Janet Carr por el prólogo. Me topé con su trabajo mientras leía Twitter con detenimiento y descubrí que había llegado a muchas de las mismas conclusiones que yo respecto a la programación funcional y Clojure.

Y, por escribir el epílogo, gracias a Gina Martiny, mi encantadora hija: una química e ingeniera de software consumada. Hablo más sobre ella en la dedicatoria.

Sobre el autor

Robert C. Martin (Uncle Bob) es programador desde 1970. Es fundador de Uncle Bob Consulting, LLC, y cofundador, junto a su hijo Micah Martin, de The Clean Coders, LLC. Martin ha publicado docenas de artículos en varias revistas profesionales y es orador habitual en conferencias y ferias internacionales. Ha escrito y editado muchos libros, incluyendo Designing Object-Oriented C++ Applications Using the Booch Method, Pattern Languages of Program Design 3, More C++ Gems, Extreme Programming in Practice, Agile Software Development: Principles, Patterns, and Practices, UML para programadores Java, Código limpio, El limpiador de código, Arquitectura limpia, La artesanía del código limpio y Desarrollo ágil esencial.

Líder en la industria del desarrollo de software, Martin trabajó como editor jefe de C++ Report durante tres años y fue el primer presidente de la Alianza Ágil.

Índice de contenidos

Dedicatoria

Agradecimientos

Sobre el autor

Prólogo

Prefacio

Breve historia de la programación funcional y por procedimientos

Sobre Clojure

Sobre arquitectura y diseño

Sobre la orientación a objetos

Sobre «funcional»

Parte I. Conceptos funcionales básicos

1. Inmutabilidad

¿Qué es la programación funcional?

El problema con la asignación

Entonces, ¿por qué se llama funcional?

¿Sin cambio de estado?

Inmutabilidad

2. Datos persistentes

Sobre la trampa

Hacer copias

Compartición estructural

3. Recursividad e iteración

Iteración

Tutorial muy breve de Clojure

Iteración

TCO, Clojure y la JVM

Recursividad

4. Pereza

Acumulación perezosa

Vale, pero ¿por qué?

Conclusión

5. Programas con estado

Cuándo DEBEMOS mutar

Memoria transaccional de software (STM)

La vida es dura, el software aún más

Parte II. Análisis comparativo

6. Factores primos

Versión en Java

Versión en Clojure

Conclusión

7. Partida de bolos

Versión en Java

Versión en Clojure

Conclusión

8. Conductores de autobús cotillas

Solución en Java

Conductor

Ruta

Parada

Rumor

Simulación

Clojure

Conclusión

9. Programación orientada a objetos

Nómina funcional

Espacios de nombres y archivos fuente

Conclusión

10. Tipos

Conclusión

Parte III. Diseño funcional

11. Flujo de datos

12. SOLID

Principio de responsabilidad única (SRP)

Principio de abierto-cerrado (OCP)

Funciones

Objetos con tablas virtuales

Multimétodos

Capacidad de despliegue independiente

Principio de sustitución de Liskov (LSP)

La regla ISA (es-un)

¡No!

La regla representativa

Principio de segregación de la interfaz (ISP)

No dependa de cosas que no necesita

¿Por qué?

Conclusión

Principio de inversión de dependencias (DIP)

Una mirada al pasado

Una violación del DIP

Conclusión

Parte IV. Pragmática funcional

13. Pruebas

Pero ¿qué hay del REPL?

¿Qué hay de los mocks?

Pruebas basadas en propiedades

Una técnica de diagnóstico

Funcional

14. GUI

Gráficas tortuga en Quil

15. Concurrencia

Conclusión

Parte V. Patrones de diseño

16. Revisión de los patrones de diseño

Patrones en la programación funcional

Abstract Server

Adapter

¿Es eso un objeto Adapter de verdad?

Command

Undo

Composite

¿Funcional?

Decorator

Visitor

¿Cerrar o usar Clojure?

El problema de los 90º

Abstract Factory

90º otra vez

¿Seguridad de tipos?

Conclusión

Posdata: ¿veneno OO?

Parte VI. Caso práctico

17. Wa-Tor

Satisfacer necesidades

Las duchas resuelven problemas

Es hora de reproducirse a lo grande

¿Qué pasa con los tiburones?

Conclusión

Epílogo

Créditos

Prólogo

Uncle Bob necesita pocas presentaciones. Figura prominente en la industria del desarrollo de software, ha escrito muchos libros sobre diseño y entrega de software. Algunos de sus trabajos se enseñan en las clases de informática de todo el mundo.

Yo estaba en la universidad cuando empecé con la programación funcional. No asistí a un programa de informática de élite en el que se enseñara Scheme y C, pero me apasionaba todo lo relacionado con la computación. En aquel entonces, nadie hablaba de la programación funcional. Vi una ola de programación entrando en el futuro; un futuro en el que los desarrolladores dedicaban más tiempo a pensar en el problema que estaban resolviendo que en cómo gestionarlo. Después de leer Diseño funcional, pienso que ojalá hubiese tenido este libro entonces y ahora, en cada fase de mi carrera, desde estudiante a profesional.

Diseño funcional tiene madera de clásico inmediato. Da la impresión de ser un libro escrito exactamente para el desarrollador de software profesional. Bob aborda los fundamentos de la ingeniería de software y los amplía, explicando en pocas palabras las cosas que he experimentado años. Abre el telón con elegancia para revelar cómo los elementos de la programación funcional hacen que el diseño de software sea simple, pero pragmático. Lo hace sin alienar a los programadores orientados a objetos experimentados que vienen de lenguajes como C#, C++ o Java.

Al introducir un análisis comparativo con Java, Diseño funcional presenta el diseño de sistemas funcionales con Clojure, un dialecto de Lisp. Clojure no es tan puro como Haskell, donde hay que utilizar conceptos de programación funcional pura. En su lugar, Clojure lo recomienda encarecidamente, haciendo que sea una gran primera opción como lenguaje funcional. Diseño funcional señala los obstáculos a los que se enfrentan los desarrolladores de Clojure de vez en cuando. Como asesora de Clojure, doy fe de ello. Este libro enseña a mantener un lenguaje (y al desarrollador) apartado del camino, en vez de buscar algo que se salga del camino.

Los críticos de Clojure dirán que este lenguaje es inadecuado para cualquier base de código bastante grande. Como aprenderá en los próximos capítulos, los principios y patrones de diseño se aplican a Clojure igual que a Java, C# o C++. Los principios de diseño de SOLID le ayudarán a crear un software mejor con la programación funcional. Los programadores funcionales se burlan de los patrones de diseño desde hace mucho tiempo, pero Diseño funcional desmonta estas críticas y muestra exactamente por qué los desarrolladores los necesitan y cómo pueden implementarlos en los suyos.

He escrito mucho en línea acerca de los patrones de diseño clásicos en Clojure, así que me encantó descubrir que este libro trata sobre el uso de patrones de diseño con diagramas razonados antes de mostrar código al lector. Para cuando llegue a esos capítulos, ya será capaz de imaginar el código de Clojure solo a partir de los diagramas. Después, seguirá el código. Por último, Diseño funcional lo une todo al hacer un recorrido por una aplicación «de empresa» en Clojure usando los patrones y principios de diseño.

—Janet A. Carr, asesora de Clojure independiente

Prefacio

Este es un libro para programadores en las trincheras que quieren aprender a utilizar lenguajes de programación funcional para hacer cosas reales. Por tanto, no voy a dedicar un tiempo notable a los aspectos más teóricos de la programación funcional, como mónadas, monoides, funtores, categorías y demás, no porque estas ideas no sean válidas, valiosas o relevantes, sino porque no suelen tener impacto en el mundo cotidiano del programador. Esto se debe a que ya se han incorporado a los lenguajes, bibliotecas y frameworks comunes. Si le interesa la teoría funcional, recomiendo los trabajos de Mark Seemann.

Este libro trata sobre cómo (y por qué) utilizar la programación funcional en nuestro trabajo diario para crear sistemas reales para clientes reales. En las páginas que siguen, vamos a comparar y contrastar estructuras de elaboración de código comunes en lenguajes orientados a objetos como Java con aquellas comunes en lenguajes funcionales como Clojure.

He elegido estos dos lenguajes en particular porque Java es muy conocido y utilizado, y Clojure es extraordinariamente fácil de aprender.

Breve historia de la programación funcional y por procedimientos

En 1936, dos matemáticos, Alan Turing y Alonzo Church, resolvieron de forma independiente uno de los famosos retos de David Hilbert: el problema de decisión. Describir este problema con detalle queda fuera del ámbito de esta introducción, salvo para decir que tenía que ver con encontrar una solución general para fórmulas de enteros.1 Esto es relevante para nosotros porque cualquier programa en un ordenador digital es una fórmula de enteros.

Los dos probaron, de modo independiente, que no existe tal solución general al demostrar que hay enteros que nunca podrían calcularse mediante una fórmula de enteros menor que el entero en sí.

Dicho de otro modo, hay números que ningún programa informático puede calcular. Y, de hecho, ese fue el enfoque que adoptó Alan Turing. En su famoso artículo de 1936,2 Turing inventó un ordenador digital y después demostró que había números que no podían calcularse, incluso aunque se dispusiera de tiempo y espacio infinitos.3

Church, por su parte, llegó a la misma conclusión a través de su invención del cálculo lambda, un formalismo matemático para manipular funciones. Mediante manipulaciones en la lógica de su formalismo, fue capaz de demostrar que había problemas lógicos que no podían resolverse.

La invención de Turing fue el antepasado de todos los ordenadores digitales modernos. Cualquier ordenador digital es, a todos los efectos, una máquina de Turing (finita). Cualquier programa que se haya ejecutado en un ordenador digital es, a todos los efectos, un programa de la máquina de Turing.

Más adelante, Church y Turing colaboraron para demostrar que sus enfoques eran equivalentes, que cualquier programa en una máquina de Turing puede representarse en cálculo lambda y viceversa.

La programación funcional es, a todos los efectos, programación en cálculo lambda.

Así pues, estos dos estilos de programación son equivalentes en un sentido matemático. Cualquier programa puede escribirse mediante el estilo por procedimientos (Turing) o el estilo funcional (Church). Lo que vamos a examinar en este libro no es esa equivalencia, sino las formas en que el uso del enfoque funcional afecta a la estructura y al diseño de nuestros programas. Intentaremos determinar si estas estructuras y estos diseños diferentes son, en algún sentido, superiores o inferiores a las que surgen del uso del enfoque de Turing.

Sobre Clojure

He elegido Clojure para este libro porque aprender un lenguaje y un paradigma nuevos es una tarea doblemente difícil. Por tanto, he intentado simplificar esa tarea eligiendo un lenguaje lo bastante simple para que no entorpezca el aprendizaje de la programación funcional y el diseño funcional.

Clojure es rico a nivel semántico, pero trivial a nivel sintáctico. Eso significa que el lenguaje en sí tiene una sintaxis muy simple que requiere muy poco esfuerzo para entenderse. Toda la curva de aprendizaje de Clojure está en la parte semántica. Las bibliotecas y modismos requieren un esfuerzo significativo para internalizarse, pero el lenguaje en sí casi no requiere esfuerzo. Tengo la esperanza de que este libro le proporcione una manera de aprender y apreciar la programación funcional sin que se vea distraído por la sintaxis de un lenguaje nuevo.

Dicho esto, este libro no es un tutorial acerca de Clojure.4 Explicaré algunos conceptos básicos en los primeros capítulos y utilizaré notas al pie explicativas a lo largo del texto, pero también confiaré en que usted, amable lector, haga los deberes y busque las cosas. Hay muchos sitios web que pueden ayudar. Uno de mis favoritos es https://clojure.org/api/cheatsheet.

El framework de pruebas que he utilizado en este libro es speclj.5 A medida que avancen los capítulos, veremos cada vez más al respecto. Es muy similar a otros frameworks de pruebas, así que, al pasar las páginas, no debería resultarle difícil familiarizarse con sus características.

Sobre arquitectura y diseño

Un punto de interés importante de este libro es describir los principios de diseño y arquitectura para sistemas construidos con un estilo funcional. Hacia el final, emplearé diagramas UML (lenguaje unificado de modelado) y haré referencia a los principios SOLID6 de diseño de software, los patrones de diseño,7 y los conceptos de la arquitectura limpia. No se asuste, explicaré las cosas a medida que avancemos y citaré muchas referencias externas por si necesita buscar algo.

Sobre la orientación a objetos

Muchas personas han expresado la opinión de que la programación orientada a objetos y la programación funcional son incompatibles. Estas páginas deberían demostrar lo contrario. Los programas, diseños y arquitecturas que verá aquí serán una mezcla de conceptos tanto funcionales como orientados a objetos. Según mi experiencia, y en mi firme opinión, los dos estilos son compatibles y los buenos programadores pueden, y deberían, aplicarlos juntos.

Sobre «funcional»

En este texto, utilizaré el término «funcional». Lo definiré y hablaré sobre él largo y tendido. A medida que avancen los capítulos, también me tomaré algunas licencias con él. Habrá ejemplos que, aunque estén escritos en un leguaje funcional y en un estilo funcional, no serán puramente funcionales. En la mayoría de esos casos, pondré entre comillas la palabra «funcional» y usaré notas al pie para indicar la licencia que me estoy tomando.

¿Por qué tomarme esa licencia? Porque este libro trata sobre la práctica, no la teoría. Me interesa más extraer los beneficios del estilo funcional que la adherencia estricta a un ideal. Por ejemplo, como veremos en el primer capítulo, las «funciones» que toman la entrada del usuario no son puramente funcionales. Sin embargo, haré uso de esas «funciones» como sea apropiado.

El código fuente para todos los ejemplos de todos los capítulos está en un único repositorio de GitHub llamado https://github.com/unclebob/FunctionalDesign.

1 Ecuaciones diofánticas.

2 Turing, A.M. (1936). «On Computable Numbers, with an Application to the Entscheidungsproblem».

3 Si se dispone de tiempo y espacio infinitos, un ordenador podría calcular π o ϵ o cualquier otro número irracional o trascendental para el que exista una fórmula. Lo que demostraron Turing y Church es que hay números para los que no puede existir tal fórmula. Esos números son «incomputables».

4 Para cuando lleguemos al final, creerá que soy un mentiroso.

5https://github.com/slagyr/speclj.

6 Martin, R.C. (2018). Arquitectura limpia. Anaya Multimedia (p. 67).

7 Gamma, E., Helm, R., Johnson, R. y Vlissides, J. (2002). Patrones de diseño: Elementos de software orientado a objetos reutilizables. Addison-Wesley.

Parte I

Conceptos funcionales básicos

1

Inmutabilidad

2

Datos persistentes