martes, 18 de octubre de 2016

Que cosas hacen de Scrum?


Este post ya tiene rato en la congeladora, así que espero recordar bien lo que quería transmitir con él en ese momento de mi vida.

Hace unos meses alguien me hizo esta pregunta, ¿Qué hacen de Scrum?, la cuál me llamó mucho la atención ya que esta es una pregunta que normalmente hace alguien que no conoce de metodologías ágiles de desarrollo de software, mucho menos de Scrum, normalmente estas personas sólo han oído hablar, han leído del tema o los han "obligado" a la mala a "usarlo", por eso es que a ellos les hace sentido esa pregunta.

A parte de esto lo que yo leo en esta pregunta es desinterés y rechazo sobre el framework en sí ya que aunque se ha tenido el contacto no se ha tenido las ganas de de verdad conocerla y poder ver mas allá de su "uso".

Pero bueno, en ese momento puse mi cara de what? la sangre me hirvió y me dieron ganas de platicarle lo que realmente significa y que no es algo que se "usa", sino algo que se interioriza y se vive hasta el punto de convertirse en uno de tus principios de vida (ya se que suena muy mamón, pero de verdad que así es) pero pude contenerme y lo que me salvó fueron las siguientes preguntas de esta persona, las cuales me ayudaron a desafanarme del tema muy rápidamente, ¿sólo hacen junta diaria y ya verdad? y ¿también hacen sprints no? a las cuales mis respuestan fueron "heee (dudando) aaa si, solo eso hacemos", ya se que estuvo mal, pero en ese momento no quería entrar en discusiones ni detalles, solo me quería desafanar.

Gente, scrum no se usa, es un modo de ver el mundo, ágil en general lo es, si recordamos uno de los principios ágiles que dice:
"At regular intervals, the team reflects on how 
to become more effective, then tunes and adjusts 
its behavior accordingly"
Nos habla sobre lo que en scrum conocemos como retrospectivas, esto en lo personal me ha ayudado mucho a mí en vida de portero, cada vez que acaba un partido paso por mi mente una y otra vez los goles que me metieron y así visualizar que es lo que hice mal y que pude haber hecho en ese momento que me hubiera ayudado a que el balón no terminara en las redes. Parece algo simple, pero así es, y este es sólo un ejemplo de como es que yo "uso" scrum en mi vida.

Ahora, ven como es que esto se vuelve parte de tus principios, en este caso, la reflexión y la mejora continua.

A mis lectores, en verdad les recomiendo que lean, escuchen, vean, se involucren y entiendan lo que scrum y ágil en general les puede dejar en sus vidas, por la red rondan muchos sitios donde no sólo hablan de ágil en desarrollo de software, sino en la vida cotidiana por lo que aún si no te dedicas a la profesión de los 0's y 1's estaría muy bueno que le des una pasada, al menos para que no se te ocurra preguntar ¿Que cosas hacen de Scrum?.

Un abrazo a todos.

lunes, 5 de septiembre de 2016

Reduce regresando un objeto


La semana pasada escribí acerca de algunas funciones útiles en javascript, una de ellas es mas interesante de lo que parece, ésta es la función reduce, en ese post comentamos que lo usamos cuando tenemos que generar un sumarizado de un arreglo, en ese momento hicimos el conteo (sumarizado) de cachorros y de adultos, en sí esta forma es útil, pero a veces lo que queremos no es un sumarizado numérico, sino crear un objeto y que él sea el sumarizado.

Reduce nos sirve también en este caso de uso ya que la función también puede regresar el sumarizado como un objeto, no solo como un entero.

Otra cosa que mencioné es que no me había tocado usar alguna de estas funciones, pero ya en esta semana que pasó me tocó usar reduce, el caso de uso fue el siguiente:

Tengo un arreglo de bancos con los bines de tarjetas de crédito, en este caso lo que necesitaba es un arreglo de los bancos que tengo en la lista, por lo que usé la función reduce para "reducir" (sumarizar) el arreglo de bines de bancos en un arreglo de bancos, el código es como sigue:

var bines = [{"bank":"banco1","bin":"111111"},
     {"bank":"banco1","bin":"122222"},
           {"bank":"banco1","bin":"133333"},
     {"bank":"banco1","bin":"144444"},
          {"bank":"banco2","bin":"211111"},
     {"bank":"banco2","bin":"222222"},
     {"bank":"banco2","bin":"233333"},
     {"bank":"banco3","bin":"311111"},
     {"bank":"banco3","bin":"322222"}];

var reduced_banks = bines.reduce(function(banks, bin) {
isAlreadyAdded = banks.find(function(bank) {
return bank == bin.bank;
})
if(!isAlreadyAdded)
banks.push(bin.bank);
return banks;
}, []);
console.log(reduced_banks);

lo que sale a la consola es:


[ 'banco1', 'banco2', 'banco3' ]

Esto es, el listado de bancos.

Ahora, explicando un poco lo que sucede, tenemos un arreglo de bines en el que se repiten los bancos y lo que queremos es sólo el arreglo de bancos, lo que hacemos es usar la función reduce mandándole una función que recibe el objeto contenedor del sumarizado (banks) y el elemento actual de la lista original (bin), enviándole también a la función reduce un arreglo vacío como último parámetro ([]) que es el valor inicial de banks, luego reduce aplica a cada elemento del arreglo bines la función que le enviamos como primer parámetro donde lo que hacemos es buscar en el arreglo de bancos (banks)
si ya existe el banco del elemento en el que estamos de bines y si no ha sido agregado antes se agrega al arreglo banks (objeto simarizador). Como ven, también find es aplicado sobre un arreglo, en este caso banks y lo que hace es iterar sobre cada elemento del arreglo y a cada elemento le aplica la función  que le mandamos como parámetro y que regresa true si el arreglo ya contiene banco del elemento actual de bines.

Espero que este ejemplo sea didáctico en el uso de reduce y find, en este ejemplo el objeto sumarizador es un arreglo, pero bien puede ser cualquier otro tipo de objeto.

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.



sábado, 23 de julio de 2016

Single responsibility principle (parte 1)

Este es el primer post para comentar a cerca de los principios SOLID, en esta ocasión nos enfocaremos en el principio de Single responsibility o Responsabilidad única (la S en SOLID), como ya comentamos en un post anterior los principios de son ciertas características (de diseño) que el desarrollo de software orientado a objetos debe de cumplir para que se diga que está bien estructurado y que ayuda a que el codigo sea entendible y por ende matenible, así que eso es lo que abordaremos en este post enfocandonos al principio de responsabilidad única.

Bien se dice por alli que el que mucho abarca poco aprieta, pues bien, esto llevado a la programación orientada a objetos es éste principio, en el que se describe que una clase debe de tener una única responsabilidad y no más que esa, como nos damos cuenta de que nuestra clase cumple con ella? pues esto es coo muchos dice, cumple con ella si es que tiene una única razon por la que tiene que cambiar, si es así entonces se dice que tiene una sola razón de ser y si esa razón de ser cambia por alguna razón entonces la clase debe de cambiar, pero sólo por eso deber de hacerlo.

Ahora este principio no solo se refleja en clases, sino en métodos, variables, paquetes, componentes y hasta sistemas, como es esto? pues bien, una variable debe de existir para solo una cosa, esto nos lleva a un buen nombramiento de la variable y esto es parte de clean code, esto es si se tiene una variable por ejemplo nombrada x que es de tipo Integer, en si el nombre no nos dice nada, por lo que estaremos tentados a usarla para lo que se nos antoje dentro de nuestro sistema, pudiendo usarla para almacenar la edad de un empleado, como índice para iterar el arreglo de percepciones del empleado (lo bueno es que ese arreglo no es muy grande jeje), etc. esto nos lleva a problemas muy graves de mantenimiento del código, lo que provoca que existan bugs, lo que provoca que nuestros clientes se quejen de lo que hacemos, lo que provoca que la empresa pierda dinero (o reputación), lo que provoca que se pierda la confianza en el desarrollador, lo que provoca que nos despidan, lo que provoca que nos atrasemos en el pago de nuestro lujoso carro (que sacamos a crédito augurando una buena carrera) lo que provoca... bueno, creo que ya di a entender el punto y todo esto por nombrar mal una variable, pero que pasa si a esa variable le nombramos employeeAge, pues ya sabemos que esa variable representa a la edad del empleado y estaremos menos tentados a usarla para almacenar algo distinto a la edad del empleado.

Si se dan cuenta, esta variable tiene una única responsabilidad que es almacenar la edad del empleado, ahora, esto aplica igual para métodos, éstos tambien deben de tener una única responsabilidad, por ejemplo el método que calcula los dias de vacaciones que tiene un empleado, esa es su responsabilidad, no la de ir a la base de datos por las reglas de vacaciones configuradas por el departamento de RH, ni ir a la base de datos para obtener la fecha de ingreso del empleado, este método sólo debe de hacer el cálculo y ya, no más que eso, en cuanto a una clase, pues como ya lo han de intuir, aplica igual ya que ésta solo se debe de encargar de algo en específico y delegar lo más que se pueda a otras clases que podrá usar o desde las que podrá ser usada para lograr un objetivo más general, en paqutes pasa lo mismo por ejemplo un paquete que tega las clases necesarias para la sección de nómina de los empleados que incluye clases para el cálculo, para extracción de datos, excepciones probables y demñas cosas que tienen que ver con la nómina, mas arriba, al sistema completo, que tiene que tener una resposabilidad única que es manejada por la gente de negocio de nuestra organización.

Últimamente se ha escuchado mucho sobre los microservicios, ellos son un ejemplo de responsabilidad única a nivel de deployable y de sistema pues de lo que se tratan es de que cada parte sea los mas independiente posible y tiene una responsabilidad muy específica llegando incluso a ser instalada de forma independiente a las demás características del sistema completo, teniendo su propia base de datos, su propio ambiente, tal vez hasta estar hecho en un lenguaje distinto a los demás y estar instalado en un servidor virtual en la india.

Pues bien, hasta acá le dejamos en la primer parte del Single responsibility principle, espero que se haya entendido de que se trata y que se puede extender mas allá a sólo clases.

En el siguiente post hablaremos de forma mas puntual de este principio con código de ejemplo y toda la cosa.

domingo, 10 de julio de 2016

La meta

Hace tres semanas tenía pensado escribir acerca de La meta (el libro que acababa de leer) pero al empezar a escribir vi necesario decir cómo es que ese libro llegó a mi y eso me llevó a escribir sobre el reto que me había puesto de 1 libro por mes, así que borré lo poco que tenía y empecé a escribir acerca del reto, luego pensé que era difícil que entendieran ese reto si no hay un contexto, así que decidí empezar dando ese contexto y borré lo poco que tenía del reto y así fue que salió el post de la lectura, luego, la siguiente semana no escribí debido a que anduve algo enfermo de la garganta y luego la semana pasada acabó mi ciclo en Tralix, por lo que decidí escribir un poco sobre unos pensamientos que me llegaban mientras me alejaba del lugar que fue como mi hogar por poco mas de 8 años. Así que ahora si... hablaremos de "la meta".

La meta es un libro que llegó a mí por que Ana me lo recomendó, en ese momento dije "va, solo acabo el que tengo ahorita leyendo, luego el que tengo ya formado y ya luego lo empiezo, pero va..." así fue, terminé el libro 1 de caballo de Troya, luego the pragmatic project automation y empecé con la meta, cabe mencionar que tengo la mala maña de que cuando empiezo un libro lo leo desde la portada hasta la contraportada y me llamó la atención el tipo de comentarios que ponían en las primeras secciones, eso me dio curiosidad y ánimo para leerlo.

Solo haré un pequeño resumen del contenido, los que están en Tralix pueden ver con Ana si lo tiene disponible para préstamo, los que no, lo pueden conseguir en Amazon el el título de "LA META" o "THE GOAL" (para la versión en inglés). Este libro cuenta una "novela", donde se narran 3 meses de la vida del encargado de una planta manufacturera que a su vez es esposo, padre e hijo, que como muchos de nosotros tiene problemas por todos lados, es decir, ya no ve lo duro, sino lo tupido, Alex es en cargado de una planta desahuciada a desaparecer dados los malos resultados que da a la compañía, estos problemas acarrean a Alex a problemas con su pareja, de la que se separa por un tiempo, al inicio no sabe que hacer para salvar la planta hasta que recuerda una plática con su ex profesor de física de la universidad acerca de "la meta", luego él junto con algunos compañeros de trabajo y con ayuda de Noha (su ex profesor) van viendo cuales son los problemas de la planta y van viendo como solucionarlos llegando al final a ser una planta exitosa y Alex a ser ascendido, pero lo interesante no es esa parte de la novela, sino los conceptos que se describen y como llegan al éxito, así como el cambio de paradigma que proponen y es de esto de lo que me gustaría hablar en este post.

Primero, al leerlo me vi reflejado en Alex por que su vida personal reflejaba la mía de hace unos años y que creo que la mayoría de nosotros tenemos cuando tenemos que dedicarle tiempo al trabajo que debería de ser dedicado a nuestras familias y que llegas a la casa y en tu mente están los problemas del trabajo, buscando soluciones y no dejando disfrutar la vida fuera.

Luego habla sobre la meta de una compañía que es muy difícil de captar pero que al final de cuentas es ganar dinero, bajo eso como meta cada compañía tiene una forma distinta de llegar a ganar dinero, es allí donde se ve la dirección, las estrategias de cada sección, todo enfocado hacia eso, por lo que lo que sea que se haga debe de estar encaminado a esa meta, pero el problema es que muchas veces la forma de esa estrategia no es la adecuada, en el caso de la compañía de Alex, miden la productividad por sección, lo cual como se ve allí no es lo mejor, lo mismo pasa en muchas otras empresas, incluidas las de desarrollo de software donde a leguas se ve que no es la mejor forma de medir, ya muchos en ésta área han escrito de esto, llegando a estar de acuerdo en que la productividad de un desarrollador no se basa en las líneas de código que genera, o el tiempo que pasa sentado frente a su monitor, o la cantidad de bugs que resuelve, ni siquiera en la cantidad de features que genera... se debería de basar en la cantidad de dinero que ese nuevo feature le entrega a la compañía o en la cantidad de dinero que al solucionar el bug le está ahorrando a la compañía, es decir, en el valor de negocio EFECTIVO. Es aquí donde el concepto de contabilidad de costos tuerce el rabo, ya que no mide de esa forma, sino (en el caso de desarrollo de software) a cuanto tiempo le dedicas a solucionar un bug o a que hay mas? bugs o features? y eso  al final no es una métrica que ayude a "la meta".

Otro concepto interesante que mencionan en el libro es la fluctuación estadística, que es la variación que hay en hacer una tarea, por ejemplo el empleado A tarda 5 minutos en hacer una tarea, mientras que el empleado B tarda sólo 3 y el empleado C tarda 6, la fluctuación estadística es esa variación, que en manufactura puede llegar a ser algo estándar y controlable de alguna manera, pero en desarrollo de software es enorme debido a que es un proceso mas artesanal, intelectual, de feeling que un proceso mecánico, acá otro problema en el manejo de las empresas de software donde para hacer una tarea se piden tiempos fijos, escritos en piedra y firmados con sangre y que la gente administrativa, los vendedores, los directores no entienden y no ven como es posible que esas fechas nunca se cumplan teniendo que jugar con el triángulo de alcance, calidad y recursos, hay una corriente dentro del desarrollo de software que precisamente trata de atacar esto, que es no estimation.

Por último quiero mencionar otra idea interesante que se trata en el libro, que es que en términos de la meta, no necesariamente todos los recursos deben de estar produciendo todo el tiempo, de hecho esto es contraproducente... en términos de la meta, esto es, a veces (la mayoría de las veces) para llegar a la meta es muy recomendable que hayan recursos (materiales, maquinaria, equipo) y personas sin hacer nada, holgazaneando, echando la hueva, yendo a fumar, viendo los partidos de la euro, etc. esto por qué? por que de no ser así se causa un sobre inventario o una sobre carga inmanejable en ciertas secciones; esto, de nuevo, es algo que los managers no entienden y es uno de los cambios culturales más difíciles de hacer, ya que estamos acostumbrados a siempre tener a la gente ocupada (aunque no sea beneficioso en términos de la meta), haciendo algo, por que?, pues por que les pago por 8 horas de trabajo y no quiero obtener menos que eso, a esto le llamamos horas nalga, es decir, lo importante es que estés sentado frente a tu escritorio, pero como lo dice el libro y el sentido común, esto no es lo mejor, ya que si no ayudas a la meta, no tiene caso que lo hagas, por lo que lo mejor es que las cosas que se hagan estén bien pensadas y hay que aprovecharlas al máximo en términos de la meta. Acá en desarrollo de software esto se acrecienta aún más por que no sólo es que a veces es necesario que la gente no produzca, sino que como ya comentamos antes, es una actividad más parecida al arte que a otra cosa y esto implica que se debe de tener un ambiente adecuado para que fluyan las ideas y que el estado de ánimo sea el mejor para poder logra este fin, esto es, si es necesario que vean un partido de la euro para que el estado de ánimo sea el adecuado... hay que poner el partido de la euro y permitirles que lo vean sin problemas, pero esto, de nuevo, es un cambio cultural en el manager muy difícil de tener.

Ahora sí, por último, me llamó la atención cómo fue que Alex y su equipo se ganaron a un cliente muy importante, ofreciéndole entregas en partes de su pedido, con lo que pudieron cumplirle al cliente, ganaron dinero, se ganaron al cliente y le ahorraron dinero al cliente en inventarios, si, así es, hicieron sprints y entregas continuas, tenían reuniones de mejoras continuas, se enfocaban en darle valor al cliente ¿les suena?, así es, era algo muy similar a ágil, por lo que en la industria también funciona ( de hecho también existe esa corriente como "lean manufacturing").

En verdad les recomiendo ese libro, vale mucho la pena, como novela, como proceso de producción (introduciendo la teoría de las restricciones) y para los que estamos dentro del desarrollo de software, como marco conceptual del desarrollo ágil.

PD: Anita, muchas gracias por prestarme el libro, espero que cuando leas management 3.0 te sigan haciendo clic las ideas de la meta.

sábado, 2 de julio de 2016

El titulo que importa

Ayer fue mi ultimo día en mi empleo anterior y mientras iba  caminando hacia la casa de mi  mamá para recoger mi moto iba pensando en lo que dejé ahí, una de las cosas que dejé es un producto estable el cual considero como mi hijo ya que estuve yo involucrado desde la concepción, pasando por su salida a producción, tuvo (como cualquier otro hijo) su tiempo de rebeldía en que no nos aguantó la carga gracias a la cantidad de usuarios que tenía, menosprecio de algunas personas hasta llegarlo a ver como un producto muy estable y que deja una buena cantidad de dinero a la organización, pero bueno esa es otra historia que contaré luego; otra de las cosas que iba pensando es en ¿qué le dejé a las personas?, en particular a mi tribu, a mi equipo de desarrollo, mis chavos... al final es muy difícil que yo lo diga pues eso es algo que ellos dirán o al menos lo pensarán (si algo les dejé o no) y de allí salió este post.

Hay que hacernos la pregunta ¿los títulos importan?, socialmente, me queda claro que importan, algunas veces me tocó que por que visto de tenis, pantalones rotos, cabello largo "despeinado" y barbudo como rey mago la gente no me tomaba tan enserio, hasta que por alguna razón llegan a preguntar mi puesto en donde trabajo y decía (con pena) "gerente de desarrollo" y en ese momento el  trato cambiaba, eso nunca me gustó ya que soy creyente en la igualdad y en el  valor de las personas sin importar como vistan, como se vean, donde trabajen o que puesto tienen pero algo me quedó claro, socialmente los títulos importan, lo  bueno de ser yo es que eso a mi no me importa.

Bueno pasando al tema real del post hay títulos que uno tiene solo "por que si" o por que un "tercero" te dio o por que las circunstancias así fueron como el título de jefe, el de padre, el  de marido, el de responsable del equipo de fut, cuñado, primo, hermano, etc, pero esos títulos realmente de algo sirven? o que peso tienen en nosotros y en la otra persona?. Bien pues en lo que yo creo que es mejor un título que alguien te "da" y que no tienes solo "por que si" en vez de ser jefe yo prefiero ser líder, en vez de padre yo prefiero ser ejemplo, en vez de marido yo prefiero ser su amor, en vez de el responsable del equipo de fut yo prefiero ser el líder,  en vez de ser el cuñado, primo o hermano yo prefiero ser el amigo; pero por que? por que creo que un título que te da "el segundo en cuestión" (como el título de líder) por convicción es muchísimo mas importante que el que te da un "tercero" (como el título de jefe) o el que se da solo por que así es como  se le conoce "socialmente" (como cuñado).

Por último, que peso tiene esto? bien pues lo que hace es que genera un compromiso mucho mayor y un apego  mucho mayor de las dos partes, por  ejemplo el titulo de líder hace que la gente te siga, que hagan las cosas no por que tienen que hacerla, sino por que están comprometidos moralmente contigo, porque saben que ese sentimiento de respeto y de confianza es mutua, por que lo hacen por ti y de esta forma se llega a una sinergia impresionante en que las dos partes hacen hasta donde pueden por la otra parte, por el "segundo en cuestión".

Bien pues espero que esto nos haga pensar en los títulos que tenemos en todos los ambientes en que nos desenvolvemos y queramos tener los títulos que en verdad importan.

Por cierto y ahora si ya por último, déjenme decirles que para mi el  título que mas vale, el que es muy difícil de ganarse,  pero que cuando lo tienes es lo  máximo es el título de amigo. Y a mis amigos... gracias por ello.


saludos.

domingo, 19 de junio de 2016

La lectura

Desde chico en casa estaba acostumbrado a ver libros, entrar a la "biblioteca" de la familia, un cuartito lleno de libros, revistas, artículos que tenían mis papás en él, a veces en las noches ver a mi papá acostado en la hamaca leyendo algo, algunas veces yo le preguntaba que leía y sentía real curiosidad por saber, pero nunca fue algo que me llamara la atención en demasía (como la mayoría de los niños en el pueblo yo me la pasaba en la calle jugando, vagando y haciendo una que otra travesura), así pasó la primaria, la secundaria, luego nos venimos a vivir a Querétaro (de donde soy originario), pasó el bachillerato, luego la ingeniería y nop, nunca me sentí muy atraído a los libros; bueno realmente si leía pero solo lo necesario para entender los temas y asignaturas de la escuela, así leía sobre Platón, Sócrates, Calculo, programación, etc. pero siempre por cuestiones académicas.

Empecé a trabajar, el hábito de la lectura continuaba igual, sólo leía artículos para poder "sacar" lo que me pedían en el trabajo, luego cambié de trabajo (mi actual trabajo) y pues todo seguía igual en ese ámbito, luego Rox empezó a traer libros al trabajo, una vez, hace como unos 3 años yo creo, nos trajo uno escrito por su esposo, dije bueno... vamos a leerlo, así empecé, leyendo cuentitos, luego me prestó otro libro donde igual su esposo era coautor y así continué, leyendo pequeñas historias, luego mi gran reto fue Canek de Emilio Abreu Gómez y así empecé con los libros, desde lectura técnica para el ámbito del desarrollo de software hasta algo de ciencia, pasando por novelas, así conforme me han ido recomendando lecturas las he tomado.

Al iniciar este año me puse un reto, como muchos más que me pongo a mi mismo siempre, y esta vez fue leer un libro cada mes, así empezó enero con cometas en el cielo (recomendado por Albaneth), febrero con el libro de los abrazos (recomendado por Armandiurix), marzo con las uvas de la ira (recomendado por Armandiurix), abril con el caballo de troya (éste mi papá lo tenía, alguna vez intenté leerlo pero no pude, pero siempre ha estado en mi mente leerlo), mayo pragmatic project automation, junio con La meta (recomendado por Ana), por ahora voy bien según el plan, 6 meses, 6 libros leídos y me he dado cuenta que me gusta esto de la lectura de todo tipo, como siempre he sido de mente abierta me es fácil digerir las letras, entender la trama e imaginar la historia, el viernes pasado terminé el libro de junio, así que ya empezaré con el de julio, en este caso un libro recomendado por Armandiurix, La 3a alternativa, veamos como nos va con él.

Realmente el leer ha cambiado de cierta forma mi vida, hoy mis hijos ven que yo leo en cuanto tengo la oportunidad, a veces se acercan a mí y me preguntan que leo, les digo de que se trata, a veces me dicen que les lea una parte, les leo unas cuantas páginas y así nos la llevamos, espero que en algún momento ellos también se interesen en leer y lo hagan por convicción y gusto, más que por una obligación.

Y tu que me lees, ¿aceptas el reto?, vamos 1 libro cada mes durante doce meses, puede ser de lo que sea, lo que te guste, lo que te llame la atención, no importa el número de páginas, ni el autor, ni el tema ya que al empezar no te podrás detener y seguramente empezarás a vagar de uno a otro sin preferencias. Por el costo pues si bien coprar libros puede resultar caro, siempre hay alguien dispuesto a prestar alguno de su acervo o puedes comprar uno sólo y al acabarlo cambiarlo con alguien más por otro y así continuar... recuerda, uno por mes.

Saludos a todos y felices lecturas.

domingo, 12 de junio de 2016

Behavior Driven Development (BDD)

Behavior Driven Development o BDD (Desarrollo Dirigido por Comportamiento) esta técnica es a mi parecer una de las mas importantes en cuanto al desarrollo de software, veamos que es BDD,  BDD es una técnica que nos permite plasmar un requerimiento en código, asegurándonos que lo que se desarrolle va directamente a solucionar un problema muy específico de negocio, pero cómo se logra esto? inicialmente es teniendo pláticas con la gente de negocio, cliente o product owner para entender lo más claro el problema a resolver, esto se deberá de hacer en juntas pequeñas en las que lo ideal es que estén representantes de desarrollo, pruebas y negocio y así de esta forma generar un requerimiento "estable" entre los tres, tratando de en ese momento identificar no solo el problema, sino una posible solución a él y ciertos escenarios que serán el boundary del desarrollo.
Luego de esto lo ideal es plasmar el requerimiento en forma de los escenarios o comporatmiento esperado en alguna herramienta de pruebas funcionales automatizadas como jbehave, robot, gauge o fitnesse en las que se pueden crear los escenarios de pruebas usando un lenguaje apto para la gente no técnica, acá hay que mencionar otra herramienta muy ampliamente aceptada en el medio que es la notación Gherkin en la que los requerimientos se escriben en tres partes siendo éstas Given (dado que cierto prerequisito o estado del sistema), When (cuando una acción específica ocurre sobre ese estado del sistema), Then (que sucede con el estado del sistema), veamos un ejemplo de la notación:
Dado que soy un empleado que tiene derecho a 5 días de vacaciones.
Cuando pido vacaciones por 3 días.
Entonces se me conceden mis días de vacaciones y me quedaré con 2 días por disfrutar.
Usando esta notación no solo es algo que la gente de pruebas, desarrollo y negocio sabe interpretar, sino que define claramente el comportamiento esperado.
Lo que sigue ahora es empezar con el desarrollo, pero ahora la asignación del equipo de desarrollo será hacer pasar los tests creados en la herramienta, volviéndose esta su principal tarea.... espera!!!!!, cuales test? pues las pruebas de aceptación al final de cuentas son tests, es decir, la chamba del equipo de desarrollo es hacer que el "Entonces" suceda cuando el "Cuando" es ejecutado bajo la circunstancia descrita en el "Dado", con esto se logra que el desarrollador tenga un foco muy claro y algo que le define cuando el desarrollo ya está terminado (cuando ya ha hecho pasar todas las pruebas descritas).
Bien, ahora ya tenemos varios tests escritos en una herramienta y código que hace pasar esos tests y que por ende ya resuelven el problema, ahora, que pasa con lo ya desarrollado? pues bien.... yo creo que ya lo podemos pasar a producción no?... lo ideal es que si, es decir, si se tiene una buena cobertura del comportamiento esperado, incluyendo pruebas no funcionales, pues si, ya se puede pasar a producción con la bendición del Yorch sin ningún problema, pero que pasa con nuestros amigos de pruebas? pues bien, ellos ya hicieron su trabajo (y muy bien hecho) al inicio del desarrollo, agregándole calidad al desarrollo creando los escenarios de pruebas necesarias (tratando de dar la mejor cobertura a nivel negocio).
Además de todo esto, ganamos pruebas de regresión automatizadas por lo que ahora ya no hay que dedicar cada vez más a la ejecución manual de las mismas cada vez que se agrega una funcionalidad al sistema, lo cual hace que el tiempo de entrega se acorte casi un 60%, lo cual hace que nuestros clientes sean aún mas felices, lo cual hace que la empresa gane más dinero, lo cual hace que... bueno iba a decir que nos aumenten el sueldo, pero eso casi no pasa jeje.
Además de rapidez en la entrega ganamos documentación a nivel de negocio que nos dice con un nivel de certeza del 100% lo que el sistema hace ya que se puede asegurar que si un test pasa, el sistema lo hacen, si un test no pasa, el sistema no lo hace.
Bueno, muy bonito todo hasta acá, pero no todo es color de rosa ni huele a nalguita de bebé, el problema (y es donde mas hay que luchar) es que hay que cambiar hábitos y formas en la empresa,  tales como el proceso que puede ser anticuado creando casos de uso, o el hecho de que no estén dispuestos a trabajar hombro a hombro con el desarrollador o que la gente de pruebas esté ya en la sinergia de que las pruebas van al último y eso no se puede cambiar, definitivamente esto es lo más difícil, el cambio de mentalidad, pero eso lo abordaremos más adelante... bueno, mejor no, mejor lean al respecto en el blog de mi amiga Rox, ella está más metida en estos asuntos y tiene más autoridad para hablar de eso que yo.

sábado, 4 de junio de 2016

Don't Repeat Yourself Principle o DRY (segunda parte)

En la primer parte comentamos algunas de la aplicaciones del principio DRY, estas aplicaciones son enfocadas totalmente al código, en esta segunda parte le daremos uso al principio, lugares donde a veces ni nos pasa por la mente, pues bien empezamos.


En los requerimientos

Esta parte es muy importate para cuando se está usando un framework ágil y es una de las mejores prácticas en la industria, en principio dry se aplica aplica en los requerimientos... pues haciendo... como decirlo... cambiando la forma de hacer requerimientos, esto es, en si, los documentos de requerimientos son una de las tantas representaciones de lo que se supone que hace el sistema, pero éstos tienen muchas desventajas, una de ellas es que normalmente se escriben antes de que se desarrolle la aplicción, por lo que a final esta representación del sistema muy seguramente va a quedar desactualizada casi desde la primer versión productiva del sistema, la otra es que muy dificilmente es actualizada con forme el sistema va mutando y la otra es que la documentación de requerimientos es como igor (el de winnie poo), naadie lo quiere por lo que hay un momento en que queda en desuso. Otra representación del sistema es el código en si, el sistema por sí mísmo, esta representación es la que al final de cuentas es mas fiel a lo que ejem... el sistema hace en realidad, esta representación en aún mejor que la dcumentación de requerimientos ya que a ésta si se le da el mantenimeinto debido y pues 100% seguro va mutando conforme el sistema va cambiando, además de que a esta representación muchos la quieren, en si todo el equipo de desarrollo, pero cual es el problema de esta representación, pues bien esta representación asegura hacer lo que hace pero puede no asegurar hacer lo que se espera que haga, para esto existe otra representación del sistema, ésta es los casos de pruebas, en los casos de pruebas también de alguna forma se describe lo que el sistema es, por lo que es otra representación del mísmo, que dependiendo de cómo se hagan pueden ser aún mejor que el código productivo de la aplicación ya que aplicando técnicas como BDD (Business Driven Developmen) pueden llegar a ser muy útiles para describir el sistema y el comportamiento esperado.
De estas tres representaciones de lo mísmo, de una no nos podemos librar (aún) que es la segunda por lo que es tiene que segur (aún) viviendo, pero entonces donde podemos aplicar DRY es en la primera y en la tercera, esto es en la forma de levantar requerimientos haciendo que el propio requerimieto sea expresado en lo que se espera que el sistema haga usando BDD y de esta forma estamos a un paso más adelante hacia automatización de pruebas y entregas continuas.

En las pruebas

Pues bien, en las pruebas como se aplica DRY... pues automatizandolas, para que chingaos queremos andar haciendo pruebas de regresión de todo el sistema (como debe de ser) de forma manual sólo por que ahora le cambiamos el color a la página de login o corregimos un bug de validacion en un campo de entrada; para este tipo de tareas repetitivas las computadoras son mucho mejor que los humanos, por lo que lo mejor es ir creando el sistema junto con los pruebas funcionales automatizadas, acá es donde entra en escena nuevamente nuestro amigo BDD.

En la construccuón

Bueno, en la vida de una aplicacion, cuantas veces tenemos que compilar, crear paquetes instalables, instalar, ejecutar pruebas unitarias, etc. pues acá es donde de nuevo decimos para que chingaus hago yo eso una y otra vez, mejor automaticemos lo mas que se pueda el proceso de construcción.

En el deploy

Pasa algo similar que en la construcción, esto es un proceso repetitivo y que difícilmente cambia cada vez que se deploya, hay que automatizarlo, mejor aún por que no nos aseguramos de que lo que construimos, el desarrollador encargado probó, la gente de qa probó, se instaló en ambiente sandbox, se instaló en ambiente de demo y por último se instaló en los 20 app servers que tenemos para la aplicación web es exactamente lo mismo? acá es donde entra el concepto de contenedores, de lo que hablaremos mas adelante.

Bien pues hasta acá DRY, espero que ahora quede un poco mas claro el concepto y que se vea su aplicación más allá del código, más adelante estaremos hablando de cuestiones mas específicas en cosas que nos encontramos en este post.

sábado, 28 de mayo de 2016

Don't Repeat Yourself Principle o DRY (primera parte)

Esta vez la entrada es acerca del principio  DRY o no te repitas  a ti mismo, este principio es muy conocido, tal vez uno de los principios de los que mas se habla en el desarrollo de software pero sobre todo en el contexto del código, aunque sus aplicaciones son muchas más, de estas aplicaciones es que hablaremos en el post de esta semana.

En el código

Es el contexto mas común en el que se aplica es este principio, y de lo que se trata es de que no se tenga código duplicado, el hecho de tener código duplicado es un problema grave en el desarrollo de software ya que es muy difícil tener identificado este código en todos los lugares donde se repite y en caso de que por ejemplo se tenga algún bug en esas líneas se tiene que replicar la corrección en todos los lugares necesarios lo cual es algo difícil de hacer sobre todo si no se sabe donde se tiene repetido el código.
Normalmente lo que se hace para solucionar esto es poner el código duplicado en un método y hacer la llamada a él en los lugares donde se se tenían los bloques duplicados. Otra estrategia es dejar en uno de los dos lugares donde se tiene el código duplicado y heredar una clase de la otra y así ya las dos usaran el mismo método vis herencia, pero ojo, esta estrategia la mayoría de las veces no es la mejor ya que normalmente se rompen oros principios como "Composition over inheritance" o preferir composición sobre la herencia y "Liskov Substitution" o substitución de Liskov, los cuales esperemos abordar en entradas siguientes.
En cuanto a la detección, ya hay herramientas de análisis estático de código que son de mucha ayuda al momento de detectar cuando se rompe este principio.

En el contexto

Este tipo de "código duplicado" es un poco mas difícil de percibir y se trata de que aunque los bloques de código por sí mismos no son iguales, si tienen el mismo objetivo, con este tipo de "código duplicado" se tiene que tener mas cuidado ya que normalmente los analizadores de código estáticos no los detectan por lo que quedan más al feeling del desarrollador.
Las soluciones son normalmente las mismas que en el caso anterior.

En los comentarios

Este caso se da mucho en los desarrolladores jóvenes ya que normalmente se les enseña que tienen que "documentar" su código y que esto es una buena práctica, el hecho es que la mayoría de las veces cuando hacen esto están violando este principio ya que te estás "repitiendo a ti mismo" en código y en comentarios, lo cual no tiene caso.
Esto parece muy trivial y uno podría llegar a pensar que que payaso soy pero cual es el problema de esto, el problema es que el software está siempre en constante evolución, lo que implica es que el código cambia tan constantemente (o tal vez mas constantemente) como las veces que uno se cambia los calzones, pero cual es el problema... el problema es que normalmente no cambiamos los comentarios, por lo que el comentario se vuelve obsoleto y si uno documentó bien chingón el código con muchos detalles pues ya valió pues ahora el comentario no es fiel a lo que hace el código y esto puede llegar a causar bugs muy graves ya que quien esa ese código (api) se pede basar en la documentación para decidir su uso o no y seguramente esperará un comportamiento muy distinto al que el código al final de 10 cambios de calzones hace.
Como solucionarlo, pues documentando con comentarios lo menos posible el código y haciendo que él por si mismo revele su intención desde el paquete, nombre de clase y nombre de método. Aguas no digo que no se pongan comentarios, solo que si se ponen o se actualicen o sean algo que realmente valga la pena, por ejemplo si tiene un código que usa una estrategia de minimax para solucionar un problema pero este algoritmo es muy complejo pues vale la pena primero que el código por si solo revele su intención y tal vez documentar un poco acerca de este algoritmo.


viernes, 20 de mayo de 2016

Principios en el desarrollo de software

Los principios en desarrollo de software son ciertas características de diseño de objetos que permiten que el código sea mas expresivo y por ende mas mantenible, hay varios principios, los más conocidos son los principios SOLID, DRY y KISS, en una serie de blogs entraremos mas en detalle en cada uno de ellos, por lo pronto y de forma muy general doy una breve descripción.

SOLID acrónimo de Single Responsability (responsabilidad única), Open-Close (abierto a extensión y cerrado a modificación),  Liskov Substitution (substitución de Liskov), Interface Segregation (segregación de interfaces) y Dependency inversion (inversión de dependencias) estos son principios que aplican de forma directa en el diseño de clases para programación orientada a objetos, como comenté, mas adelante en algún post revisaremos cada uno de estos principios.

DRY acrónimo de Don't Repeat Yourself (No te repitas a ti mismo), este principio es uno de los más publicitados en el medio y su aplicación va desde una clase hasta un sistema completo, pasando por versionamiento de la base de datos y documentación.

KISS acrónimo de Keep It Simple Stupid (mantenlo simple, estúpido) es un principio también muy conocido pero que es muy difícil de aplicar ya que por naturaleza (no le encuentro otra razón) los desarrolladores somos muy perfeccionistas, pero este principio nos dice que hay que mantener las cosas lo más simple posibles y esto es desde el código, hasta el propio producto igual, pasando por la documentación y el proceso de desarrollo de software.

Estos principios son muy usados y mencionados del desarrollo usando metodologías ágiles (de las que escribiremos en algún post posterior) y es que es muy normal que en este tipo de metodologías dada su naturaleza propicien que los desarrolladores se apeguen a este tipo de principios casi de a fuerzas pero de una forma un poco sutil.

Además de estos principios se podrían mencionar también otras características del software que un buen desarrollo debe de cumplir como el hecho de que todo código productivo debe de estar respaldado por un test o prueba unitaria automatizada y ya hablando de los tests también mencionar que estos tests no deben de ser "low class citizens", es decir, estos tests son igual (o tal vez hasta mas) de importantes que el código productivo, otra característica de un buen código es que debe de ser un código limpio siguiendo ciertos lineamientos encaminados mas que nada a que sea entendible y por lo tanto mantenible.

Bueno, pues esperen próximamente posts relacionados a todo esta madre sin sentido que les acabo de decir.

Saludos.

domingo, 15 de mayo de 2016

Patrones

Originalmente en este post iba a hablar de forma muy general de patrones, principios y herramientas, pero con forme empecé a hablar acerca del primero de ellos me di cuenta que es mejor separarlos, por lo que esta vez hablaremos sólo de patrones desde un punto de vista general, no hablaremos de un patrón en específico si no mas bien sobre que es y por que es importante, pero bueno pues a darle que es mole de olla.

Patrones, seguramente hemos oído mucho del patrón mvc (que creo es que es el único que se menciona en las universidades de México) o mvvm o singleton, pero que cosa es eso y por que son patrones? pues empecemos definiendo lo que es un patrón, también conocidos como patrones de diseño, según wikipedia "Los patrones de diseño son la base para la búsqueda de soluciones a problemas comunes en el desarrollo de software y otros ámbitos referentes al diseño de interacción o interfaces.
Un patrón de diseño resulta ser una solución a un problema de diseño. Para que una solución sea considerada un patrón debe poseer ciertas características. Una de ellas es que debe haber comprobado su efectividad resolviendo problemas similares en ocasiones anteriores. Otra es que debe ser reutilizable, lo que significa que es aplicable a diferentes problemas de diseño en distintas circunstancias" tomando esta definición como base un patrón es algo que te ayuda a solucionar un problema y que de alguna forma es algo genérico, por lo que para poder aplicar un patrón hay que tener un problema de diseño que se quiere solucionar y acá es a donde muchos de los desarrolladores jóvenes no les hace mucho sentido esto de los patrones, ya que las primeras veces que uno empieza a tirar código es muy difícil que identifique estos problemas de diseño (aguas, no confundir con los problemas de negocio a solucionar) ya que en su experiencia aún no se ha topado con ellos, a veces, me atrevo a decir que no solo las primeras veces que uno tira código, los primeros sistemas en que se ve involucrado o hasta en los primeros años de "profesional" (en algún otro post hablaremos sobre esta palabra) es algo difícil de identificar estos problemas de diseño, ya conforme uno se va haciendo mas huevudito en esto del desarrollo de software y empieza a saber lo que en verdad es desarrollar software con calidad es cuando le empieza a caer el veinte de lo que son los patrones y por que son importantes; pero bueno, volvamos a la definición, otra parte de ella que llama la atención es que dice que debe de ser reutilizable, es decir debe de ser de alguna forma genérica en cuanto a la solución de un problema e diseño en específico por lo que la primera vez que uno usa un patrón para resolver un problema la siguiente vez que se encuentra con un problema similar ya tiene una herramienta más para solucionarlo y debe de poder aplicar el mismo patrón con éxito.

Pues bien eso es lo que es un patrón, y ya sabemos lo primero es identificar el problema que se tiene que solucionar, como siempre hay muchas formas de solucionar un problema pero siempre algunas de ellas son mejores que otras, pero esto también depende de la situación específica en la que se esté, ahora que es lo que sigue, pues empezar a llenar nuestra caja de herramientas aprendiendo algunos patrones y éstos los empezaremos a aprender en el transcurso de esta serie de posts (intercalados con otros temas de interés en el desarrollo de software), como primer patrón ya comentamos acerca de el patrón decorador y una situación muy específica en la que se usa.

Los patrones son importantes por que ayudan a solucionar de una forma "estándar" un problema y que puede ser aplicado en muchas ocaciones dando generalmente un software con mejor diseño, por lo que será mas desacoplado, testeable y mantenible.


sábado, 7 de mayo de 2016

Patrón decorator para validar

Cuantas veces hemos oido de el principio de responsabilidad única (Single responsability) de los principios SOLID, en el que dice que una clase debe de tener una y sólo una responsabilidad, eso dice la teoría, pero ya en la práctica es muy dificil de cumplir ese principio y una de las razones de ello es derivado de las validaciones ya que uno dice que cierta clase debe de hacer cierta acción, pero a su vez para poder hacer esa acción es necesario validar algunas cosas, por ejemplo que un atributo no sea null, pero entonces lo que pasa es que esa clase ya no tiene una sola responsabilidad, sino que aparte de hacer su chamba también tiene que validar algunos valores, en este caso que algo no sea null. En este tipo de escenarios es en donde entra en juego una de las variantes del patrón decorador, con el que lo que hacemos es que la clase base sólo hace su chamba y nada más que eso, y las validaciones pues las creamos como una decoración de la clase base y de esta forma tenemos dos clases donde cada una de ellas tiene una responsabilidad única, una hacer el "negocio" principal y la otra el de validar pero pues veamos algo de código.

veamos la clase, por ejemplo Report

public class Report {
    public byte[] getBytes(File report) {
        if(report != null) {
            if (report.exists()) {
                return getBytesFromFile(report);
            } else {
                throw new FotoEmpleadoInvalida("The report doesn't exists");
            }
        } else {
            throw new IllegalArgumentException("Unknown report");
        }
    }

    private byte[] getBytesFromFile(File report) {
        return new byte[0];
    }
}

en esta clase se tiene el método getBytes con el que se obtiene un arreglo de bytes que contiene el reporte listo para ser descargado, como vemos, se hacen ciertas validaciones antes de que se genere y descargue el arreglo de bytes, parece todo bien no? pues entonces de lo que hablamos antes, Single responsability, en este caso esta clase hace validaciones y la conversión y obtención del arreglo de bytes del reporte, pues bien, acá es donde podemos aplicar el patrón decorador para separar las validaciones de lo demás quedando las clases de la siguiente forma:

public interface Report {

    public byte[] getBytes(File report);
}

public class NormalReport implements Report {

    @Override    public byte[] getBytes(File report) {
        return getBytesFromFile(report);
    }

    private byte[] getBytesFromFile(File report) {
        return new byte[0];
    }
}

public class ReportWithFileExistsValidarion implements Report {

    private final Report report;

    public ReportWithFileExistsValidarion(Report report) {
        this.report = report;
    }

    @Override    public byte[] getBytes(File file) {
        if (file.exists()) {
            return this.report.getBytes(file);
        } else {
            throw new FotoEmpleadoInvalida("The report doesn't exists");
        }
    }
}

public class ReportWithNullValidation implements Report {

    private final Report report;

    public ReportWithNullValidation(Report report) {
        this.report = report;
    }

    @Override    public byte[] getBytes(File file) {
        if (file != null) {
            return this.report.getBytes(file);
        } else {
            throw new IllegalArgumentException("Unknown report");
        }
    }
}

y la forma en que se usan estas clases es:

public class Main {
    public static final void main(String... args) {
        Report report = new ReportWithNullValidation(
                new ReportWithFileExistsValidarion(
                        new NormalReport()));
        
        byte[] reportInBytes = report.getBytes(new File("report.csv"));
    }
}

como se ve, se crea una interfaz que define que método debe de existir, y de allí se definen 3 implementaciones de esa interfaz, en donde una de ellas es la que hace el "negocio" de obtener y transformar el reporte y esa es su única responsabilidad, mientras que las otras dos implementaciones se dedican exclusivamente a hacer la validación que le corresponde a cada una, pero estas dos implementaciones a diferencia de la primera reciben en su constructor un Report, con lo que se puede ir haciendo una cadena de validaciones hasta llegar al "negocio" y así poder ejecutar la ación esperada.

A esto que sucede acá es a lo que se llama "decoración" ya que se tiene un "negocio" que se quiere hacer y que está encapsulada en una clase específica y luego esa clase se "decora" con otra que se dedica a hacer la validación de existencia del archivo y luego esa clase se "decora" con  la que se encarga de hacer la validación de que le parámetro no sea nulo, así aplicando este patrón se logra que cada una de las clases tenga una responsabilidad única.

Pues bien, chingón, ya se tiene todo bien separado y demás, pero ahora ¿cuál es la ventaja de tener las clases así? pues bien aunque al parecer es más código, esto nos da la ventaja de que las clases sólo cambian por una única razón por lo que posibles errores y cambios son mas localizados y si se quiere se pueden agregar mas validaciones con más decoraciones de ser necesario, por ejemplo si ahora nos dicen que sólo los reportes con extensión .txt son soportados basta con hacer el nuevo decorador y unirlo a la cadena de llamadas o si se encuentra un bug en como obtener el arregla de bytes del archivo pues se sabe específicamente en que clase se debe de hacer el cambio. Otra gran ventaja es la testeabilidad ya que al depender de una interfaz solamente, en las clases de tests se pueden crear mocks y pasarlos como parámetros y así poder testear cada parte por separado.

viernes, 29 de abril de 2016

Inyección de dependencias

Cuantas veces hemos oído hablar o leído acerca de la inyección de dependencias y en ese momento a muchos nos llega a la mente Spring, a otros ni sentido les hace, bien pues en este mi primer post de mi blog les voy a explicar de forma rápida y sencilla lo que es.

Primero ¿que es la inyección de dependencias?

Pues la inyección de dependencias no es otra cosa que... chan chan chan chan... inyectar la dependencia a una clase... jejeje así de simple es, pero bien ya dejémonos de jaladas y veamos de forma mas clara, la inyección de dependencias es un "recurso" que se usa para desacoplar las clases, es decir, la idea es que una clase no cree la instancia de otra clase dentro de su código, sino mas bien que la instancia de la clase de la cual se depende sea creada desde fuera y que sea "inyectada" a la clase que la usa, en términos simples eso es la inyección de dependencia.

Ejemplo:

Pero bueno, creo que hasta acá no he dicho nada que no hayan ya leído o escrito, así que vamos a un ejemplo:

Pensaremos en un portal de empleado, en el que un empleado puede consultar los dias pendientes que tiene de vacaciones, viendo el diseño se puede pensar en las siguientes clases:

public class EmpleadosBusiness {

    private EmpleadosDAO empleadosDAO;

    public EmpleadosBusiness(){
        empleadosDAO = new EmpleadosDAO();
    }

    public int obtenerDiasPendientesVacaciones(Empleado empleado) {
        return this.empleadosDAO.obtenerDiasPendientesVacaciones(empleado);
    }
}


public class EmpleadosDAO {

    public int obtenerDiasPendientesVacaciones(Empleado empleado) {
        // se conecta a la base de datos y consulta cuantos dias 
        // pendientes de vacaciones tiene el empleado.
        return diasPendietes;
    }
}

Pues bien, acá no estamos aplicando inyección de dependencias, ya que la clase EmpleadosBusiness depende directamente de EmpleadosDAO pero en el constructor estamos creando la instancia de EmpleadosDAO.

Ahora lo que vamos a hacer es "inyectarle" la dependencia a EmpleadosBusiness, con esto el código queda así:

public class EmpleadosBusiness {

    private EmpleadosDAO empleadosDAO;

    public EmpleadosBusiness(EmpleadosDAO empleadosDAO) {
        this.empleadosDAO = empleadosDAO;
    }

    public int obtenerDiasPendientesVacaciones(Empleado empleado) {
        return this.empleadosDAO.obtenerDiasPendientesVacaciones(empleado);
    }
}


public class EmpleadosDAO {
 
    public int obtenerDiasPendientesVacaciones(Empleado empleado) {
        // se conecta a la base de datos y consulta cuantos dias 
        // pendientes de vacaciones tiene el empleado.        
        return diasPendietes;
    }
}

Como pueden notar, la clase EmpleadosDAO no tiene alteraciones, ya que no es necesario en esta versión, pero lo que si cambia es el constructor de la clase EmpleadosBusiness, el que ahora ya no crea la instancia de EmpleadosDAO, sino que en lugar de eso solo recibe la instancia y la usa.

Esa es la forma básica de la inyección de dependencias, pero aunque si es un paso adelante, aún se le puede hacer algo más (digo, ya empezamos con esto, ahora nos chingamos y lo hacemos bien de una vez) y ese algo más es quitar la dependencia directa de la clase EmpleadosDAO, pero ¿y esto como?, pues bien, usando interfaces (pinches interfaces son la onda), de esta forma el código queda así:

public class EmpleadosBusiness {
 
    private EmpleadosDAO empleadosDAO;

    public EmpleadosBusiness(EmpleadosDAO empleadosDAO) {
        this.empleadosDAO = empleadosDAO;
    }

    public int obtenerDiasPendientesVacaciones(Empleado empleado) {
        return this.empleadosDAO.obtenerDiasPendientesVacaciones(empleado);
    }
}


public class EmpleadosDAODataBaseImpl implements EmpleadosDAO {
 
   @Override
    public int obtenerDiasPendientesVacaciones(Empleado empleado) {
        // se conecta a la base de datos y consulta cuantos dias 
        // pendientes de vacaciones tiene el empleado.        
        return diasPendietes;
    }
}


public interface EmpleadosDAO {
 
   int obtenerDiasPendientesVacaciones(Empleado empleado);
}

Lo que hicimos fue renombrar la clase EmpleadosDAO a EmpleadosDAODataBaseImpl, luego crear la interface EmpleadosDAO, luego hacer que la clase EmpleadosDAODataBaseImpl implemente la interface EmpleadosDAO y por último hacer que la clase EmpledosBusiness trabaje con la interface, no con la clase concreta.

Al final así es como se ven las clases usando inyección de dependencias y bueno, al final ¿que ganamos? pues ganamos desacoplamiento entre las clases y algo muy importante en el diseño de clases... es mucho mas testeable, pero de esas dos cosas hablaremos después.