Mostrando las entradas con la etiqueta clean code. Mostrar todas las entradas
Mostrando las entradas con la etiqueta clean code. Mostrar todas las entradas

viernes, 3 de febrero de 2017

Patrón Observador




Hemos vuelto, esta vez escribo sobre el patrón observador (the observer pattern), este patrón es muy simple y se usa cundo se require que alguien se entere de que algo ha sucedido dentro de otro ámbito, de allí su nombre, veremos un ejemplo sencillo:

Lo primero que se requiere es una interface Observer de quien saldrán las implementaciones que serán los Observadores:

public interface Observer {
    void update();

}

Luego tendremos otra interface Observable que es la que va a implementar nuestra objeto que necesitamos que notifique sus cambios de estado:

public interface Observable {
    public void addObserver(Observer observer);
    public void removeObserver(Observer observer);
    public void notifyObservers();

}

Ahora las implementaciones, primero veamos la implementación de Observable:

import java.util.ArrayList;
import java.util.List;

public class Invoice implements Observable {

    
    private String serialNumber;
    
    private String status;
    
    public Invoice(final String serialNumber) {
        this.serialNumber = serialNumber;
        this.status = "new";
    }
    
    public String getSerialNumber() {
        return serialNumber;
    }
    
    public String getStatus() {
        return status;
    }
    
    private List<Observer> observers = new ArrayList<Observer>();
    
    public void markAsPaid() {
        notifyObservers();
    }
    
    public void addObserver(final Observer observer) {
        this.observers.add(observer);
    }

    public void removeObserver(final Observer observer) {
        this.observers.remove(observer);
    }

    public void notifyObservers() {
        for(Observer observer : this.observers) {
            observer.update();
        }
    }


}

Por último las implementaciones de la interfaz Observer:

public class InvoiceStorer implements Observer {

    private Invoice invoice;
    
    public InvoiceStorer(final Invoice invoice) {
        this.invoice = invoice;
        this.invoice.addObserver(this);
    }
    
    public void update() {
        System.out.println("Guardando cambio de estado de la factura: " 
                + this.invoice.getSerialNumber() 
                + " a " + this.invoice.getStatus());
    }
    
    public String getInvoiceSerialNumber() {
        return invoice.getSerialNumber();
    }

}

public class InvoiceStatusChangeNotifyer implements Observer {

    private Invoice invoice;
    
    public InvoiceStatusChangeNotifyer(final Invoice invoice) {
        this.invoice = invoice;
        this.invoice.addObserver(this);
    }
    
    public void update() {
        System.out.println("Notificar pago de factura: " + invoice.getSerialNumber());
    }
    
    public String getInvoiceSerialNumber() {
        return invoice.getSerialNumber();
    }

}

Tenemos un test para probar la funcionalidad hecha:

import java.util.UUID;

import org.junit.Assert;
import org.junit.Test;

public class InvoiceTest {
    
    @Test
    public void markAsPaid(){
        String serialNumber = UUID.randomUUID().toString();
        Invoice invoice = new Invoice(serialNumber);
        InvoiceStorer storer = new InvoiceStorer(invoice);
        InvoiceStatusChangeNotifyer notifyer = new InvoiceStatusChangeNotifyer(invoice);
        invoice.markAsPaid();
        Assert.assertEquals(serialNumber, storer.getInvoiceSerialNumber());
        Assert.assertEquals(serialNumber, notifyer.getInvoiceSerialNumber());
    }

}
La salida del test es:

Guardando cambio de estado de la factura: db1a5606-2aad-475c-b4af-bf59f03975d4 a new

Notificar pago de factura: db1a5606-2aad-475c-b4af-bf59f03975d4

Ahora si vamos a ver lo que sucedió.

Lo primero es que los Observers al inicializarse se "registran" haciendo la llamada al método addObserver de la clase Invoice, este método llena una lista de observadores a la que al momento de que se actualiza su estado (método markAsPaid) les notifica del cambio hecho.

Cuando los observadores son notificados hacen uso de la instancia de su observable para hacer su trabajo, por ejemplo el InvoiceStorer se encargará de guardar el cambio de estado en la base de datos, mientras que el InvoiceStatusChangeNotifyer se encargará de enviar una notificación por correo electrónico informando del pago de la factura.

Como vemos, esto se pudo haber hecho en sólo el método de markAsPaid pero usando el patrón observador se puede hacer una mejor separación de responsabilidades.

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.

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.