viernes, 26 de agosto de 2016

Algunas funciones útiles en javascript

Esto de cambiar de trabajo es muy interesante, la verdad es que uno está acostumbrado a cierto ritmo y al cambiar de trabajo tu día cambia mucho desde tomar otra ruta para llegar a la oficina, levantarte en un horario distinto hasta conocer gente distinta, reencontrarte con los antiguos camaradas, regresar a programar activamente y bueno pues como en todo encontrar problemas distintos a los ya habituales, un ritmo de trabajo distinto, un negocio distinto y cosas nuevas por aprender.

Dentro de estos cambios me ha tocado entender AWS, lo que ofrece y como manejar lo que tiene (en mi primer semana instalé dos veces en producción), algo de spring que ya tenía un poco empolvado y lo que más me ha costado, reencontrarme con los html, javascript y css, esos fueron mis amigos en mi primer trabajo hace mas o menos 10 años y desde entonces no me había tocado trabajar activamente en el front end de aplicaciones web de esta manera pues en Tralix me la pasé más con GWT, un poco de echo2 y muy poco de struts.

Y como parte de mi aprendizaje he estado viendo algunas cosas en javascrip que me llamaron la atención, en particular las funciones find, filter, map y reduce (que aún no he ocupado pero que ya son parte de mi toolbox) y de esas funciones es de lo que quiero hablar en este post. Comencemos con el arreglo definido de la siguiente manera:

mascotas = [
{
'nombre'  : 'max',
'especie' : 'perro',
'raza'    : 'dálmata',
'edad'    : '3',
'sexo'    : 'macho'
},
{
'nombre'  : 'yoshina',
'especie' : 'perro',
'raza'    : 'dálmata',
'edad'    : '5',
'sexo'    : 'hembra'
},
{
'nombre'  : 'luneta',
'especie' : 'perro',
'raza'    : 'dálmata',
'edad'    : '4',
'sexo'    : 'hembra'
},
{
'nombre'  : 'simba',
'especie' : 'perro',
'raza'    : 'dálmata',
'edad'    : '1',
'sexo'    : 'macho'
}
]

Find

La función find nos sirve para encontrar un elemento en un arreglo, por ejemplo si queremos encontrar a max dentro del arreglo lo que tenemos que hacer es:

max = mascotas.find(function(mascota) {
return mascota.nombre == 'max'
})
console.log(max)

y lo que nos va a imprimir en la consola es a max.

Filter

La función filter la usamos para obtener un sub arreglo del arreglo original, por ejemplo si queremos encontrar a todos nuestros perros machos lo que tenemos que hacer es:

machos = mascotas.filter(function(mascota) {
return mascota.sexo == 'macho'
})
console.log(machos)

en este caso nos imprimirá en la consola un sub arreglo conteniendo a max y a simba.

Map

La función map se usa cuando queremos transformar un arreglo en otro, esta es una función muy útil cuando se trabaja en un cliente de servicios REST ya que normalmente lo que el servicio nos trae son cosas generales y tal vez nosotros no queremos operar sobre todos los datos, sino sobre sólo algunos, espero esto no sea confuso, pero bueno, para que quede mas claro vamos a transformar nuestro arreglo de mascotas en un arreglo de edades de la siguiente forma:

edades = mascotas.map(function(mascota) {
return mascota.edad
})
console.log(edades)

Lo que nos imprime en la consola es el arreglo de las cuatro edades de nuestros perros (transformamos un arreglo de mascotas a un arreglo de edades).

Reduce

La función reduce normalmente la ocupamos cuando queremos generar un "sumarizado" o un resultado "agregativo" (jeje no supe como decirlo) sobre un arreglo, para que sea mas claro veamos el ejemplo:

cachorros = mascotas.reduce(function(total, mascota) {
if (mascota.edad <= 1)
return total +1
else 
return total
}, 0)
console.log(cachorros)

la salida a la consola que obtenemos es la cantidad de cachorros que hay en nuestro arreglo (los que son menores o igual a 1 año de edad), y la forma en que opera es que va iterando el arreglo, para cada elemento checa la edad de la mascota y si es un cachorro suma 1 al total, por cierto ese 0 "cero" extraño que se ve al final de la llamada a la función reduce es el valor inicial del total.

Lo bonito de esto es que muchas de estas funciones existen dentro de prácticamente todos los lenguajes funcionales y nos ayudan no solo en la programación del front end en javascript.

Otra cosa a hacer notar es que todas estas funciones reciben como uno de sus parámetros una función, esto las hace muy poderosas y reusables ya que por ejemplo si quieres obtener a los adultos (en el ejemplo del reduce) lo único que tienes que hacer es cambiar a función que recibe el reduce como parámetro, lo que se hace es sacar la función a por ejemplo:

cachorros = function(total, mascota) {
if (mascota.edad <= 1)
return total +1
else 
return total
}

y tener otra función:

adultos = function(total, mascota) {
if (mascota.edad > 1)
return total +1
else 
return total


y pasar uno u otra al reduce:

numero_cachorros = mascotas.reduce(cachorros(total, mascota), 0)

o

numero_adultos = mascotas.reduce(adultos(total, mascota), 0)

Con esto se ilustra una de las bondades de la programación funcional, el poder enviar funciones como parámetros.

Este post nos sirve como capítulo introductorio a la programación funcional, de la que estaremos hablando poco a poco.

sábado, 6 de agosto de 2016

Single responsibility principle (parte 2)




Esta es la segunda parte de mi post sobre SRP, en la primer parte comentamos que es y una de las formas en que nos afecta, esta vez hablaremos de otra forma en que nos afecta y veremos algo de código, así que agaaaarrrrrrense...

Primero una de las cosas que hay que tomar en cuenta es que el software y en particular las clases en POO son una representación del negocio, por lo que es una forma muy habitual de "encapsular" ese negocio el crear una clase por ejemplo EmployeeBusiness en donde se mete todo lo que tiene que ver con el empleado, a simple vista esto es correcto ya que coo decimos, representa el negocio, pero el problema es que lo estamos viendo desde el punto de vista de la entidad y ahí es donde esta jodido este asunto, que va a pasar con esta clase?

1. Va a crecer enormemente dado todas las operaciones que se pueden hacer con el empleado.
2. Va a tener un montón de dependencias por lo que se corre el riesgo de un alto acoplamiento.
3. Va  tener muchos motivos por los cuales puede cambiar, y acá es donde se rompe este principio.

Pero entonces como CREO YO que se deben de hacer las cosas? bien, pues afectivamente separar bien las cosas de acuerdo al negocio, por ejemplo una clase para manejar las vacaciones del empleado, otra para el cálculo de su nómina, otra para cuando se da de baja y así, como se dan cuenta la separación es efectivamente por negocio y nos damos cuenta ya que cada una de estas clases tiene un "stakeholder" específico y no necesariamente el mismo, por ejemplo la gente de RH es el "encargado" de las modificaciones a las reglas de vacaciones, la gente de nómina es el "encargado" de las modificaciones a las reglas de cálculo de nómina y así sucesivamente. Así tendremos las siguientes características en cada clase:

1. Se hacen pequeñas ya que cada una sirve a un propósito my específico.
2. Las dependencias disminuyen al sólo tener las necesarias para realizar su trabajo.
3. Sólo tiene un motivo por el cual va a cambiar y no sólo un motivo, sino un solo rol que dicta que cambia cómo y porqué.
4. Es mucho más fácil de probar.
5. Cumple con una alta cohesión.

Un ejemplo de este principio lo pueden ver en mi post de patrón decorador para validar en el que las responsabilidades están muy bien definidas y son totalmente independientes cada una de las clases.

Ya se que les prometí código en este post, pero creo que la explicación es lo suficientemente buena como para convencerse de que vale la pena que nuestras clases cumplan con este principio y les dejo la liga mi post donde pueden ver la aplicación de una forma muy clara y sencilla.