Incomprehensible Finder Kata en PHP – Colecciones y funcional λ

Un tiempecillo atrás vimos vimos cómo encarar esta kata en PHP y también cómo resolverla utilizando Scala. Hoy vamos a demostrar que con PHP también se pueden hacer cosillas funcionales y que encima hacen que nuestro código quede bastante más cohesionado, inmutable, guay, y simple! 😎

Recordad que tenemos publicado el repositorio con las soluciones que hicimos en el evento de la Software Craftsmanship Barcelona, las Pull Request son bienvenidas!

En esta iteración os presentamos las colecciones (y vemos cuándo y por qué nos son útiles) y también haremos nuestros primeros pinitos en la programación funcional haciendo uso de una librería con un nombre muy original: phunctional.

Os recordamos que la kata trata sobre refactorizar un código ya existente y con una base de test, pero que no hay quien lo entienda. 🙂

 

Colecciones

Las colecciones son un concepto simple y que hemos hecho toda la vida sin saber cómo se llamaban 😇.

Una colección no viene a ser nada más que un array de un mismo tipo de objeto que nos sirve para cohesionar la lógica que le pertenece. Imaginaos que queremos obtener todos los usuarios nacidos después del 1950 de un listado de usuarios. Tradicionalmente lo hubiésemos hecho tal que así:

Quizás estamos acostumbrados a hacerlo así de toda la vida y jamás nos hemos parado a pensar en la de problemas que esto nos acarrea. Algunos de los problemas, entre otros, que nos pueden aparecer:

  • Duplicidad de código: Si dos puntos de nuestra aplicación necesitan la misma lógica la estemos copiando y pegando.
  • Ofuscación de funcionalidad: No sabemos de simple vista qué operaciones estamos realizando sobre los conjuntos de usuarios (falta de cohesión).
  • Facilidad a que se cuelen errores en el código: Imaginaos que alguien sin querer mete un Product en lugar de un User. Empezaríamos a reventar en el momento que se llamase a un método que existe en User y no en Product (PHP FTW 🤘).
  • Responsabilidad lejos de su dominio: Tenemos la lógica de gestión de usuarios en servicios externos en lugar de, al igual que hacemos con los Value Objects, cerca de donde sucede la acción (nuevamente, cohesión).

Pero todo esto tiene una solución muy simple: El uso de Colecciones. Recordemos, una colección es una clase que contiene un array de un mismo tipo de objeto, y tiene la lógica encargada de gestionarla allí dentro. Un ejemplo de colección para usuarios podría ser:

Aquí vemos algunas cositas nuevas, entre ellas el CodelyTip del día: Los variadic arguments. Este (User …$users) viene a ser el equivalente a “todos los argumentos que me pases me los metes en un array llamado $users”, por lo tanto, al ejecutar new Users(new User(1999), new User(1800), new User(1337)) estamos creando un array llamado $users que contiene esos usuarios que hemos creado (fijaos que hemos pasado los parámetros como diferentes argumentos, no hemos enviado en ningún momento un array).

Otra cosita que vemos que nos puede confundir es el type hinting que hay de User delante de los tres puntitos, esto significa que todos los argumentos que recibimos han de ser de tipo User. Con esto tenemos nuestro array asegurándonos que siempre nos pasan usuarios y no otra cosa de por medio 💪.

Gracias a esto ahora podemos obtener todos los usuarios aplicando una determinada lógica de una manera más simple, encapsulada y cómoda.

 

Funcional

Si volvemos al ejemplo anterior:

Podemos ver que el método bornAfter tiene una complejidad ciclomática muy alta. Vamos, que tenemos una asignación dentro de una condición, que a su ves está dentro de un bucle. Esto hace que nuestro código no quede nada simple y que cueste más de entender. Una de las manera de ayudar a mejorar esto es traernos uno de las principios ampliamente extendidos en programación funcional: La inmutabilidad. Lo que promueve la inmutabilidad es evitar ir modificando el estado (una vez ya has asignado un valor a una variable, no la vuelves a reasignar).

En este caso, la función que más bien nos iría sería el filter, una función que recibe un array y te devuelve otro aplicando un filtro (el nombre hace juicio a su función 😬).

Utilizándola nuestro código quedaría:

Un código mucho más simple (que no fácil, sobretodo si no estás acostumbrado), pero que se lee mucho mejor. Además, nos puede ser útil ir adoptando este tipo de prácticas si queremos transicionar a un lenguaje de programación funcional como Scala. Si es el caso, ¡no te pierdas el vídeo de introducción a Scala!

 

Si has disfrutado de esta kata y ves margen de mejora, agradeceríamos infinito que lo compartieras a través de un comentario en el vídeoTwitter, o incluso, una PR al repo 🚀🦄

SHOWHIDE Comments (0)

Leave a Reply

Your email address will not be published.