Estimación y Compromiso

Antes solíamos decir que eramos malos para hacer estimaciones, debido a que era muy frecuente que las cosas tardaran más de lo que decíamos que demorarían. Siento que si bien este tema ha sido agotado en los ámbitos ágiles, muchos proyectos siguen llegando a esos momentos de “necesitamos una fecha”. Esta es una recolección de mis opiniones y conocimientos respecto del tema.

Estimación

Barry Boehm, ya en en 1981 en su libro Software Engineering Economics intentaba adoptar el cono de incertidumbre desarrollado por la industria química como modelo estadístico de predicción (yo lo aprendí de Steve McConell en Code Complete 2).

Con esta y otras iniciativas de gestión de proyecto se trata desesperádamente de modelar lo inmodelable. De predecir el futuro. Como predecir el futuro es algo que no se puede hacer, estas técnicas generalmente intentan incorporar subjetividades como “grado de confianza” o “probabilidad de éxito”. Finalmente lo único que logran es que además de estimar fechas concretas de término, también estimemos cuánto nos desviaremos. Es un estimado por encima de otro estimado. En estadística nos enseñan el concepto de Propagación de errores y parece que todos convenientemente lo ignoran en gestión de proyecto. Es una especie de pensamiento mágico.

Nunca fuimos malos para estimar. No se puede ser malo para estimar, tampoco se puede ser bueno para estimar, ya que una estimación no puede ser evaluada al final, ya que fue hecha sin suficiente información.

La estimación se puede usar en proyectos para estimar una fecha, por ejemplo; pero también se puede usar con personas, como por ejemplo en la frase, “estimo a mis amigos”. La estimación es una consideración. En las relaciones personales, implica que consideras valiosa a una persona para tu vida. En la gestión de proyecto significa que consideras el impacto de muchas variables para hacer un pronóstico. En su definición está incorporada la incertidumbre, es decir, una estimación en gestión de proyectos, se debe asumir que es algo incierto y no se pueden hacer planes exactos en base a las estimaciones.

Si te comprometes en base a una estimación, estás haciendo algo muy poco profesional. Estás comprometiéndote a algo que es posible que no puedas cumplir. Estás básicamente, colocándote en una mala posición voluntariamente.

En todo caso, lo sabemos. Cada vez que nos piden una fecha de término de algo, sentimos algo en el estómago que nos dice que es mala idea dar una fecha, pero rara vez logramos articular las ideas y los pensamientos debido al stress de la situación, o callamos y pensamos que esa sensación es un miedo a ser irresponsables.

Mi reflexión, es que la gestión de proyecto tradicional te encierra en una situación en donde no puedes desarrollarte profesionalmente, debido a que estás fallando constantemente y aunque no es tu culpa,  sientes que es tu culpa y todo los demás ven que es tu culpa. Pero también los incompetentes parecen encontrar la forma de ganarle al sistema y ser promovidos constantemente.

En la agilidad hemos entendido esto desde hace tiempo. Las estimaciones son una trampa.

El modelo ágil respecto de la planificación y gestión de un proyecto se enfoca en asegurar que los profesionales tienen un ambiente en el que se puedan desarrollar profesionalmente, se establecen canales de comunicación transparente para evidenciar las verdaderas incompetencias, y se enfoca en entregar valor por sobre la ejecución de un plan.

Compromiso

En la gestión de proyecto tradicional se realizan compromisos en base a fechas estimadas, como ya dijimos, eso es una trampa que establece un ambiente tóxico para los profesionales involucrados. Sin embargo, ¿Cómo podemos funcionar como industria responsable sin compromiso?

La pregunta no solo es válida, es crítica. El compromiso no se puede sacrificar, debido a que la responsabilidad y nuestro profesionalismo se deben reflejar en un alto compromiso, de otra forma nuestro trabajo no tiene valor.

Pero el compromiso sobre las fechas es un compromiso falso. Si te comprometes a entregar en una fecha, el cliente no solo asume el compromiso en la fecha, sinó también en las funcionalidades completas que has planificado y también en la calidad que has ofrecido y el costo. No puedes fallar en nada.

La respuesta normalmente es hacer un presupuesto por sobre los estimados, algún múltiplo de 1.5 o 2.0 de lo estimado (que generalmente, lo estimado también vienen inflados) pero luego eso se reduce en la negociación y queda cualquier cosa. Incluso si llegara a pasar tal cual, nada asegura que ese margen es suficiente. Es simplemente otra estimación.

De esta antigua encrucijada es de donde surge el movimiento estadístico de gestión de proyecto, junto con la fijación por procesos repetibles y certificaciones, en donde “las personas cambian, los procesos quedan”. Pero ya hace tiempo sabemos que eso tampoco funciona. Empleas un montón de gente que su única tarea es mantener cartas gantt y planillas excel y no aportan nada de valor al proyecto, o peor, son un constante y tóxico aislante entre el problema y quienes lo solucionan.

Otra cosa, el compromiso es solo del “proveedor”. El cliente generalmente solamente establece un interlocutor responsable de verificar que haya un cumplimiento de los “hitos” y que grite por cualquier desviación. No hay compromiso por parte del cliente, solo hay un contrato.

La forma de resolver este problema de compromiso es sencilla, pero requiere de algo de reconstrucción del paradigma de proveedor-cliente.

Parte por entender que nosotros no somos contratados para desarrollar un software, sino para resolver un problema. Es un proyecto tanto de investigación como de desarrollo. Siempre. No importa si hay un documento de 500 páginas detallando una solución a un problema. Son solamente 500 páginas detallando la arquitectura de un castillo en el aire que no ha sido puesto a pruebas con usuarios ni ha considerado la experiencia y capacidades del equipo que lo va a solucionar. El primer paso de un proyecto debiera ser una reunión de kick-off con todos los involucrados (Los jefes de proyecto, gerentes, inversores, y otras personas que no se ven impactadas por la solución, son solo un accesorio) en donde se lee el documento de requerimientos, se ríen todos y luego se quema en un fuego y se parte de cero.

La segunda parte de la solución es entender que tanto el cliente como el proveedor forman parte del equipo. Los profesionales técnicos ofrecen la experiencia y conocimiento de sus diciplinas particulares, mientras que el cliente y las partes involucradas ofrecen su experiencia y conocimiento en el problema que hay que solucionar. La incertidumbre es el pan y mantequilla del proyecto. Si quieres una buena solución, tendrás que invertir lo que corresponda. Pero no se trata de esperar infinito tiempo para que se solucione el problema. Se trata de sacar soluciones a los aspectos más críticos del problema de la manera más rápida posible, aveces probando varias soluciones al mismo tiempo, generando un retorno a la inversión lo antes posible, y comentiendo los errores lo antes posible, cuando son más baratos. ¿Cuándo va a terminar el proyecto? bueno, cuando el problema esté solucionado, o cuando ya se ha reducido tanto que no justifica seguir invirtiendo.

Avances constantes, inversión constante, retorno de inversión constante, comunicación mutua, trabajo en equipo, objetivos comunes.

Los proyectos no son necesarios, las estimaciones no son necesarias, pero hay un fuerte compromiso de todos por solucionar el problema.

 

Logo SoCraTes Chile

SoCraTes Chile – Una comunidad de profesionales

El pasado primero de julio, tuvimos en Chile el primer encuentro SoCraTes (Software Craftmanship and Testing) en Latino américa, y debo decir, que me siento honrado de haber participado en la organización.

Logo SoCraTes Chile
Logo SoCraTes Chile

El encuentro

SoCraTes es un evento distinto a muchos. Partiendo porque no es una conferencia en donde una sola persona habla hacia un público silente, sino que un

Parte del equipo Organizador SoCraTes 2016
Parte del equipo Organizador SoCraTes Chile 2016

encuentro auto-organizado, donde quien

quiera participar, tiene todo en su haber para hacerlo en la forma que más le acomode. El formato usado es el Open Space, que es una “tecnología de comunicación” para reemplazar las conferencias, que está lentamente tomando fuerza en varias áreas del que hacer humano. SoCraTes mismo,  se viene gestando desde el año 2011 en Alemania, y rápidamente ha ido creciendo hacia distintas partes del mundo, principalmente en Europa. Siempre como Open Space.

Los SoCraTes de otras partes del mundo son retirados y generalmente de varios días. En nuestro caso, no quisimos arriesgarnos mucho y lo hicimos solo por una jornada (de 9:00 a 18:00) y nos reunimos en el Zócalo Sur de la escuela de Ingeniería de la Universidad de Chile, un espacio céntrico, amplio  para la convocatoria esperada, y que nos dio un necesario abrigo del fío que hacía. Tuvimos café, té, agua, jugos y distintos comestibles disponibles durante todo el día. Cerramos con Pizzas y Sorteos de poleras.

Organización

Círculo Openspace SoCraTes Chile 2016
Círculo Openspace SoCraTes Chile 2016

La mecánica de un Open Space es bien sencilla. Al inicio, con un micrófono se llama a todos a sentarse en un círculo tan grande como sea posible para los asistentes y el espacio, para luego proceder a explicar el código de conducta y la mecánica (esta misma explicación). Luego se invita a que cada persona que tenga un tema que exponer, explicar, consultar o estudiar que pase a la mesa del centro, lo escriba y luego lo ubique en alguna de las zonas disponibles en la agenda del encuentro. Luego de un tiempo (en el caso de este encuentro, aproximadamente media hora) la agenda se llena y no quedan más temas que proponer. Hecho eso, se procede a ejecutar la agenda, llamando a todos los responsables de un tema que se instauren en sus espacios esperando asistentes, los que luego llegarán y discutirán el tema en cuestión. Ejecutada toda la agenda del evento, se hace un círculo de cierre en donde se comparten experiencias y aprendizajes.

Funciona increíblemente bien. Es la tercera o cuarta vez que veo un Open Space funcionando. Todos y cada uno funcionan como reloj, sin mayor intervención de nadie. Solo puedo decir, que aquí uno se da cuenta que es increíble el poder de auto-organización que se desperdicia en las empresas y “organizaciones” todos los días.

Temática

La temática del encuentro es sobre Software. Pero no sobre el día a día del software, por así decir. Queremos enfocarnos en cómo hacer Software mejor de como lo estamos haciendo ahora. Para eso definimos tres pilares de discusión: Técnica, Comunidad e Industria.

Técnica

Conversaciones alrededor de el estado del arte de nuestra técnica de desarrollo de software, ya sea compartiendo tecnologías o comparando/discutiendo su uso. Este es sin duda el punto más fuerte del evento, con mucha variedad de temas, expositores y formatos. Hubieron varias sesiones de programación, mesas abiertas, presentaciones y workshops.

Comunidad

El Software es sobre personas. Por esto debemos enfocarnos en nosotros. Queremos discutir la forma de mejorar nuestra comunidad de profesionales, tanto dentro como fuera de nuestras empresas. Espacios de trabajo, inclusión, diversidad, realidades distintas y colaboración son temas que sin duda queremos fomentar. En este SoCraTes hubo harto de esto también, y debo decir que me motivó harto. En especial debo mencionar la mesa de “Programar a los 50” que me contaron, tuvo mucha reflexión. Yo llegué solo al final, lamentablemente.

Industria

Las empresas de desarrollo de software no viven aisladas del mundo. Interactúan con el constantemente, realizando soluciones para un mejor mundo (idealmente). Pero nuestra industria lleva muy poco tiempo respecto de otras y tiene mucho por crecer. Es necesario que en conjunto tomemos las decisiones que nos llevarán a dar los siguientes pasos. Aquí es donde personas más orientadas al negocio o a la política pueden aportar desarrollando las ideas que nos permitirán hacer software de manera responsable, sustentable y con un real impacto positivo en la sociedad.

 

Mi experiencia

Me sentí muy motivado de ver que hay tanta gente motivada por estas ideas, y que están dispuestas a discutir estos temas. Tuvimos una gran participación y me llevo una buena cantidad de conversaciones valiosas.

Por ejemplo, en un tema que propuse, discutimos la forma en que debiéramos hacer los contratos para un trabajo de desarrollo de software, guiándonos por los principios del Software Craftsmanship. En particular, el principio “No solo colaboración con el cliente, sino alianzas productivas”. Esta conversación derivó en entender que para que dos empresas puedan estar realmente en una alianza deben compartir el propósito, es decir, la visión, o al menos estar alineadas. Luego pensando en como codificar esto en un contrato, nos dimos cuenta que la mejor forma es medir el trabajo en cuanto a métricas de avance en el logro de una meta común. Quedamos claros en que dejar que una empresa trabaje en un problema “a sueldo” no es un modelo sustentable en este proceso. Ambas partes en una alianza deben trabajar en conjunto, cada una aplicando su conocimiento y habilidades (¿Porqué lo harían? eso nos lleva de vuelta al propósito y la alineación de visión).

Obviamente la conversación no terminó con una respuesta definitiva, sino con más preguntas de las iniciales, pero me ha motivado a adentrarme en un área que no había considerado antes dentro del software, que es en el propósito de hacer las cosas, y eso me ha llevado a una profunda reflexión de mi quehacer profesional.

Aquí les dejo una galería con fotos y videos que iremos llenando a medida que recolectemos las imágenes de los asistentes: https://goo.gl/photos/tdDdyAys3duchegW6

 

 

¿Qué es un code kata?

Un code kata es una práctica a conciencia de las habiliades de programación, es entrenamiento; de la misma forma que lo es un kata (formas) en las artes marciales.

kata en karate

Fue inicialmente ideado por Dave Thomas (@PragDave, codekata.com, The Pragmatic Programmer) y rápidamente fue incorporado por muchos que entendieron el valor que una sesión de entrenamiento y la disciplina para ejecutarla con regularidad, podría ofrecer en productividad para el día a día.

Las características de un code kata son:

  • Los ejercicios deben ser sobre un problema aislado y particular
  • Deben haber pequeños pasos definidos que seguir.
  • Deben ser ejecutados durante un tiempo definido, sin interrupciones
  • Deben ser repetidos muchas veces en el tiempo.
  • No deben haber presiones por terminar
  • El código debe ser desechable

Ejercicios code kata

Con el tiempo, la comunidad produjo un conjunto de problemas con estas características para ser usados de práctica, y se han armado directorios y demostraciones, aunque todos los que he encontrado están en inglés:

Los invito a discutir y compartir sus experiencias y recursos con code katas en el foro de chileagil: http://foro.chileagil.cl/t/katas-en-programacion-coding-dojo-alguien-que-pueda-contar-su-experiencia/657

 

 

SOLID: Resumen de los principios

Los cinco principios de diseño de software SOLID fueron reunidos por Robert Martin (@unclebobmartin) a partir de varias ideas y papers pre-existentes en la comunidad. En este posts aparecen resumidos y se enceuntran enlaces a la descripción más profunda de cada uno de ellos.

Este post es un de índice para cada principio que he explicado en este blog, cada uno tiene un post dedicado.

SOLID

SOLID es un acrónimo, en donde cada letra representa una frase, que es el nombre de un principio. Los cinco principios son:

Single responsibility principle (SRP) | Principio de responsabilidad única [ver post completo]
Open-closed principle (OCP) | Principio abierto-cerrado [ver post completo]
Liskov substitution principle (LSP) | Principio de substitución de Liskov [ver post completo]
Interface segregation principle (ISP) | Prinicipio de segregación de interfaces [ver post completo]
Dependency inversion principle (DIP) | Principio de inversión de dependencias. [ver post completo]

 

 

Comunicación es consideración

Renè Magritte, The Son of Man, 1964
Renè Magritte, The Son of Man, 1964

Muchos de los grandes problemas en las empresas, se atribuyen a falta de comunicación, o a mala comunicación, o a comunicación incorrecta.

Personalmente, creo que no es un mal diagnóstico. Mas me parece que la mayoría las medidas para corregir este problema están completamente mal enfocadas, porque al parecer, la comunicación es mucho más complicada de lo que se cree.

Las medidas implementadas, generalmente apuntan a distribuir mejor el flujo de información y fortificar la cadena de mando para que las personas indicadas se enteren de la información correcta en el momento adecuado.

En papel, eso suena muy profesional, muy serio y muy eficiente. La verdad es que soluciona algunos problemas de comunicación, pero empeora los que realmente importan.

En la el manifiesto por el desarrollo ágil de software, el primer principio es “Individuos e interacciones, por sobre procesos y herramientas” y no es casualidad que sea el primer principio, ya que es sobre comunicación: la de verdad.

Todo este preámbulo es para enfatizar la diferencia entre la comunicación “coloquial” en las empresas entre empleados y la comunicación real, que es entre personas.

Parte del adoctrinamiento del profesional, es que cuando entras a una oficina como empleado, dejas tus problemas personales en la casa y te colocas una careta de eficiencia y pro-actividad. Eso deshumaniza el trabajo y lo hace más “fácil” al usar formalidades y protocolos, pero mata la comunicación directa y honesta, abriendo el mercado negro de los rumores y pelambres. Es un adoctrinamiento tan, pero tan fuerte, que incluso cuando intentamos crear una cultura horizontal, con buena onda y cariño, igual observamos problemas de confianza y autocensura, o lenguaje “profesional” recatado y con eufemismos, incluso pelambre y secretos innecesarios.

La careta de profesional es dañina porque nos impide empatizar con nuestros compañeros de trabajo, y de esta forma nos impide comunicarnos de manera efectiva. Porque la comunicación es en gran parte empatía, junto a la consideración que conlleva. Sin consideración por el otro, no podemos usar las palabras correctas o el tono correcto para transmitir las ideas y el significado correcto. Ese es el verdadero problema de comunicación, no los procesos o las políticas o la jerarquía o la falta de ellos.

Entonces, para combatir los problemas de comunicación, lo que propongo que nos quitemos esa careta y aceptemos que somos personas trabajando junto a personas, y que todos tenemos tristezas y alegrías, y si alguien está con problemas que interfieren con su trabajo, intentemos liberarles el camino para que los resuelvan de manera responsable.

Bajo esta nueva mirada, pretendo promover que es necesario que re definamos el significado de un “profesional” para que deje de ser la imagen de un traje con cara de palo y hablando solamente frases prefabricadas. Todos cagamos hediondo, todos tenemos problemas, y todos tenemos personalidades. Es parte de la igualdad y la inclusión, es parte de reclamar nuestra humanidad y de eliminar la cultura de la revolución industrial.

SOLID: Principio de inversión de dependencias

SOLID: Principio de Inversión de dependencias

Los cinco principios de diseño de software SOLID fueron reunidos por Robert Martin (@unclebobmartin) a partir de varias ideas y papers pre-existentes en la comunidad. En estos artículos los revisaremos uno a uno con la interpretación desde mi experiencia con ellos y cómo han afectado mi forma de programar.

Todos los principios los puedes ver en el índice: http://www.davidlaym.com/2015/05/solid-resumen-de-los-principios

Principio de Inversión de dependencias

La D en SOLID es por “Dependency Inversion Principle” o “Principio de inversión de dependencias” como podría traducirse al español. La definición de este principio según Robert Martin consta de dos partes:

a) Módulos de alto nivel no deben depender de módulos de bajo nivel. Ambos deben depender de abstracciones.
b) Abstracciones no deberían depender de detalles. Los detalles debieran depender de abstracciones.

Muy elegante, pero no entendí nada.

Comencemos por algunas aclaraciones, ya que el lenguaje usado para describir este principio es bastante técnico y un poco grueso.

Los niveles

Cuando se habla de “alto nivel” o “bajo nivel”, se refiere al nivel de abstracción relativo de una capa en un conjunto de “capas de abstracción”. Una capa de abstracción no es nada más que una forma de esconder detalles de implementación de un conjunto específico de funcionalidades, para permitir la separación de resposabilidades y facilitar la interoperabilidad. Dentro de nuestro programa, nosotros definimos las capas de abstración que utilizamos. Hace algunos años estaba de moda el uso de la separación por N capas, hoy aun se utiliza, pero me gustaría pensar que solo cuando lo justifica. El modelo de 3 capas (simplificación de las N capas: presentación, lógica, persistencia) también se usa bastante. Para esta discusión, las capas de abstracción son un poco más granulares, por ejemplo, dentro de la presentación probablemente tengamos una o dos sub-capas, no formales, de abstracción (vista, controlador) mientras que en la lógica, quizás tengamos varias (servicio, factory,strategy,lo-que-sea) y lo mismo hacia la persistencia. Habrán algunas operaciones que pasen por solo una mientras que otras ocuparán bastantes, no todas las opreraciones ocuparan todas las sub-capas.

Un ejemplo

Por ejemplo, si en un controlador usamos un factory que internamente utiliza el patrón strategy para generar un objeto, en esa operación tenemos 3 capas de abstracción, siendo 1: controlador, 2: factory, 3:strategy, en ese orden de abstracción (el strategy es el menos abstracto en esta lista). El principio dice entonces que controlador no debe depender de factory ni factory de strategy para funcionar. Deben haber abstracciones (interfaces, clases base) entre ellos.La segunda clausula es un casi repetir lo mismo de otra forma, excepto que nos advierte que nuestras abstracciones no deben depender de “detalles” o de clases particulares (insinuando que las abstracciones también deben depender de abstracciones).

Cuando se siguen este principio, rápídamente se puede ver como el control de creación de objetos comienza a invertirse. Para continuar con el ejemplo, Si antes teníamos un factory que crea nuestras estrategias en el constructor una a una, al terminar nuestro refactoring para aplicar este servicio, no debieramos ver ningun keyword “new” en ninguna parte, ya que crear un objeto concreto es una dependencia directa en él. Esto lo resolveríamos creando una interface para nuestras estrategias y recibiendo por parámetro en el constructor nuestras estrategias ya creadas por nosotros. Y así repentinamente, se ha invertido la dependencia. Lo mismo para el controlador y factory.

Entonces, ¿Quién crea los objetos?

En nuestro código no solo tenemos tres capas, este es un humilde ejemplo. Podemos llegar a tener 10 capas involucradas en una operación. Eso significa que el origen de todo esto, probablemente nuestro Main, o nuestro router, es el encargado de para cada operación crear 10 o más objetos al inicio y engancharlos todos en una infinta cadena, que obviamente, se torna muy difícil de mantener.

Es por esto que se inventó la herramienta llamada “Contenedor de Dependencias”. Puedes pensar de un contenedor como una madre de objetos, o un mega-factory, que es capaz de no solo crear un objeto en base a los parámetros que tenga en el constructor, sino además entender que los parámetros son abstractos y crear los objetos concretos que correspondan, y luego las dependencias de ellos también. En nuestro ejemplo, si usáramos un contenedor y pidiéramos al contenedor que nos fabrique un controlador, nuestro contenedor vería que el controlador depende de un factory abstracto, así que intentaría crear un factory concreto, solo para encontrar que el factory concreto depende de un strategy abstracto, entonces primero que nada crearía un strategy concreto, se lo pasaría al factory, se lo pasaría al controller y recién ahí, nos devolvería el controller creado para nosotros.

Distintas implementaciones de contenedores tienen distintas formas de configurar. Los iniciales se basaban en archivos XML gigantes en donde uno decía “esta abstracción corresponde a esta clase concreta” un millón de veces (una por cada par abstracción objeto) y algunas otras configuraciones más complejas. Hoy en día los contenedores modernos son capaces de trabajar en base a nomenclaturas (ICosa corresponde con Cosa y OtraCosaAbstract corresponde con OtraCosa) y uno debe configurar, generalmente usando código, solo los casos especiales o más complejos.

¿Y Qué se gana con todo esto?

Al seguir este principio logras fácilmente clases y objetos que colaboran muy bien entre ellos, pero que no están amarrados; es decir, logras una alta cohesión y un bajo acople. Esto a su vez es bueno porque reduce ampliamente las preocupaciones de “romper otra cosa cuando se arregla algo” (cada componente está aislado), resulta fácil realizar pruebas unitarias y resulta fácil extraer bloques de funcionalidades para reusarlas de otra manera. A modo personal puedo ofrecer mi observación de este principio como uno de los que ha ocasionado más impacto en la forma en que escribo el código, ya que el simple hecho de saber que un componente particular no depende directamente de otros, y que todo lo que declara como colaboradores (dependencias) son abstractos, me libera la mente en cuanto a planificar o modificar la funcionalidad de ese componente y me hace mucho más productivo.

En mi experiencia una de las mayores diferencias con el grado de dificultad que te puede presentar este principio en la vida diaria, es saber elegir tu contenedor. Si tu contenedor de dependencias es demasiado complejo y te obliga a declarar cada minucia de su funcionamiento, vas a odiar haber ido por este camino. Si elijes un contenedor que es demasiado simplista en su diseño y solo hace una o dos cosas, vas a encontrar que el contenedor te coloca límites. También está la preocupación de la performance, mientras más hace por tí el contenedor, más recursos ocupa. Es por esto que hay muchos contenedores de dependencias para cada lenguaje, porque cada uno está diseñado para distintas características. Conócelos y elije bien.

También puedes ver cómo se interlaza con otros principios:

  • Si una clase utiliza muchos colaboradores (recibe muchos parametros) es posible que esté cumpliendo más de una sola responsabilidad: DIP actúa como vigilante del SRP en este caso.
  • Al tener todas tus dependencias como abstractas, naturalmente estás muy avanzado en el cumplimiento de OCP: DIP actúa como facilitador en este caso.
  • El LSP te entrega la guia para construir correctamente las abstracciones. En este caso DIP requiere de LSP.
  • EL ISP también entrega guias para definir tus interfaces.En este caso DIP requiere de ISP.

 

usabilidad-diseno-ux

Sobre UX, Usabilidad y Diseño

La usabilidad (como yo la entiendo, no vengan a ser puristas conmigo ¿Ok?) es un enfoque de Diseño orientado a los usuarios y al uso que le otorgarán a aquello que está siendo diseñado, en contraste con el enfoque “tradicional” de exclusivamente cumplir las demandas del cliente y satisfacer una estética en particular. Usabilidad es entonces, el asegurarse que algo que fue diseñado, pueda ser utilizado como se diseñó. Así de simple.

Si, en el párrafo anterior utilicé la D mayúscula para Diseño, porque hay que hacer la diferencia entre los varios “diseños” diseminados en distintas profesiones como el diseño de software o el diseño gráfico, que en lo técnico poco tienen que ver unos con otros, y entre el Diseño, que es la actividad humana donde se crea algo nuevo con intención y propósito, en general.

Bueno, la diferencia está hecha, en este post estoy hablando de Diseño, la actividad humana, y cómo hemos fallado en hacerlo en digital por tanto tiempo.

En mi interpretación de todo esto, el mundo digital empezó cuando eramos geeks sin estudios de Diseño o sin consideraciones más allá de lo técnico, que se tomaron este mundo digital y comenzaron a crear productos. Una par de décadas más tarde la industria ha crecido, y hemos estado recibiendo input de profesionales de otras disciplinas más maduras y  tomando peso de lo que significa diseñar una cosa, ya sea digital o física.

En el más básico de los casos, usabilidad es tener consideración y respeto con el usuario de nuestro producto, asegurándonos que no les ocasione inconvenientes o que efectivamente estemos mejorando su situación. Luego, eso evoluciona a entender que el usuario de nuestro producto debe ser nuestro foco de atención y que nuestro producto no solo debe tener cero inconvenientes, sino que debe hacer una diferencia positiva neta en la experiencia que él tiene resolviendo el problema para el cual nuestro producto está diseñado. La usabilidad se hace cargo de la funcionalidad, de la estética, de lo técnico y finalmente, de lo subjetivo como la experiencia que tiene el usuario cuando enfrenta todos estos aspectos funcionando juntos.

Aterrizandolo a los proyectos en digital, significa que la usabilidad no es un tema del director de arte, o de una persona enfocada en usabilidad. Es un tema de todos y cada uno, tanto en su área de especialidad (estética, software, interacciones, infraestructura) así como también en la integración de estas especialidades (una decisión de estética puede afectar las interacciones, o una decisión de software puede ayudar a la infraestructura, etc, todos afectando la experiencia final del usuario). Significa que cada decisión que se tome en el proyecto sea orientada hacia el impacto que tenga en la experiencia del usuario final, más que al costo o al deadline, como se hace tradicionalmente (ojo: no es uno en vez de otro, es uno por sobre el otro. Significa que los plazos y el costo siguen siendo considerado, solo que no mandan).

En lo poco que he aprendido sobre esto, no es que la usabilidad sea algo nuevo, sino que en realidad es Diseño. Usabilidad = Diseño. punto. Antes no hacíamos Diseño, ahora estamos empezando.

Algunos hablan de experiencia de usuario (UX) pero para mi, eso es solo una parte de todo. Yo personalmente quiero dejar de hablar sobre usabilidad, y prefiero comenzar a usar la verdadera palabra: Diseño.

Los podcasts que escucho

Soy una máquina de escuchar podcasts, desde que los descubrí en 2006 he acumulado cada vez más podcasts que escucho, y cada vez aparecen más.

Los podcasts, son “programas de radio” en mp3, publicados en internet mediante un feed rss. Son un medio increible para consumir información en tiempos muertos, como el viaje de ida y vuelta al trabajo. Algunos leen, yo escucho podcasts.

Debo decir que junto con mantenerme actualizado, informado y entretenido, los podcasts, al ser principalmente en inglés, me ayudan a tener ejercitado el oido para entender inglés. Hay entrevistados indios, rusos, irlandeses, italianos  entre otros, hablando inglés en sus viscosos acentos que realmente desafían tu capacidad de entender inglés y esto me ha ayudado en más de una vez en situaciones laborales.

El primer podcast puede haber sido DotNetRocks, aunque es algo muy controvertido pero ya que resulta que también es mi podcast favorito, estoy con “bias“. Su primer episodio es de tan temprano como el 30 de agosto de 2002, pero hay hoy un montón de otros podcasts de calidad.

Tengo principalmente tres categorías de podcasts y los voy a listar a continuación:

Software Development

Obviamente es mi categoría principal, ya que de estos podcasts obtengo la información del día a día y las semillas para muchas ideas que pueden germinar semanas, meses o años despúes.

  • Dot Net Rocks: Podcast muy veterano, con más de mil episodios y con dos presentadores muy carismáticos e invitados de lujo. Se enfocan en las tecnologías .Net, pero son la referencia con la cual todos los demás se miden.
  • Herding Code: Panel de desarrolladores web, discuten temas y entrevistan invitados del lado más alternativo del mundo .Net.
  • The Changelog: Podcast dedicado a destacar proyectos del mundo opensource y entrevistar sus mantenedores, programadores y emprendedores.
  • HanselMinutes: Conversa sobre temas relacionados al desarrollo y la tecnología, siempre desde un punto de vista más humano y personal. Sus entrevistados son a veces desconocidos pero siempre muy, muy interesantes.
  • FLOSS Weekly: En formato podcast, videopodcast y show en vivo, es un estandarte del mundo opensource. Entrevistan a personas involucradas en proyectos opensource, tanto veteranos como emergentes.
  • RunAs Radio: Spin off de DotNetRocks, se enfoca en el mundo TI / OPS de las tecnologías Microsoft con productos como SQLServer, HyperV, Windows Server, Active Directory, Sharepoint, etc (debo admitir que los de sharepoint me los salto)
  • Adventures in Angular: el más nuevo de los podcast en mis suscripciones, noticias y discusiones de Angularjs, participando core commiters y evangelizadores.

Tech Talk

Podcast que hablan de tecnología pero que no tratan directamente software o código.

  • All About Android: Charla sobre novedades en el mundo android. Aparatos, aplicaciones, rumores, patentes, etc.
  • This Week in Tech: Revisión de los acontecimientos de la semana en el mundo tecnológico.
  • Windows Weekly: Revisión de los acontecimientos de la semana en el mundo Windows y Microsoft, tanto corporativo como tecnológico.
  • Hello World Podcast: Entrevistas a experimentados programadores sobre sus primeros días de desarrollo y los desafíos de la época. Excelente recurso para aprender de la historia del desarrollo de software.
  • Security Now: Largo podcast (90 a 120 min) sobre seguridad, criptografía, protocolos, vulnerabilidades y protecciones. Gran recurso para aprender, porque todos los tópicos son explicados al más extensivo detalle, pero también para estar al día ya que se habla de harta contingencia.

General Talk

Podcasts de cultura general y entretenimiento

  • Radiolab: Este podcast es altamente informativo, altamente entretenido, y altamente bello. Es una obra de arte y al mismo tiempo un despliegue de trabajo periodístico profesional. Los temas a tratar son muy variados pero frecuentemente tienen que ver con tecnología.
  • Freakonomics radio: De los autores del libro, presentan una mirada desde la economía, aplicada al día a día de las cosas. Suena mortalmente aburrido, pero la verdad es que es muy entretenido e interesante, y si bien no concuerdo con todo lo que dicen, es un gran ejercicio mental pensar en las cosas que hablan.
  • Stuff you should know podcast: Explican como funcionan cosas cotidianas y no tanto. Algunas cosas de ejemplo: Karate, Socialismo, Celulas Madre, Dinero, Ascensores, Sushi, Monopoly (el juego).

¿Cómo escuchar podcasts?

En iOS es sencillo: iTunes

En Android tienes algunas opciones, pero recomiendo fuertemente la aplicación Pocket Casts ya que es muy sencilla de usar, bonita y con todas las características que siempre he querido (he tenido harta experiencia con muchas aplicaciones a lo largo de los años, y esta es LEJOS la mejor)

Autopromoción obligatoria

Como algunos de uds sabrán, participo de un podcast en español llamado Sudamerican Coders. Hablamos de variados temas que varían desde lo profundamente técnico hasta lo altamente vivencial, siempre al rededor del desarrollo de software. No tenemos límite de longitud en los episodios, ya que tratamos de sacar todo el jugo posible de nuestros invitados o bien, agotar los temas que conversamos hasta nuestra satisfacción.

Espero que se suscriban a todos estos podcast, y por favor, si conocen otros que me estoy perdiendo y quieren compartir con quien llegue a este artículo desde la internetstsrsts, por favor indíquelo aquí abajo en los comentarios! (si visitas desde linkedin en móvil, abre el sitio en el navegador para tener una mejor experiencia de comentarios)

¿Qué es un CodeRetreat?

Un CodeRetreat es un evento de un día completo, en donde se practica intencionalmente las habilidades de programación y diseño de software en pos de mejorar. Este taller tiene un formato en particular que detallaremos a continuación:

  • Como el nombre lo indica, es un retiro. No debiera haber presiones o distracciones externas, los participantes solo se deben enfocar en la práctica.
  • El almuerzo y snaks para los breaks son provistos por los organizadores.
  • Cada participante debe llevar su ambiente de desarrollo configurado con el lenguaje y las herramientas de su interés o gusto. Durante el code retreat no se instala software ni se realizan configuraciones.
  • Hay un facilitador o un equipo de facilitadores que guían a los participantes y les presentan desafíos.
  • Los participantes se dividen en grupos de a dos para realizar pair programming. Se utiliza TDD todo el taller.
  • Todo el día se trabaja en un solo problema. Se recomienda generalmente el Juego de la Vida de John Conway por ser sencillo y a la vez entretenido.
  • Se dividen las prácticas en sesiones de 20 a 40 minutos.
  • Cada sesión hay un desafío o una restricción diferente. Entre las opciones están:
    • Utilizar un lenguaje desconocido
    • No utilizar ciclos (for, foreach, etc)
    • No utilizar condicionales (if, case, etc)
    • Utilizar programación funcional estrictamente
    • Utilizar programación orientada a objetos estrictamente
    • Forzar la utilización de alguna técnica de TDD en pair programming (ping pong, timebox, etc)
    • Programar todos en formato Coding-dojo
    • No hablar (comunicarse solo mediante el código que se escribe)
    • Cualquier sugerencia que los participantes consideren valiosa se puede intentar.
  • Una vez terminada una sesión, se elimina el código que se escribió, forzando a comenzar nuevamente.
  • Al finalizar cada sesión se realiza una pequeña retrospectiva y se comparten las lecciones aprendidas y reflexiones.
  • Luego de cada sesión se recomienda cambiar las parejas para tener la oportunidad de trabajar con la mayor cantidad de personas posibles durante el día.

La Historia

La idea original sobre el code retreat es de Gary Bernhardt, Patrick Welsh, Nayan Hajratwala y Corey Haines y data del año 2009 en la conferencia Codemash. Durante el año 2009 se realizaron varios eventos de este tipo y el año 2010 Corey Haines lo hizo internacional, realizando 11 eventos al rededor del mundo.

El año 2011, en diciembre, se celebró el primer Global Day of Code Retreat (GDCR) que se puede traducir como Día global del CodeRetreat y desde entonces se realiza todos los fines de año. Son 32 horas durante las cuales se realizan CodeRetreats sincronizados en múltiples partes del mundo, en distintas zonas horarias.

SOLID: Principio de segregación de Interfaces

Los cinco principios de diseño de software SOLID fueron reunidos por Robert Martin (@unclebobmartin) a partir de varias ideas y papers pre-existentes en la comunidad. En estos artículos los revisaremos uno a uno con la interpretación desde mi experiencia con ellos y cómo han afectado mi forma de programar.

Todos los principios los puedes ver en el índice: http://www.davidlaym.com/2015/05/solid-resumen-de-los-principios

Principio de Segregación de Interfaces

La I de SOLID es por “Interface Segregation Principle” que se puede traducir como Principio de “Segregación de Interfaces”. Se define como:

Principio de Segregación de Interfaces
Principio de Segregación de Interfaces

Los clientes no deben ser forzados a depender de métodos que no utilizan

Cuando hablemos de interfaz, no estaremos hablando exclusivamente de el keyword en un lenguaje en particular, sino que del conjunto de métodos y propiedades públicas que expone una clase hacia sus clientes.

Este principio trata el caso de clases que, si bien cumplen con el SRP, los clientes que utilizan estas clases ocupan solo un subconjunto de los métodos presentados por su interfaz. En estos casos, este principio nos recomienda crear interfaces independientes para cada uno de los clientes, ya sea mediante herencia o implementación de «interface».

Un ejemplo sencillo

Un bus pub/sub es un ejemplo perfecto. Si no te ha tocado trabajar con ellos, son clases que se encargan de recibir mensajes y publicarlos a todos los subscriptores, como eventos, pero sin el acoplamiento que conllevan. Un diseño ultra simplificado de un bus sería:

Bus

Podemos deducir que un bus tiene dos tipos de clientes: subscriptores y publicadores. Aveces habrán algunos clientes que realicen ambas actividades, pero no es un caso típico. Esta clase respeta el SRP ya que tiene un solo motivo para cambiar: que cambie la forma de tratar los mensajes.

Un diseño que respete el ISP sería:

AbstractBusSin embargo este diseño es muy poco flexible y obliga a tener instancias separadas para cada uno de los roles. Además en la mayoría de los lenguajes, este diseño es muy complicado de implementar debido a que el publicador debe conocer los subscriptores, debiendo compartir de alguna forma las estructuras de datos internas.

Un diseño más práctico es el siguiente:

InterfaceBusDe esta forma se puede tener una sola instancia como singleton, que maneja todos las estructuras de datos internas,  pero los clientes podrán depender de la interfaz que utilicen. Si usan ambas interfaces (esos raros casos) pueden depender de ambas o depender de la clase directamente.

Es difícil apreciar a primera instancia los problemas que se pueden generar al violar este principio, o los beneficios que se obtienen al cumplirlo, ya que parece algo muy inocuo y normal tener clases para los que distintos clientes utilicen distintos métodos, por lo que veremos algunos de los que considero más importantes:

Intencionalidad

Al cumplir con ISP, mejoramos la intencionalidad de nuestro código, compara lo siguiente:

 

Los dos trozos de código son casi idénticos, excepto en los componentes de los que dependen. En el segundo caso podemos determinar que esta clase se subscribe en algún momento al bus solamente leyendo la firma del constructor. En el primer caso no podemos saber nada sobre el uso que se le dará al bus del cual depende.

Esto es intencionalidad, quiere decir, nuestra codificación refleja la intención con la cual se realizan las decisiones de diseño. Es muy importante para mantener nuestro código fácil de mantener en el tiempo.

Pruebas unitarias

Al realizar pruebas unitarias, se nos simplifica mucho más la tarea si tenemos que realizar fakes o mocks a interfaces más sencillas. Es súper simple, pero las pequeñas mejoras suman y suman.

Simplificación de jerarquías

Al cumplir con ISP, pavimentamos el camino para simplificar las jerarquías de clases.

Para mi este es uno de los grandes beneficios del ISP. En el ejemplo de este artículo no se puede apreciar, pero no es difícil recordar alguna clase que tenía tres o cuatro niveles de herencia en alguno de los proyectos que hemos trabajado. Es algo que normalmente sucede. Es posible que esa cadena de herencias cumpla con el SRP, incluso posible que respete el LSP,  pero es muy probable que no respete el ISP simplemente porque al heredar tantos métodos la interfaz pública es simplemente un asco. Respetar el ISP generalmente lleva a tomar la decisión no solo de separar interfaces, sino que mediante aquello también deshacer esas jerarquías y remplazar la herencia por colaboración de componentes, que es un modelo mucho más flexible en el largo aliento.