martes, 24 de enero de 2017

Principio de Responsabilidad Única


Este principio es clave en la programación orientada a objetos, y nos dice que cada clase debe tener un solo motivo para cambiar, entendiendo como motivo la responsabilidad que tiene la clase, en otras palabras, para qué fue hecha o qué hace en específico. También se le puede llamar cohesión, entendiendo cohesión como la medida en que un componente (clase, paquete, método) se dedica a realizar solo la tarea para la cual fue creado.

¿Por qué es necesario aplicar este principio? Bueno, partamos de que tenemos una clase A que tiene dos responsabilidades, es decir, hace dos cosas; de ahora en adelante las llamaremos R1 y R2. En el cuerpo de la clase, esta tiene varios métodos, donde algunos de estos se utilizan tanto para llevar a cabo R1 como para R2. Al momento de la creación de la clase no hay ningún problema y todo funciona bien.

Un mes después ...

Es hora de mantener nuestra aplicación, debemos cambiar una clase. Espero hayas adivinado qué clase es, ¡sí, es la clase A!, resulta que R1 no está del todo bien y se debe corregir, entonces, empieza nuestra labor.

Tres días después, 500 tazas de café y pocas horas de sueño después ...

Creemos que hemos terminado y cuando se empiezan a realizar las pruebas... OOOOOH sorpresa, tú o el equipo de testing (o como se le llame en tu empresa) se dan cuenta que ahora R1 funciona bien, pero R2 no funciona. ¿Qué pasó?, recordemos algo: “Algunos de los métodos de la clase A se utilizan por R1 y R2”, entonces al modificar alguno de estos métodos, se corrige R1 pero genera errores en R2.

Es por lo anterior que se debería cumplir este principio, así cuando se haga un cambio tendremos la certeza que solo se afectará una responsabilidad. Otra justificación se hace evidente cuando ocurre un error y se detecta qué es, es fácil identificar la clase que tiene esa responsabilidad.

Si deseas ampliar más este tema te recomiendo el artículo The Single Responsibility Principle de Robert C. Martin.

Si deseas leer sobre los demás principios SOLID da click aquí.

miércoles, 18 de enero de 2017

Qué Método de Estimación Utilizar para mi Sprint?


Este artículo surge de un comentario que hice al artículo Planear sprints en horas y no por puntos de Lucho Salazar.

Estimar, según la RAE es “Calcular o determinar el valor de algo” o “Creer o considerar algo a partir de los datos que se tienen”, y como todos, en nuestra poca o mucha experiencia, sabemos que estimar no es algo trivial y aún más cuando estamos empezando en este mundo; ahora, con el paso del tiempo mezclamos las dos definiciones, ya que, calculamos con base en datos obtenidos con el paso de cada sprint; o al menos ese es el deseo, o, a mi consideración, lo que se debería hacer.

¿Qué método de estimación utilizar para planear mi sprint?, es la pregunta que muy seguramente nos surge cuando vamos a empezar, y según a quién se la formules te dará una respuesta con la cual, probablemente, muchos coinciden, debido a que unos métodos son más populares que otros.

Para responder esta pregunta, yo diría que todo método de estimación puede llegar a ser válido para un equipo, siempre y cuando este adquiera la madurez y la destreza en su utilización. Esto se consigue inicialmente a prueba y error, pasando por el punto en que se aprecia el avance en la utilización del método escogido, hasta conseguir dominarlo; en caso de no conseguir ningún avance es mejor cambiar y experimentar con otro método.

Para justificar mi postura, partamos de un método cualquiera (sea por horas, por puntos o puntos que equivalen tiempo o esfuerzo, u otro que hayas escuchado) y mi consejo es que te documentes muy bien al respecto antes de empezar. Comenzamos planificando los primeros sprint, los cual tenderán a errores (sobre o bajo la línea del Burndown) debido a la incertidumbre que conlleva iniciar con algo que, aunque esté documentado, se desconoce su comportamiento en la práctica; es con el tiempo (sprint tras sprint) en que este margen de error baja a su mínima expresión. Hay que tener en cuenta que se pueden obtener estadísticas como la velocidad promedio y las que creamos necesarias, con las cuales se puede predecir la estimación con base en datos y cada vez ser más acertados al planear el sprint.

Por lo anterior, estoy de acuerdo con Lucho cuando en su artículo expresa que "igual que con los puntos, estimar con horas no nos eximirá del error inherente a las estimaciones", para acuñar esta frase a este artículo he realizado unos pequeños cambios, quedando de la siguiente forma:

"estimar, independientemente del método utilizado, no nos eximirá del error inherente a las estimaciones"

Independientemente del método, la experiencia en su utilización te ayudará a obtener buenos resultados. Experimentar es fundamental para esto, puede que un método de estimación te dé mejores resultados que otro, y por lo tanto, sea el momento de realizar un cambio, ya sea de puntos a horas o de horas a puntos, o quizás algún método distinto a los aquí mencionados.

lunes, 12 de diciembre de 2016

Clean Code Capítulo 4 Comentarios


No se debería tener la necesidad de escribir algún comentario a excepción de unos pocos casos, si se sigue y aplica lo visto en los artículos anteriores de Clean Code; me refiero a ponerle nombres con sentido a las entidades del software y a sus variables, a escribir funciones cortas que hagan una sola cosa y que la secuencia de llamados en la funciones vayan contando la historia, contando qué hace el software.

Como mencioné al comienzo del artículo, hay unas cuantas excepciones en las que el autor de Clean Code nos dice que nos podemos tomar el tiempo para escribir un comentario. ¿A que se refiere con tomarnos el tiempo?, se refiere a que cuando se escribe un comentario se debe hacer consciente de lo que queremos plasmar y hacerlo de  una forma que aporta información (comentario de calidad), ya que, muchas veces no nos tomamos el tiempo necesario y nuestros comentarios terminan convirtiéndose en desinformación que hace menos legible el código; un claro ejemplo es dejar código comentado, este código es obsoleto y los programadores que lo vean muy rara vez lo borran creyendo que hay algo importante en ellos, de esta forma perduran en el tiempo. Veamos cuáles son los casos en que debemos tomarnos el tiempo para escribir un comentario:

  • Comentarios Legales, cabe aclarar que en lo posible se debe hacer referencia a una licencia estándar o a un documento externo y no poner todos los términos y condiciones en el comentario.
  • Comentarios Informativos, solo cuando sea necesario, en los otros casos tratar de utilizar nombres con sentido.
  • Explicar la Intención, pueden ayudar a entender porque un programador tomó una determinada decisión al escribir una línea o bloque de código.
  • Clarificación, estos comentarios suelen utilizarse cuando se implementa alguna API estándar que no puede ser modificada.
  • Advertir las consecuencias, en ocasiones determinado código debe escribirse estrictamente de una manera o hacer uso de algún componente, en estos casos es útil advertir la consecuencia si se modifica o cambia el código.
  • Comentario TODO, estos comentarios hacen referencia a una tarea que el programador piensa que se debe hacer pero que no realizó, como por ejemplo, una implementación por hacer, un recordatorio para agregar o eliminar alguna función.
  • Amplificación, estos comentarios buscan ampliar la importancia de un determinado fragmento de código con el fin de que no pase como irrelevante.
  • Javadoc en API públicas, sólo cuando el API es pública se debe describir, pero se debe hacer con calidad, por esto quiero citar un consejo dado por el autor de Clean Code “los javadoc pueden ser tan ambiguos, amplios y descorteses como cualquier otro tipo de documento”.

Recuerden que antes de colocar un comentario nos debemos asegurar si no hay una mejor forma de escribir el código para evitar el comentario, por tanto quiero terminar con la frase con que comienza el capítulo de comentarios en el libro Clean Code.

 “No comente el código incorrecto, reescríbalo
Brian W. Kernighan y P.J. Plaugher

Nota: Para más artículos relacionados ver Clean Code.

sábado, 10 de diciembre de 2016

Principio de Abierto Cerrado


El principio Abierto/Cerrado hace parte del los principios SOLID y se considera a Bertrand Meyer como la persona que lo acuñó.

"Las entidades de software (clases, módulos, funciones, etc.) deben estar abiertas para su extensión, pero cerradas para su modificación"

Este principio busca no cambiar el código existente que funciona bien (Cerrado). ¿Pero si llegan nuevos requisitos? o ¿Si cambian los requisitos ya existentes?, ¿Qué hacer?, es ahí donde se debe poder extender el comportamiento de las entidades de software a través de la adición de nuevo código (Abierto).

Es claro entonces que para cumplir con este principio se debe:
  • Estar Abierto para Extender
Con el pasar del tiempo, todo cambia, es inevitable que los requisitos de una aplicación no lo hagan, por eso cuando llega el momento, es conveniente poder cambiar el comportamiento y esto se logra a través de poder extender las entidades de software.
  • Estar Cerrado para su Modificación
El código fuente de las entidades de software no debe modificarse, es decir, su código debe ser inmutable.

¿Cómo así que se debe cambiar el comportamiento, pero su código fuente no se debe cambiar?, ¿Esto cómo es posible?. Aunque todo esto parece confuso, contradictorio y hace que surjan muchas preguntas, en la programación orientada a objetos (POO) existe la herencia y como algunos lenguajes no permiten herencia múltiples, también existe la posibilidad de implementar interfaces o clases abstractas, con esto se puede extender las entidades de software, sin modificar el código fuente del padre (objeto de quien se hereda).

Con base en lo anterior ¿Qué estrategia utilizar?, en este punto surge la abstracción como la piedra angular de este principio, pues las entidades de software pueden utilizar una clase abstracta cuyo comportamiento está cerrado (que no se puede modificar), pero si en un futuro se quiere cambiar su comportamiento puede extenderse creando entidades de software que desciendan de dicha clase abstracta. La abstracción se centra en el que hace más no en el cómo lo hace, aislando los comportamientos específicos de una entidad, dejando que un desarrollador pueda sobreescribir o implementar dicho comportamiento como él lo desee.

Este artículo es un abrebocas y un pequeño resumen para este principio. Te invito al plato fuerte, a que profundices aún más, para esto te propongo que leas el siguiente artículo y en tus comentarios me cuentes tus impresiones. ¡No te vas a arrepentir de leerlo!:
http://web.archive.org/web/20060822033314/http://www.objectmentor.com/resources/articles/ocp.pdf

lunes, 5 de diciembre de 2016

Principios SOLID


SOLID, es un acrónimo introducido por Robert C. Martin (autor de libro Clean Code y coautor del manifiesto Ágil), este acrónimo representa 5 principios claves en la programación Orientada a Objetos (POO). Veamos el acrónimo y a qué principios se refiere:

Single responsibility (Principio de Responsabilidad Única)
Open-Closed (Principio de Abierto/Cerrado)
Liskov substitution (Principio de Sustitución de Liskov)
Interface segregation (Principio de Segregación de la Interfaz)
Dependency inversion (Principio de Inversión de Dependencia)

Lo ideal es que conozcas y  utilices cada uno de estos principios a la hora de desarrollar software, debido a que nos ayudan a que nuestro diseño sea bueno, limpio y claro, obteniendo así aplicaciones fáciles de mantener y escalar, pues nos ayuda a lograr uno de los objetivos relevantes de la POO, el cual consiste en tener una alta cohesión (la clase debe enfocarse en hacer una sola cosa del sistema) y un bajo acoplamiento (la clase debe tener la menor cantidad de dependencias posibles).

Los principios SOLID en combinación con Clean Code te permitirán obtener aplicaciones fáciles de leer y comprender lo que ayuda a un más al momento de mantener, escalar y conseguir alta cohesión y un bajo acoplamiento; en pocas palabras, se complementan y se potencian mutuamente.

sábado, 3 de diciembre de 2016

Clean Code Capítulo 3 Funciones


Al crear software debemos proporcionar mecanismos para llevar a cabo diferentes acciones, por esto aparecen las Funciones. En Clean Code, se hace énfasis en lo importante que es crear cada función para hacer una cosa, que vayan contando una historia y que cada una lleve a la siguiente. Si observamos secciones en funciones (por ejemplo declaraciones, inicializaciones y filtros), es una clara señal que la función hace más de una cosa, otro caso es cuando una función hace lo que dice que hace en su nombre, pero hace algo extra (se está incumpliendo la regla de hacer una cosa) generando un efecto secundario inesperado, siempre recordemos que las funciones son sin efecto secundarios, por lo tanto, si es necesario, se debe pensar en refactorizar. Una función debe responder a algo o hacer algo, pero no las dos cosas, de ahí que surge lseparación de consultas de comando, el autor lo expresa de la siguiente manera "Su función debe cambiar el estado de un objeto o devolver información sobre el mismo, pero ambas operaciones causan confusión".

Al darles nombre no olvidemos el capítulo nombres con consentido, por esto se debe usar nombre descriptivos, que revelen la verdadera intención o acción de la función, una recomendación es utilizar verbos y palabras claves como por ejemplo writeField(name). write (Verbo), Field (Palabra Clave).

Cada función debe ser de tamaño reducido, ¿Cuántas líneas? no sabría decirte con exactitud, pero si nos basamos en el libro, este nos recomienda que tengan una longitud aproximada de 20 líneas, en estas líneas hay que prestar mucha atención a los bloques y sangrados. Cuando hablo de bloques hago referencia a fragmentos de códigos dentro de if, else, for y similares, en este caso la recomendación es que su longitud sea de una sola línea (lo más probable es que se invoque a otra función); en cuanto al nivel de sangrado no debe ser mayor a dos, ayudando a que haya un nivel de abstracción por función haciendo más fácil de comprenderla, con lo anterior se puede leer el código de arriba a abajo (la regla descendente). Esta regla consiste en posicionar las funciones por nivel de abstracción, como lo explican en Clean Code "Queremos que tras todas las funciones aparezcan las del siguiente nivel de abstracción para poder leer el programa, descendiendo un nivel de abstracción por vez mientras leemos la lista de funciones".

Otra parte clave en las funciones son sus argumentos, cuyo número ideal es cero, posteriormente uno (mónadico) y dos (diádico); se debe evitar las funciones de tres argumentos (triádico), las de más de tres argumentos (poliádico) deben tener una motivo especial. Las formas monádicas habituales son tanto para preguntar sobre el argumento o para transformar el argumento en otra cosa, un caso poco habitual es para eventos, en este caso las funciones por lo general no devuelven nada. En este punto el autor desaconseja utilizar argumentos de indicador (Pasar un booleano a una función) ya que de una forma u otra está indicando que la función hace más de una cosa. Para las funciones diádicas se debe propender que los argumentos sigan y tengan un orden natural, cuando estos carecen de dicho orden debe el programador utilizar los mecanismos necesarios para evitarlas. Cuando una función requiere dos o más argumentos se suele utilizar Objetos Como argumentos, pero esto no es una trampa, pues suele suceder que las variables antes pasadas como argumentos pertenezcan a un concepto más grande. Los nombres de los argumentos deben ser claros y acordes al contexto.

Algunas funciones tienen argumentos de salida, es decir, ver argumentos que en vez de ser entrada son salidas, estos argumentos deben evitarse.

El manejo de errores en una función en muchos casos se hace por medio de códigos de error, que suelen estar en una clase o varias lo que va creando alto acoplamiento y cuando surge un nuevo tipo de error, es donde viene los dolores de cabeza, por esto es mejor emplear excepciones que devolver código de error. Al utilizar excepciones es inevitable utilizar Try/Catch esto empieza a generar estructuras anidadas por eso es una buena práctica extraer bloques Try/Catch, esto quiere decir que se debe crear una función donde se procesa el error (dónde está la estructura Try/Catch, el procesamiento de errores es una cosa), desde esta se invocará la función que realizará la acción.

Antes de terminar quiero mencionar las instrucciones Switch, donde el autor hace una mención específica diciendo "Mi regla general para las instrucciones Switch es que se pueden tolerar si solo aparecen una vez, se usan para crear objetos polimórficos y se ocultan tras una relación de herencia para que el resto del sistema no las pueda ver. Evidentemente, cada caso es diferente y en ocasiones se puede incumplir una o varias partes de esta regla".

Las funciones nos ayudan a realizar acciones concretas, es nuestro deber evitar el no repetir código, por eso se deben crear con la mayor responsabilidad y dedicación y sin miedo a reescribir cuantas veces se crea necesario hasta que el resultado satisfaga las necesidades.

Nota: Para más artículos relacionados ver Clean Code.

lunes, 28 de noviembre de 2016

Clean Code Capítulo 2 Nombres con Sentido (2/2)



Continuando con la segunda parte del capítulo 2, vamos a seguir viendo aquellas reglas para crear nombres correctos. Si aún no has visto la primera parte te invito para que la veas.

Nombres de clases: Los nombre de clases no deben ser verbos. Los nombres deben proporcionar de manera clara el propósito de la clase, por lo general debe ser un sustantivo, evitando nombres genéricos. Algunos ejemplos de nombres correctos serían: Persona, Direccion, Cliente. Algunos nombres incorrectos de clases podrían ser: Info, Procesador, CalcularNomina.

Nombre de métodos: Debe ser un verbo como por ejemplo, eliminar, agregar, guardar. Los métodos de acceso, modificación deben tener como nombre su valor y usar como prefijo get, set e is. Como recomendación el autor dice, que “Al sobrecargar constructores use métodos de factoría estáticos con nombres que describan los argumentos

No se exceda con el atractivo: Esta regla hace referencia a no utilizar nombres provenientes de formas coloquiales de decir las cosas o de jergas, dejando a un lado la claridad, ya que, si llega un nuevo programador que no conozca estas formas de decir las cosas, se llenará de desinformación. 

Un nombre por concepto: Es simple, cuando nos decidimos por una palabra para representar un concepto, esta debe ser constante por todo el código y no utilizarse en unos lados y en otros no. Por ejemplo, no es conveniente utilizar en algunos nombres de métodos la palabra get y en otros retrieve. 

No haga juego de palabras: Se refiere a no utilizar una palabra con dos fines distintos, por ejemplo, digamos que en nuestro código hemos venido utilizando la palabra remove para nombrar métodos que inactivan, y en algún momento somos tentados a utilizar remove para hacer referencia a un método que elimina, en este caso sería mejor utilizar el nombre delete para el método en cuestión.

Usar nombres de dominio de soluciones: No es necesario que todos los nombres utilizados sean extraídos del dominio del problema, ya que, los lectores del código son programadores y ellos conocen o están familiarizados con términos informáticos, de patrones, y demás. Por ejemplo para un programador va a tener mucho sentido si una clase tiene el nombre de ListAdapter.

Usar nombre de dominios de problema: Cuando no se pueda cumplir la regla anterior porque no existe un término en el ámbito de programación, se debe recurrir a un nombre del dominio del problema. El autor nos dice “Separar los conceptos de dominio de soluciones y de problemas es parte del trabajo de un buen programador y diseñador”.

Añadir contexto con sentido: Cuando los nombres no tiene sentido por sí mismo, es necesario crearle un contexto que enriquezca dicho nombre, esto puede hacerse convirtiendo variables en parte de un concepto mayor, es decir, extraer una clase de la cual hagan parte o en una función o método que aporte un contexto. Como última instancia usar prefijos.

No añadir contextos innecesarios: Se refiere a no agregar en los nombres más información de la necesaria. Imagine una clase llamada DireccionResidencia y otra DireccionTrabajo, estos nombres no son realmente adecuados para una clase, lo mejor sería una clase Direccion y estos nombres serían ideales para nombre de instancias. Otro caso es agregar prefijo al nombre de las clases.


Como hemos visto en estos dos post acerca de nombres con sentido, el elegir un nombre adecuado para cada parte del código es fundamental, tanto para la legibilidad como para entender qué se hizo o qué se va a hacer. Para dar un nombre adecuado es necesario emplear habilidad descriptiva, gran vocabulario, conocimiento técnico y dejar los miedos, es momento de empezar a buscar mejores nombres, agregar o quitar el exceso de contexto, refactorizar el código, cambiando los nombres que no sean adecuados en el código existente.

Nota: Para más artículos relacionados ver Clean Code

Instalación NodeJS

Ingresamos a la página oficial de NodeJS donde lo descargaremos  https://nodejs.org/en/download/ Escogemos el instalador que se ajuste a ...