Jorge Ruiz - Blog

Mes: agosto 2020

Código Limpio. Switch

Os detallo a continuación, un ejemplo de código limpio extraído de la lectura del libro: Código Limpio. Manual de estilo para el desarrollo ágil de software. Robert C. Martin.

El tema va sobre las instrucciones switch. Es muy difícil mantenerlas con un código reducido y con el objetivo de que una función haga una sola cosa. Por la naturaleza, de la instrucción switch vamos a tener funciones que hagan N cosas. Malo, esto no hace mantenible el software pero claro, tampoco podemos dejar de utilizar instrucciones switch.

Lo que sí que podemos hacer es asegurarnos de incluir estas sentencias switch en una clase nivel inferior y NO repetirlas. Para ello, EVIDENTEMENTE, tenemos que recurrir al POLIMORFISMO (me encanta, es probable que a alguno de vosotros en la entrevista os haya pedido que me definieráis el polimorfismo).

Vamos a fijarnos en este listado de código fuente (Payroll.java)

public Money calculatePay(Employee e) throws InvalidEmployeeType{
    switch (e.type){
        case COMMISSIONED:
             return calculateCommisionedPay(e);
        case HOURLY: 
             return calculateHourlyPay(e);
        case SALARIED: 
             return calculateSalariedPay(e);           
        default: 
             throw new InvalidEmployeeType(e.type);
    }
}

Esto, por un lado taaaaaaaaaaan habitual, tiene varios problemas:

  1. Es una función de gran tamaño y cuando se añadan más tipos de empleados todavía crecerá más.
  2. Hace más de una cosa, incumpliendo el Principio de Responsabilidad Única (Single Responsibility Principle – SRP-) ya que hay más de un motivo para cambiarla, por ejemplo cuando se añadan nuevos tipos de empleados.

Nota: No veais lo que me gusta la Orientación a Objetos. Sus conceptos que ya tienen sus años se utilizan ahora en temas de diseño de microservicios, por ejemplo.

  1. Incumple el Principio de abierto/cerrado (Open Closed Principle o OCP) igualmente porque debe cambiar cuando se añadan nuevos tipos de empleados.

  2. Pero el problema mayor, es que vamos a tener un número iliminatado de funciones que también van a tener el mismo problema.

Imagínate la implamentación de algo como:

ìsPayday(Employee e, Date date)

o

deliveryPay(Employee e, Money pay)

La estamos liando parda y no nos estamos dando ni cuenta.

La solución al problema consiste en OCULTAR LA INSTRUCCIÓN swicth en una FACTORIA ABSTRACTA e impedir que nadie la vea

Para los que no entendáis esto, digamos que lo que vamos a hacer es enterrar en lo más profundo del código ese switch (porqué tiene que estar) pero va a estar controlado por una FACTORIA que es un patrón de diseño que va a permitir crear, en este caso, los empleados con un DESACOPLAMIENTO del software (me parece brutal).

Fíjate la solución es sublime:


public abstract class Employee {
    public abstract boolean isPayDay();
    public abstract Money calculatePay();
    public abstract void deliverPay(Money pay);
}

public class CommissionedEmployee extends Employee { ... }
public class HourlyEmployee extends Employee { ... }
public class SalariedEmployee extends Employee { ... }

public interface EmployeeFactory{
    public Employee makeEmployee(EmployeeRecord r) throws InvalidEmployeeType;
}

public class EmployeeFactoryImpl implements EmployeeFactory{
    public Employee makeEmployee(EmployeeRecord r) throws InvalidEmployeeType {
          switch (r.type) {   
             case COMMISSIONED:
                 return new CommissionedEmployee(r);
             case HOURLY: 
                 return new HourlyEmployee(r);
             case SALARIED: 
                 return new SalariedEmployee(r);           
             default: 
             throw new InvalidEmployeeType(e.type);

          }
    }
}

¡Madre mía! preparado para jerarquía de clase Employee y los diferentes empleados que extienden de ella. Ahí sí que nos tocará implementar cada vez que haya un nuevo empleado.
Y el switch encerrado en una factoría (interfaz con método makeEmployee más su implementación en EmployeeFactoryImpl. Si amplías a nuevos empleados extiendes de la clase Employee, implementas sus métodos abstractos y tocas la factoría que hace NEW del objeto devolviendolo sobre una referencia a clase base (Employee).

Nota: Que no te asuste la clase EmployeeRecord que es simplemente para identificar el tipo de empleado.

Teclado Mecánico. HIDITEC GK500

Voy a iniciar una serie de post en los que os voy a comentar que elementos configuran mi escritorio en estos días de trabajo remoto.

Empezamos por el teclado.

Tanto en mi etapa de estudiante como en mi etapa profesional la realidad es que he utilizado el teclado que me han puesto por delante. No era algo en lo que prestase mucha atención. Si el ordenador era de torre pues el teclado que viniese, si el ordenador era el del portátil pues el incorporado.

Pero hace un año más o menos las cosas empezaron a cambiar. El teclado del portátil que uso me empezó a parecer incómodo y busqué uno externo que acoplar. Nada del otro mundo, uno de tipo membrana.

Bueno, ya sabemos, estos teclados de tipo membrana son muy funcionales pero la realidad que la experiencia de uso con tantas horas que le meto al ordena era mediocre.

Así que decidí dar el salto, cambiaría a los teclados mecánicos. La realidad que no tenía ni idea, sabía que quería probarlos, no tenía mucho presupuesto así que me decidí a comprar un KROM KERNEL TKL.

Suficiente para comenzar. No lleva teclado numérico pero me permitiría probar la experiencia de trabajar en un teclado mecánico.

Me gustó. La sensación de pulsación de tecla es más satisfactoria que membrana. Investigando sobre el tipo de pulsación digamos que es lineal. Debes pulsar la tecla un determinado tiempo hasta recorrer unos 4 mm y se activa la tecla pulsada. Ojo porque aquí está una de las claves de estos teclados mecánicos.

El interruptor de pulsación (Switch) que lleva es rojo, justo el que proporciona esta experiencia de uso lineal aunque es un interruptor, digamos, genérico, no de marca.

Hace su ruido como todos los mecánicos y me iba bastante bien hasta este verano que empezó a fallar. Los 45 € y los componentes que lleva supongo que no dieron mucho de sí en algunas de las teclas. Tuve que pasar al teclado de membrana.

Aprovechando que este teclado mecánico estaba fallando, aproveché para aprender un poco sobre la verdadera experiencia de uso que yo quería. Y no era otra que la del tecleo en aquellos teclados mecánicos de los ordenadores IBM de los años 90 cuando yo estudiaba (existían mucho antes).

Entonces aprendí que el interruptor que realmente hay que tener en el teclado es un Blue y fijándome en las marcas, era interesante que fuera Cherry MX Blue. Cherry es uno de los primeros fabricantes de teclados mecánicos y abandera la tecnología de ellos (aunque hay muchos más con sus propias tecnologías que también van muy bien, Razor, Logitech, …)

Para los que os estéis preguntando que sensación de pulsación es, es como cuando pulsas el botón de un bolígrafo para sacar la punta. Haces todo el recorrido de pulsación y notas ese clic famoso.

Si te pones a buscar teclados mecánicos Cherry MX Blue (no genéricos) los precios se disparan un poco pero encontré la empresa española HIDITEC con su modelo GK500 que tiene uno a unos 75 €.

Lo compré y estoy encantado con él (de momento 🙂 )

Os dejo enlace a vídeo para que escuchéis el Cherry MX Blue: