Quantcast
Channel: Genbeta dev - Genbeta
Viewing all 564 articles
Browse latest View live

Los 17 momentos por los que odias ser desarrollador

$
0
0

Silicon Valley

No amigo, la vida no es de color de rosa. Ni siquiera la del desarrollador por mucho que yo mismo os lo pintara de esa manera la semana pasada. Por eso hoy os traemos la otra cara de la moneda: todos esos momentos que te hacen odiar ser desarrollador. Podríamos haber elegido decenas pero como tampoco queremos abusar y somos muy de simetría, nos quedamos con 17. Ponte cómodo porque te aseguro que vas a pasar un mal rato.

1. Cuando el Eclipse tarda media hora en arrancar

Vale, te da tiempo a acompañar el café con churros y a hacer unos cuantos mandados pero es taaaaaan frustrante.

2. Cuando te hacen el chiste de "programar lavadoras"

Ah, ¿qué eres programador? Pues a ver si me programas la lavadora. Una torta con la mano abierta, eso es lo que te voy a programar.

El de "programar el vídeo" es otro clásico, menos mal que los VHS pasaron de moda.

3. Cuando tienes que asistir a reuniones interminables para temas que se podían solucionar con un par de emails

El aburrimiento y la ineficiencia llevada a la enésima potencia.

4. Cuando tus jefes se toman tus estimaciones como contratos blindados

O más aún: como un pacto de sangre. Y no, mira, una estimación es una estimación. Y ya.

5. Cuando tu empresa no te quiere pagar la entrada (y dietas) de ese evento al que tanto quieres asistir

O como diría Rafa Mora: "puta vida, tete".

6. Cuando tienes que trabajar con fechas

Da igual el lenguaje, cuando hay que trabajar con tipos Fecha, siempre es para quedarse todo loco (y en PHP ya ni te cuento).

7. Cuando te acosan los recruiters de las cárnicas por Linkedin

Esto lo explicaba mucho mejor ese gran intelectual que es Ortega y Gasset Cano: "Dejenme en paz, dejenme vivir". Ya está bien, hombre, ya está bien.

8. Cuando intentas ayudar en un foro y te amenazan con un pincho (y no usb)

"Ya será menos", "Exagerao, andaluz tenías que ser". Si, exagerado, ya, ya.

9. Documentar

Sí, documentar es muy necesario. Sí, documentar es un peñazo de cuidado.

10. Cuando confirmamos que el legacy code que nos ha tocado en herencia no está documentado

Claro, como el momento 9 es odioso, poca gente lo hace y llegamos a este momento 10. El karma.

11. Cuando el cliente te cambia los requerimientos a mitad de proyecto

Y pasa siempre pero aún así, fastidia que no veas.

12. Cuando arreglas un bug y aparecen muchos más

El efecto Hydra. Presencia casi asegurada en cualquier proyecto medianamente grande.

13. Cuando el viernes a última hora suena el teléfono

No. Lo. Cojas. Es un marrón. Es un marrón. Siempre es un marrón.

14. Cuando haces un Delete (o un Update) y se te olvida el Where.

Drama. Para que esto no ocurra, recuerda: "No te olvides de poner el Where en el Delete From". A fuego.

15. Ese fin de semana cuando te diste cuenta que elegir portátil en vez de equipo de sobremesa había sido un error

Te creíste muy listo pero ahora no paras de llevarte el trabajo a casa. Te la dieron con queso, reconócelo.

16. Cuando llevas horas devanándote los sesos y resulta que tan sólo se te había olvidado un punto y coma

Esa mezcla de alivio por haberlo resuelto y de decepción y vergüenza por un fallo tan tonto y obvio. Si tuvieras un cilicio, te lo apretaba más fuerte, ¿qué no?

17. Cuando haces deploy a producción y todo se va al garete

"¿He sido yo?" Pues si Steve, has sido tú. Rezemos a los antiguos dioses y a los nuevos para que el rollback vaya bien.

Y esto es todo. Los comentarios quedan abiertos para que os desahogueis tanto como he hecho yo. Te quedas como nuevo, prometido.

También te recomendamos

Los 17 momentos por los que merece la pena ser desarrollador

Coderfacts: humor de programador a programador

Los 10 mandamientos de un cíborg sobre tecnología híbrida

-
La noticia Los 17 momentos por los que odias ser desarrollador fue publicada originalmente en Genbeta Dev por Fernando Siles .


Exprimiendo Android Studio: trucos y atajos de teclado que te harán más productivo

$
0
0

Android Studio

Android Studio es la herramienta oficial para el desarrollo de aplicaciones android. Al estar desarrollado sobre IntelliJ IDEA, aprovecha (casi en su totalidad) características de edición de código, análisis, refactor y generación entre otras categorías para desarrollar de forma efectiva.

En su versión 2.2, Android Studio incluye multitud de mejoras como un nuevo editor de UI, interacción con la nueva ConstrainTLayout, APK Analyzer y muchas cosas más, este artículo no se enfoca en cubrir estas novedades. Si buscas información sobre lo nuevo de esta versión, en Genbeta Dev ya hablamos sobre Android Studio 2.2 desgranando todas sus nuevas características.

Empezamos a hablar de algunos de los trucos y atajos para sacarle el máximo partido a Android Studio.

Desactivar el mostrado automático del logcat

Puede ser interesante desactivar la expansión del panel Android Monitor cada vez que ejecutemos nuestra app (ya que éste se expande automáticamente en cada ejecución), para ello, en la configuración de ejecución que estemos utilizando tan solo es necesario desactivar dicha opción en la pestaña Miscellaneous.

Sin pestañas

Como bien dice Hadi Hadiri en este artículo, el resultado del uso de pestañas ofrece diversos inconvenientes: pérdida del contexto, ocupación de espacio para el editor, además de que la interacción con pestañas suele requerir utilizar el trackpad o el ratón.

Si crees que las pestañas no ofrecen mayor beneficio para tí puedes descativarlas en: opciones / editor / tabs y configurando la opción Placement a None.

IntelliJ IDEA ofrece una basta cantidad de herramientas para moverse efectivamente a través del código sin necesidad de pestañas.

Navegación

Uno de los objetivos que tiene el equipo de JetBrains para sus usuarios es que utilizen el ratón el menor tiempo posible. Existen multitud de acciones que permiten trabajar de forma muy efectiva sin apartar las manos del teclado.

Encontrar clases, tipos y acciones

IntelliJ IDEA y por consecuencia, Android Studio, ofrece soluciones a la hora de encontrar archivos, clases, acciónes y métodos de manera específica (cuando conocemos el nombre o parte del mismo en lo que pretendemos buscar).

Buscar en todo - ⇧ + ⇧ - Search everywhere

Muestra un diálogo para buscar todo tipo de elementos: clases, archivos, acciones, etc. Se recomienda utilizar las búsquedas especificas ya que ésta acción puede ser algo más lenta y costosa en cuanto a recursos.

Buscar tipos - ⌘ + O - Navigate class

Permite encontrar enumeraciones, clases e interfaces.

Buscar archivos ⌘ + ⇧ + O - Navigate file

Permite encontrar todo tipo archivos, útil para archivos xml como layouts, resources, etc.

Buscar acciones - ⇧ + ⌘ + o + A - Find action

Es posible consultar y ejecutar todo tipo de acciones desde esta característica, acciones que se encuentran bajo menús, determinadas preferencias, paneles, etc.

Bonus:

  • No es necesario escribir el nombre completo de lo que buscamos, si nos encontramos buscando un archivo llamado CharacterDetailPresenter, lo encontraremos únicamente buscando CharacterDetaPres.

  • Podemos ir a una línea en particular ante una búsqueda de clases (⌘ + o) poniendo el número de línea deseada detrás de lo que pretendemos buscar: CharacterDetailPresenter:50.

  • Si ponenos una / al principio del textxo cuando buscando archivos (⌘ + ⇧ + o) encontraremos directorios, por ejemplo, con /land, podemos encontrar directorios con resources para configuraciones landscape.

  • Podemos filtrar en función de la carpeta o ruta que contiene el archivo buscado, por ejemplo, values-es/strings.xml o values/strings.

Panel de proyecto - ⌘ + 1 - Project

Para navegar por los diferentes archivos del proyecto existen diferentes alternativas, una de ellas es utilizar el panel Project que muestra la estructura de archivos del proyecto, podemos expandirlo y ocultarlo con el atajo ⌘ + 1.

Bonus:

  • Mediante ⌘ + ⇧ + ⟵ / ⟶, podemos modificar las dimensiones de cualquier panel en el que nos encontremos sin necesidad de utilizar el trackpad o el ratón.

  • Podemos realizar búsquedas escribiendo el nombre de lo que buscamos, el cursor se posicionará únicamente en los resultados encontrados.

Saltar a la barra de navegación - ⌘ + ↑ - Jump to navigation bar

La barra de naveagión puede ser también interesante a la hora de navegar por los archivos del proyecto, pulsando el atajo de teclado ⌘ + ↑ podemos navegar por los archivos del proyecto.

Bonus:

  • Estando en una ruta en particular incluso podemos realizar algunas operaciones, como crear o borrar archivos en la ubicación concreta ⌘ + N o .

Mostrar y ocultar paneles

Existen diferentes modos de manipular los paneles: mostrar u ocultar alguno en particular, saltar al último panel activo (llevando el foco al mismo) y volver al editor después de utilizar un atajo.

Ocultar, restaurar todos los paneles - ⇧ + ⌘ + F12 - Hide / Restore all windows

Como su propio nombre indica, permite ocultar y restaurar todos los paneles visibles en un momento determinado.

Saltar al último panel utilizado - F12 - Jump to Last Tool Window

Restaura la visibilidad del último panel utilizado y lleva el foco a dicho panel.

Volver al editor

Cuando tenemos el foco en un panel determinado, podemos volver al editor sin necesidad de hacer click en él pulsando la tecla .

Archivos recientes

Lo normal, durante una sesión de trabajo, es trabajar sobre determinados archivos, moviendose por un grupo determinado múltiples veces.

Éstas son tres acciones que nos pueden ayudar en ese sentido:

Archivos recientes - ⌘ + E - Recently files

Muestra los archivos que han sido abiertos recientemente.

Archivos editados recientemente - ⌘ + ⇧ + E - Recently Changed Files

Muestra los archivos que han sido abiertos y editados de manera reciente.

Estructura de un archivo

Una forma rápida de navegar por los diferentes atributos y métodos de una clase o archivo es con la acción file structure, accionable con ⌘ + F12 o utilizando ⌘ + A acompañado del texto file sctructure.

Esta opción, como en otros muchos paneles y diálogos admite búsqueda, posibilitando posicionarse rápidamente en el lugar deseado.

Análogamente, el panel structure, accionable con ⌘ + 7, muestra la misma información pero de forma permanente en un panel.

Mostrar implementaciones y navegar hasta la superclase o interfaz

Es útil, en determinadas ocasiones mostrar las implementaciones de determinada interfaz o superclase. Pulsando ⌘ + B bajo la selección del nombre ya sea del método o el nombre de la clase o interfaz en cuestión, permite, de un vistazo, mostrar las actuales implementaciones, buscar, y navegar hacia ellas presionando la tecla enter.

Análogamente, con el atajo ⌘ + U en una implementación, conseguimos navegar hasta el método, superclase o interfaz que está siendo implementada.

Navegar hasta el error - F2 - Next Highlighted Error

Cuando Android Studio detecta varios errores de compilación en un archivo determinado, lo normal es utilizar el trackpad/ratón y hacer scroll hasta el lugar en donde se encuentran para solucionarlos.

Con IntelliJ IDEA, podemos posicionarnos ante los mismos pulsando F2 activando así la acción Next Highlighted Error, evitando de éste modo abandonar las manos del teclado, además de solucionarlos de forma rápida.

Primero, F2 se navegará hasta los errores, cuando estos estén solucionados, se posicionará en los warnings (en caso estén resaltados) acordes al inspeccion profile utilizado.

Ir a la última posición editada - ⌘ + ⇧ + ⌫ - Last Edit Location

A la hora de editar el código, en archivos con un número medio de líneas, se tiende a desplazarse por diferentes secciones del archivo para realizar diversas ediciones: trabajar en el cuerpo de un método, declarar un atributo de una clase, etc.

Nos podría interesar después de editar los atributos en la parte superior de una clase, volver al cuerpo de un método que estabamos editando previamente.

La acción 'Last Edit Location' mueve el cursor hasta la última edición realizada. Incluso si la edición ha sido hecha en un archivo diferente, el editor posicionará el cursor en la localización exacta de dicho archivo.

Edición

Remplazar en lugar de añadir

Cuando estamos editando código, habitualmente utilizamos el diálogo de autocompletado para añadir las opciones sugeridas.

Al añadir una sugerencia presionando la tecla ENTER, añadimos la nueva sentencia por delante de la anterior en el caso existiese, lo que requeriría una corrección.

Si en lugar de ENTER presionamos TAB, y siempre que la nueva llamada utilize el mismo número de parámetros, se reemplazará la anterior y se ajustará a los parametros ya configurados sin necesidad de nuevas ediciones.

Completar la sentencia actual - ⌘ + ⇧ + ENTER - Complete Current Statement

Teniendo Android Studio una base tan potente como lo es IntelliJ IDEA, no tenemos por qué preocuparnos de ciertos elementos sintácticos como las llaves o los puntos y comas.

Existe una acción llamada Complete Current Statement la cuál añadira los elementos necesarios en determinados contextos.

Múltiples cursores - ⌘ + G - Add Selection To The Next Ocurrence

En determinadas ocasiones, puede ser muy efectivo activar diversos cursores para ediciones simultáneas en base a un patrón que se repite.

Con la acción Add Selection to The Next Ocurrence, accionable con ⌘ + G, podemos habilitar diferentes cursores en función a un patrón determinado. Además, Android Studio e IntelliJ IDEA todavía nos aporta diferentes mecanismo de edición, como cortar y pegar múltiples fragmentos de código, mecanismos de selección, etc.

Un uso práctico podría ser, por ejemplo, cambiar los binds de vistas para utilizar Butterknife en vez del findViewById tan famoso.

Otro uso sería cambiar simultáneamente el número de versión dn diversas dependencias de la support library en archivos build.gradle, a una constante.

Unir líneas - ⌘ + ⇧ + J - Join Lines

Cuando tenemos un string concatenado múltiples veces en diversas líneas, puede resultar últil unir dichas líneas en una sola, con la acción join lines conseguiremos una única sentencia sin tener que preocuparnos de borrar los operadores de concatenación.

Ver los parámetros de un método - ⌘ + P - Parameter Info

Al utilizar el autocompletado para insertar una llámada a un método, Android Studio muestra una previsualización de los parámetros requeridos, esta previsualización se oculta al cabo de unos segundos.

Con la acción Parameter Info, accionable con ⌘ + P, podemos consultar los parámetros necesarios para la llamada utilizada.

Envolver - ⌘ + T - Surround with

A veces, nos podría interesar envolver cierto código para evaluarlo con una condición, iterar sobre el mismo o capturar una excepción

Para ello, Android Studio y por tanto, Intellij IDEA ofrece una acción muy jugosa llamada surround with, accionable por medio de un diálogo con el atajo de teclado ⌘ + T.

En dicho diálogo podemos elegir diferentes opciones, condiciones, bucles, excepciones, etc, incluso live templates.

Bonus:

Si lo accionamos en un contexto de xml, como puede ser el caso de un layout, podemos ingeniarnoslas para que, junto a un live template, envolver ciertas vistas o viegroups dentro de otros de manera muy sencilla.

Este sería un ejemplo de un live template para envolver una vista o viewgroup en xml.

Mover sentencias - ⌘ + ⇧ + ↑/↓ - Move sentence up/down

Para mover código no es necesario cortar y pegar sentencias de forma manual. La acción Move Sentence Up/Down bajo la selección de una sentencia o un conjunto de ellas, será útil para mover código de forma efectiva.

En particular, esta acción puede resultar últil editando archivos de layout en xml. Podría resultar útil seleccionar bloques y moverlos de tal modo que puedan ser contenidos en nuevos viewgroups.

Expandir o contraer una selección - ⌥ + ↑/↓ - Expand / Collapse Selection

Android Studio gracias a IntelliJ IDEA hereda un mecanismo de selección muy interesante además de inteligente.

Utilizando el atajo ⌥ + ↑/↓ siempre que tengamos el cursor en un punto particular, crearemos una selección que abarcará el scope más cercano.

Si nuestro cursor está en un parámetro de la llamada a ún método, con esta opción, primero se seleccionará el valor, luego otros parámetros, posteriormente la sentencia, el cuerpo del método y así sucesivamente hasta llegar a seleccionar el archivo entero.

Completition

Live templates - ⌘ + J - Insert Live template

Las live templates son un mecanismo muy potente para evitar escribir código boilerplate, pudiendo ser configuradas con diferentes opciones (settings/editor/live templates).

Android Studio por defecto, tiene multitud de live templates configuradas, tanto para el contexto de java como para xml.

Mediante el atajo ⌘ + J podemos mostrar un diálogo con las live templates disponibles en el contexto que nos encontramos.

Debugging

Atar debugger a un proceso

Nos podría interesar no iniciar una sesión de debug desde Android Studio, ya sea por que tenemos breakpoints configurados de determinada forma o porque podríamos querer influir la aplicación en un estado antes de iniciar el debugging.

Existe una acción llamada attach debugger to android process la cuál permite precisamente esto.

Puntos de ruptura condicionales

En código que se llama múltiples veces, podría ser de nuestro interes comprobar el estado de nuestro programa en una situación determinada.

Para ello, podemos activar un punto de ruptura únicamente cuando se produzca una condición específica, por ejemplo, cuando se muestre un determinado elemento en una lista.

Podemos configurar el punto de ruptura configurándolo con botón derecho del ratón.

Forzar un estado

Cuando estemos en un estado determinado ante un punto de ruptura, podemos forzar el programa a una situación en particular.

Mediante la acción evaluate expression, aparte de poder evaluar cualquier expresión en el contexto del punto de ruptura, también podemos forzar un estado concreto.

Diferentes tipos de puntos de ruptura

Existen diversas configuraciones a la hora de utilizar puntos de ruptura. No necesariamente es necesario para la ejecución cuando muchas veces nuestra intención en una sesión de debug es saber si el flujo pasa por determinado lugar.

Para ello, podemos desactivar la opción suspend en el diálogo de configuración del punto de ruptura para que imprima un log en la consola, el cuál podemos consultar en el panel debug (⌘ + 5) bajo la pestaña console.

También podemos imprimir como log una expresión específica, la cuál puede ser configurada en el mismo diálogo bajo la opción log evaluated expression, el cuál autocompletará con las variables del contexto del punto de ruptura.

Referencias:

No tabs in IntelliJ Idea - Hadi Hadiri

IntelliJ IDEA Tips and Tricks - Hadi Hadiri

The experts' guide to Android development tools - Google I/O '16

Android Studio for Experts - Android Summit '16

Android studio tips of the day roundups (all of them) - Philippe Breault

What's new in Android

Dev tips - Sebastiano Poggi

450 1000

Saúl Molinero es una persona entusiasta con pasión por el desarrollo móvil. Actualmente, trabaja como desarrollador android en Popsy Buy & Sell.

Además, participa activamente con varios GDGs (Google Developer Groups) además de crear y compartir contenido con diversas comunidades de desarrolladores.

Puedes encontrarlo en su blog personal, Github, en twitter y en Google+.

También te recomendamos

Lleva al extremo el Print Oriental con unos labios Ombré

Con Go 1.4 ya es posible desarrollar aplicaciones Android

Android Studio 2.2 lleva el desarrollo de Android a un nuevo nivel

-
La noticia Exprimiendo Android Studio: trucos y atajos de teclado que te harán más productivo fue publicada originalmente en Genbeta Dev por Saúl Molinero .

Algo pasa con Haskell

$
0
0

Mary 5

Sin duda existe una gran cantidad de lenguajes de programación sobre los que podemos poner nuestra mirada. Sin embargo, sólo unos pocos están llamados para la gloria. Existen muchas cuestiones por las que un lenguaje debe ser elegido sobre otros, e igualmente, existen muchas situaciones diferentes que aconsejan usar unos y no otros.

Como lenguaje de propósito general que tenga una comunidad de usuarios con cierta relevancia, Haskell es de los pocos lenguajes que posee características que divergen enormemente del resto de lenguajes. En las siguientes líneas, intentaré dar mi propia y subjetiva visión del panorama actual del ecosistema Haskell, siempre desde un punto de vista práctico y pragmático, y de paso, dar unas pinceladas sobre lo que yo he podido entrever es, la programación funcional.

¿Haskell?

Haskell es un lenguaje de programación del que yo destacaría las siguientes características:

  • Es perezoso: por defecto, cualquier expresión (dentro de una definición) no es evaluada hasta que su valor es requerido. Este concepto tan simple tiene unas implicaciones enormes y realmente sorprendentes. En la práctica, éste hecho resulta en la recomendación de que el programador piense en términos de computaciones en lugar de código, de forma que quede nítidamente claro que al definir la lista [3 * 4, 6 * 5, 1 + 2]no tenemos la lista [12, 30, 3], sino tres expresiones que podrán o no estar evaluadas cuando su valor se requiera. No te dejes engañar por la simplicidad de este mecanismo y no pierdas la oportunidad de conocer intrigantes formas de sacarle partido.
  • Mantiene la transparencia referencial: cualquier expresión en Haskell cumple la transparencia referencial es decir, dada una expresión, por compleja que sea, siempre podrá ser sustituida por su valor al evaluarla. Lo anterior es equivalente a decir que cualquier expresión en Haskell siempre siempre devolverá exactamente el mismo valor y que por tanto, no está permitida no existe ninguna función que, por ejemplo, devuelva un número aleatorio o lea de disco puesto que estas dos operaciones pueden devolver valores diferentes cada vez que son evaluadas. Otra vez, puede que te resulte simple e incluso limitado, pero de nuevo esta característica te permite manipular estructuras con un nivel de abstracción sorprendente.
  • El sistema de tipos: Haskell implementa un sistema de tipos basado en el polimorfismo Hindley-Milner ampliado con un sistema de clases de tipos (Type classes) que no tiene nada que ver con las clases de la POO. Al contrario que las dos características anteriores, sencillas de entender pero con enormes implicaciones, el sistema de tipos de Haskell ni es sencillo, ni sus implicaciones son tan trascendentales (¡siéndolo!). Aun así es tal que, una vez te acostumbras a él, lo hechas de menos en el resto de lenguajes. Creo que es el sistema de tipos el que da cohesión a las dos anteriores y juntas las tres, marcan una diferencia radical frente a otros lenguajes que "admiten evaluación perezosa" y "admiten transparencia referencial".

Desde un punto de vista emotivo, Haskell pudiera ser considerado como el abanderado de los lenguajes que nos prometía la serie de artículos Programación imperativa VS declarativa en su variante funcional, pero desde un punto de vista práctico, veremos en las próximas líneas que el diablo está en los detalles.

Aprendiendo Haskell

Comentan los profesores que el aprendizaje de Haskell es más suave en aquellos alumnos que nunca antes hayan tenido contacto con lenguajes de programación, Tanjoven en el sentido de que los segundos adquieren "las malas costumbres y pensamientos impuros" de los lenguajes imperativos (permíteme que insista con la serie Programación imperativa VS declarativa si deseas profundizar en el tema).

Yo nunca he enseñado Haskell a nadie, por lo que sólo puedo hablar por mi mismo, pero efectivamente, cuando hace unos 4 años andaba yo hastiado de la indefectible monotonía de los lenguajes, en mi búsqueda del Santo Grial me topé con Haskell. Una disrupción mental sacudió mi cerebro y fue el reto, la dificultad, la curiosidad que me hizo elegir a éste sobre otros lenguajes candidatos (Scala, Clojure y F# en particular).

Sí, dicen que la curva de aprendizaje es más acusada en Haskell que en otros lenguajes y en mi caso así ha sido (deliciosamente acusada), pero también es cierto que, ¿no es razonable que así sea si ya tenemos deformado nuestro cerebro con estrategias imperativas?.

Ha llovido mucho desde que dejé la Universidad, pero en ellas nunca oí hablar de Haskell y tan sólo los venerables Lisp y Prolog entraban a hurtadillas en el plan de estudios. Afortunadamente parece que eso ha ido cambiando desde entonces y son varias las universidades y docentes (del que me gustaría destacar a José A. Alonso del Dpto. de Ciencias de la Computación e Inteligencia Artificial de la Universidad de Sevilla) que realizan un esfuerzo para mantener viva la plasticidad de las mentes de sus alumnos.

No te quiero engañar, a mi me resultó (y resulta) difícil, pero eso es precisamente lo que me divierte y motiva.

Haskell en las trincheras

Muchos programadores tienen lenguajes fetiche, lenguajes de los que disfrutan, pero que no los usan de forma profesional. Con frecuencia Haskell es uno de ellos.

Una vez has remontado la hercúlea pendiente y te sientes cómodo entre mónadas y functores, sería temerario usarlo profesionalmente sin antes hacerse la pregunta de si Haskell es un lenguaje útil, práctico para desarrollar nuestras soluciones.

Recientemente Gabriel Gonzalez pormenorizó el State of Haskell ecosystem de las que destacaré las que, siempre en mi opinión, son las más relevantes:

  • IDE support: a mi siempre me han gustado los IDE, desde el vetusto Turbo C de Borland, siempre he sabido apreciar las comodidades que un buen IDE suministra. Haskell adolece de una solución que pueda satisfacer, sobre todo, a aquellos que se inician en el lenguaje. Particularmente utilizo vim, porque me permite trabajar cómodamente de forma remota, emacs podría ser la alternativa adecuada y está Leksah programado en Haskell pero que no termina de enganchar. No, en mi opinión no hay una solución adecuada y debes tunearte por tu cuenta un entorno de trabajo que te resulte cómodo.
  • Standalone GUI applications: si te planteas desarrollar este tipo de aplicaciones, el problema se agudiza y deberías analizar bien la arquitectura a utilizar si tu aplicación tendrá un tamaño considerable.
  • ARM processor support: Haskell tiene soporte para Windows y Linux sobre x86_64 e i686 pero adolece de formas robustas de desarrollar para otras plataformas (en particular para Android e iOS). Si bien es cierto que es posible distribuir para todas ellas (incluidas Raspberry y Arduino).

Realmente ninguna de las anteriores tiene una gran relevancia, pero sí es cierto que sobre todo para front-end parece recomendable que si nuestro sistema va a tener un tamaño apreciable, usemos entornos con un tooling más productivo.

Mi propia conclusión es que hoy en día Haskell es una fantástica opción si tu equipo de desarrollo está capacitado y lo usas para la parte de negocio. El despliegue es trivial (más allá de tu propia arquitectura), las dependencias nulas y consumos de recursos de servidor muy ajustados.

¿Es Haskell el futuro?

Tristemente y en mi opinión, no. No creo que se vuelva mainstream a corto o medio plazo, aunque también creo que siempre será una opción apreciada y usada por muchos desarrolladores y empresas. Este hecho es un condicionante muy importante para muchos, dado que limita la cantidad de soporte y tooling respecto de otras soluciones, aun cuando proporcionalmente, en mi opinión, está notablemente por encima de otras. Por desgracia el contexto actual hace que, popularmente, las cosas negativas de Haskell tengan más peso que las positivas.

En todo caso y sin dudarlo, sea por curiosidad, porque te gustan los retos (Functional pearls) o sencillamente para tener una visión mejor de lo que significa ser programador, te recomiendo que ¡aprendas Haskell por el bien de todos!.

También te recomendamos

Recopilatorio del "Hello World" en diferentes lenguajes de programación, más de 400 ejemplos

Una habitación compartida para hermanos a prueba de peleas

Pliegues, una forma de encapsular las iteraciones en listas

-
La noticia Algo pasa con Haskell fue publicada originalmente en Genbeta Dev por Jose Juan .

Testeando tus aplicaciones Java con Spock: tests más expresivos, fáciles de leer y mantener

$
0
0

Testing Java Con Spock

No es ninguna sorpresa que en el mundo Java la herramienta de test más utilizada sea JUnit si tenemos en cuenta que fue creada hace más de 15 años. Esto, sin embargo, no implica que sea la mejor, sino que en muchas ocasiones seguimos utilizando las mismas herramientas por inercia o porque aquí siempre se ha hecho esto así sin plantearnos si existen alternativas mejores. Una de estas alternativas es Spock.

Spock es un framework de tests basado en Groovy que podemos utilizar para testear tanto aplicaciones Java como Groovy. Con Spock podemos escribir tests muy expresivos, fáciles de leer y mantener. Todo ello es posible por dos motivos principalmente: el magnífico DSL que proporciona Spock y la potencia de Groovy, lenguaje con el que escribimos los tests.

Proporciona un runner de JUnit por lo que es compatible con cualquier herramienta, IDE y servidor de integración continua que utilicemos actualmente con JUnit. Porque, no nos engañemos, aunque conocemos la importancia de escribir tests, a todos nos da pereza escribirlos en ocasiones, y si encima las herramientas no ayudan, tenemos un motivo más para no hacerlo. En este artículo veremos lo que Spock puede hacer por nuestros tests.

Empezando con Spock

Empezar a escribir tests con Spock es muy sencillo, lo único que tenemos que hacer es añadir a nuestro proyecto Java la dependencia testCompile 'org.spockframework:spock-core:1.0-groovy-2.4' y, opcionalmente, testCompile 'org.codehaus.groovy:groovy-all:2.4.7' si queremos utilizar una versión de Groovy distinta a la 2.4.1 incluída con Spock.

Creando nuestro primer test

Vamos a crear nuestro primer test y explicar cada parte en detalle:

import spock.lang.Specification

class MiPrimerTest extends Specification {             // 1

    void 'invertir una cadena de texto'() {            // 2
        given: 'una cadena de text'                    // 3
            def miCadena = 'Hola Genbetadev'

        when: 'la invertimos'                          // 4
            def cadenaInvertida = miCadena.reverse()

        then: 'se invierte correctamente'              // 5
            cadenaInvertida == 'vedatebneG aloH'
    }
}

Con un primer vistazo seguro que nos llaman la atención varias partes del test:

  1. Todos nuestros tests deben heredar de spock.lang.Specification puesto que en esa clase se encuentra definido el runner compatible con JUnit.
  2. El nombre de cada test se escribe como una cadena de texto entre comillas. Se acabó el nombrar los test como testInvertirCadenaDeTexto o similar. Ahora podemos escribir nombres de tests muy descriptivos y que realmente expresan el motivo del test.
  3. En su forma más general todos los tests de Spock se basan en los bloques given, when, then, siendo given en el que establecemos el estado inicial de nuestro test.
  4. En el bloque when describimos los estímulos, es decir, lo que queremos testear.
  5. Finalmente, en la parte then pondremos las condiciones que se deben cumplir para que el test pase. Es importante notar que lo que escribamos en este bloque son aserciones, por lo que no es necesario usar assert delante de cada una de ellas.

Cabe también destacar que podemos escribir opcionalmente un pequeño texto explicativo en cada una de los bloques, given, when, then. De hecho se considera una buena práctica porque hace que podamos leer todo el test sin tener que mirar en detalle el código del mismo.

Una alternativa a escribir el test anterior que podemos usar en ocasiones para reducir la verbosidad del mismo es utilizar el bloque expect en el que directamente definimos nuestras expectativas.

void 'invertir una cadena de texto'() {
    expect:
        'Hola Genbetadev'.reverse() == 'vedatebneG aloH'
}

¿Y si falla un test?

Si pensamos en TDD, sabemos que el ciclo de test sería escribir un test que falle, escribir el código mínimo que hace que el test pase y finalmente refactorizar el código.

Una característica que debe tener un buen framework de test es mostrar información relevante de cómo y por qué ha fallado un test. A ninguno nos gusta tener que llenar el código de println's o tener que depurar cuando el test falla. ¿No sería mejor que el framework nos mostrara de una forma visual y directa por qué el test ha fallado? ¡Power asserts al rescate!

Imaginemos el siguiente test. Queremos comprobar que el primer lenguaje de un usuario es Java. Este test falla porque como vemos, tenemos una lista de lenguajes y el primero de ellos es Groovy.

void 'El nombre del primer lenguaje es Groovy'() {
    given: 'información de un usuario'
        def info = [
            nombre  : 'Iván',
            lenguajes: [
                [nombre: 'Groovy', conocimientos: 10], [nombre: 'Java', conocimientos: 9]
            ]
        ]

    expect: 'su primer lenguaje es Java'
        info.lenguajes.nombre.first() == 'Java'
}

Si ejecutamos el test, además de indicarnos que ha fallado, Spock nos mostrará la siguiente salida:

Condition not satisfied:

info.lenguajes.nombre.first() == 'Java'
|    |         |      |       |
|    |         |      Groovy  false
|    |         [Groovy, Java] 5 differences (16% similarity)
|    |                        (Groo)v(y)
|    |                        (Ja--)v(a)
|    [[nombre:Groovy, conocimientos:10], [nombre:Java, conocimientos:9]]
[nombre:Iván, lenguajes:[[nombre:Groovy, conocimientos:10], [nombre:Java, conocimientos:9]]]

Expected :Java

Actual   :Groovy

Vemos que tenemos la información de cada variable del assert de tal forma que podemos ver claramente todos los valores y saber por qué ha fallado el test sin necesidad de depurar ni de println's adicionales.

Una de las killer features de Spock: Data driven testing

En multitud de ocasiones tenemos que testear el mismo código pero con distintos datos de entrada. Además, en ocasiones, el setup necesario para probar el test no es despreciable por lo que en la práctica acabamos con una gran cantidad de tests en los que el 90% del código es el mismo y sólo cambian los datos y el resultado. Para solucionar este problema podemos usar lo que Spock llama Data driven testing.

void 'comprobando el máximo entre dos números'() {
    expect:
        Math.max(a, b) == resultado

    where:
        a  | b | resultado
        1  | 4 | 4
        5  | 2 | 5
        -1 | 3 | 3
}

Creo que el test es suficientemente explicativo por sí mismo. Hemos creado una tabla de datos y Spock ejecutará el test tres veces sustituyendo en cada una de ellas las variables a, b y resultado con los valores de cada línea. Esta aproximación, aunque directa y muy visual, tiene un pequeño problema. Si cualquiera de las iteraciones hace fallar el test, sólo sabremos que el test ha fallado pero no podremos saber exactamente cual de ellas lo ha hecho fallar. Para solucionarlo, añadiremos la anotación @Unroll y además podremos sustituir el nombre de las variables en el propio nombre del test.

@Unroll
void 'El máximo entre dos números #a y #b es #resultado'() {
    expect:
        Math.max(a, b) == resultado

    where:
        a  | b | resultado
        1  | 4 | 4
        5  | 2 | 5
        -1 | 3 | 3
}

Así, el resultado ahora será:

Spock Data Driven Test

Aprovechando la potencia de Groovy

Hasta ahora hemos visto alguna de las principales características de Spock pero hay otra que puede que hayamos pasado de largo: Groovy. Independientemente de que estemos testeando código Java o Groovy nuestros tests se escriben siempre en Groovy.

Aunque a priori no pueda parecer importante, o incluso pienses que no quieres aprender un lenguaje nuevo para escribir los tests, en poco tiempo entenderás por qué es tan importante Groovy para conseguir esa expresión y legibilidad en nuestros tests. Como creo que la mejor forma de mostrarlo es con un ejemplo. Imaginemos que tenemos el siguiente método que queremos testear que simplemente devuelve una lista de personas.

public static List makePersonList() {
    return Arrays.asList(
        new Person("Sheldon", "Cooper"),
        new Person("Leonard", "Hofstadter"),
        new Person("Raj", "Koothrappali"),
        new Person("Howard", "Wolowitz")
    );
}

Siendo Person el siguiente POJO:

public class Person {

    private String name;
    private String lastName;

    public Person() {
    }

    public Person(String name, String lastName) {
        this.name = name;
        this.lastName = lastName;
    }

    // Getters y setters omitidos
}

Ahora podemos escribir el siguiente test:

void 'testeando una lista de personas'() {
    when:
        def personList = DataHelper.makePersonList()

    then:
        personList.size() == 4
        personList.name == ['Sheldon', 'Leonard', 'Raj', 'Howard']        // 1
        personList.name.sort() == ['Howard', 'Leonard', 'Raj', 'Sheldon']
        personList.lastName.collect { it.size() } == [6, 10, 12, 8]
        personList.name.min { it.length() } == 'Raj'
}

¿Vemos algo raro en personList.name? ¿Qué significa esto? ¿De verdad tenemos un List<Person> y estamos accediendo a name en esa lista? En realidad lo que está ocurriendo es que estamos aprovechándonos del syntactic sugar que añade Groovy para poder extraer el nombre de cada una de las personas que están en la lista. El código anterior lo podríamos escribir también de las siguientes formas, siendo cada una de ellas un poco más parecida a Java, hasta llegar a la última que sería el equivalente en Java 8:

personList.name
personList*.name // spread operator
personList.collect { it.name }
personList.collect { Person p -> p.name }
personList.collect { Person p -> p.getName() }
personList.stream().map { it.name }.collect(Collectors.toList())
personList.stream().map { p -> p.getName() }.collect(Collectors.toList())

Como veis, por el simple hecho de utilizar Groovy para nuestros test hemos conseguido éstos sean muy expresivos y fáciles de entender.

Testeando código con colaboradores

En nuestro código del día a día tenemos clases y objetos que interaccionan entre ellos, se llaman entre sí y son dependencias unos de otros. El problema viene cuando queremos testear uno de estos métodos que tiene algún colaborador y no queremos que éste interfiera en nuestro test. En el mundo Java estamos acostumbrados a utilizar frameworks de mocking como JMock, EasyMock o Mockito, que aunque pueden ser utilizados con Spock, no son necesarios pues Spock incluye el suyo propio sin necesidad de añadir una dependencia adicional.

Finalmente, según el comportamiento que queramos obtener de nuestros colaboradores, usaremos Mock o Stub.

Mocks

Un mock es un objeto sin comportamiento en el que podremos llamar a un método pero no habrá ningún efecto adicional más allá de devolver el valor por defecto del propio método. La idea es utilizarlo para comprobar que un método se ha ejecutado e incluso con qué parametros lo ha hecho.

Un ejemplo en el que se puede ver la utilidad de un mock es el siguiente: Imaginemos que estamos dando de alta un usuario en nuestra plataforma (método createUser) y la acción final es notificar por email (notificationService.sendNotification) a ese usuario de que su cuenta ha sido creada correctamente. Durante la ejecución de los tests de este método no queremos enviar un correo electrónico pero queremos asegurarnos de que el método se llama correctamente y queremos que el test falle si no es así.

public class UserService {

    private NotificationService notificationService;

    public UserService(NotificationService notificationService) {
        this.notificationService = notificationService;
    }

    void createUser(String nombre, String apellido) {
        Person person = new Person(nombre, apellido);

        // Comprobaciones
        // Lógica de negocio
        // Almacenar el usuario en base de datos

        notificationService.sendNotification(person, "Usuario creado correctamente");
    }
}

El test sería así:

void 'notificacion enviada cuando se crea un usuario'() {
    given:
        def mockedNotificationService = Mock(NotificationService)
        def userService = new UserService(mockedNotificationService)

    when:
        userService.createUser('Iván', 'López')

    then:
        1 * mockedNotificationService.sendNotification(_, 'Usuario creado correctamente')
}

Lo primero que hacemos es crear el mock de NotificationService y lo inyectamos al crear el servicio que estamos testeando UserService. Después, en el bloque then podemos comprobar que el método de envío de notificaciones has sido ejecutado solamente una vez en nuestro mock. Si el método no se ejecuta o lo hace más de una vez, el test fallará.

Stubs

Si en lugar de simplemente querer asegurarnos de que un método se ha ejecutado necesitamos que éste devuelva un determinado valor o lance una excepción, lo que haremos será un stub.

Un caso de uso para un stub puede ser que necesitemos obtener algún valor de la base de datos para continuar con nuestro test. Ejemplo:

public interface PersonRepository {
    Person findById(Long id);
}

Y el test sería:

void 'obtenemos un valor predeterminado'() {
    given:
        def stubbedRepository = Stub(PersonRepository) {
            findById(_) >> new Person('Iván', 'López')
        }

    when:
        def person = stubbedRepository.findById(1)

    then:
        person.name == 'Iván'
        person.lastName == 'López'

}

El anterior es un ejemplo muy básico pero un stub en Spock se puede personalizar de diferentes formas. Según nuestras necesidades podemos querer devolver distintos valores en llamadas consecutivas al mismo método, lanzar una excepción o incluso devolver un valor en función de los parámetros de entrada.

Resumen

Hemos visto una introducción muy rápida y básica a Spock que espero sirva para que os planteeis introducirlo en algún proyecto y empezar a utilizarlo poco a poco. Nos dejamos muchas cosas en el tintero: Comprobación de excepciones, extensiones (@IgnoreRest, @IgnoreIf, @Stepwise,...) el método old, comparadores de Hamcrest... Si teneis curiosidad por conocer todos estos detalles os remito a la documentación oficial. Para profundizar aún más os recomiendo el libro Java Testing with Spock que fue publicado en diciembre de 2015 e incluye los últimos cambios hasta Spock 1.0.

Todos los ejemplos incluidos en este artículo se encuentran en un repo de Github para que podais probar y ejecutar todo vosotros mismos.

También te recomendamos

Android Studio 1.1 habilita el soporte para hacer test unitarios

Tienes 30, pero tu piel refleja 50. ¿De verdad sabes cuántos años tiene tu rostro?

The Eclipse Memory Analyze, una excelente herramienta para buscar memory leak

-
La noticia Testeando tus aplicaciones Java con Spock: tests más expresivos, fáciles de leer y mantener fue publicada originalmente en Genbeta Dev por Iván López .

Formarse en Calidad de Software. Requisitos, cursos y más

$
0
0

Formarse en Calidad de Software. Requisitos, cursos y más Con cierta frecuencia me llegan preguntas sobre "cómo formarse en calidad de software", "qué cursos o master se pueden realizar", o "qué debería estudiar o hacer para conseguir un puesto como QA Tester". La verdad es que no es una pregunta sencilla. Casi cada especialista que conozco en pruebas de software ha tenido una trayectoria laboral diferente, y lo mismo es aplicable a su formación.

El perfil del tester o espcialista en pruebas de software ha cambiado mucho y actualmente está en plena (r)evolución. Hace no demasiado tiempo se valoraba sobre todo que fueran personas capaces de escribir y ejecutar casos de tests enfocados principalmente en el usuario final, con mucha capacidad de análisis y detallistas. Pero no era habitual que se pidiera dominar ningún lenguaje de programación, ni que se supiera nada sobre el ciclo de desarrollo de software, ni sobre análisis estático de código, o cómo hacer consultas a base de datos, por poner sólo algunos ejemplos.

Las cosas han cambiado. Ahora, un tester debe dominar, por lo menos, un lenguaje de programación. Como comentaban en expoqa'15, la automatización no hará las pruebas más fáciles, hará las pruebas posibles. En un mundo donde todo está conectado, los especialistas en pruebas de software debemos ser capaces de automatizar las pruebas, y para ello es necesario dominar algún lenguaje de programación. Además, hay que conocer cómo es el ciclo de vida de software, saber cómo funciona un equipo ágil, tener conocimientos de integración continua y conocer las herramientas que vamos a necesitar, algunas de ellas muy específicas de la parte de pruebas de software.

¿Qué perfil de probador de software buscan las empresas?

Lo que las empresas buscan en sus ofertas son perfiles que incluyan:

  • Estudios mínimos: Ingeniero Técnico ó Ciclo Formativo Grado Superior
  • Experiencia en el uso de herramientas de pruebas como Selenium, JMeter o SoapUI (estas son las 3 herramientas clásicas relacionadas con pruebas de software, y cualquier tester debería conocerlas al menos básicamente)
  • Capacidad de escribir código en al menos un lenguaje orientado a objetos
  • ISTQB (Foundation Level)

Respecto a los estudios mínimos, creo que las empresas valoran el que los candidatos tengan esos conocimientos, pero también saben que hay testers sin esos estudios, que se han formado de forma autodidacta y han adquirido a través de la experiencia parte de esos conocimientos que se consiguen estudiando una ingeniería o ciclo formativo.

Sobre los conocimientos de herramientas como Selenium, JMeter o SoapUI, estos se pueden adquirir de manera autodidacta o trabajando en equipos que ya las utilizan, pero no hay centros formativos que impartan cursos para aprender a usarlas.

Saber programar es uno de los requisitos más importantes actualmente para tener un cierto futuro en el mundo de las pruebas de software. Es más, cuanto mejor programador seamos, mejor probador. Conocer la forma en que se crea el código hace que sepamos también que que aspectos pueden ser fuente de problemas.

Si, pero ¿qué lenguaje de programación tengo que aprender?

Creo que es una elección personal, y que dependiendo de esa elección podremos trabajar en equipos de desarrollo que utilicen esa misma tecnología. El Índice Comunitario de Programación (TIOBE) publica un ranking de popularidad de los lenguajes de programacion que puede servirnos para decidir qué lenguaje elegir. En cualquier caso, más importante que conocer un determinado lenguaje de programación, lo importante es saber programar, tener una buena base, y conocer buenas prácticas de desarrollo de software.

15morepopularprogramminglanguages Los 15 lenguajes de programación más populares en 2016 según tiobe.com

¿Que certificaciones existen en esto de las pruebas de software?

Las 2 que merece la pena tener en cuenta son la certificación del ISTQB (International Software Tersting Qualification Board) y el TMap de Sogeti. Se trata de 2 certificaciones bastante maduras, y en los 2 casos es relativamente fácil encontrar centros dónde asistir a cursos y después certificarse, o simplemente certificarse, tras prepararnos el examen por libre. Para la certificación ISTQB nexoQA organiza cursos con los que preparar la certificación y hacer el examen. Sogeti por su parte organiza cursos para prepararse la certificación del TMap.

Estos cursos no son cursos con los que aprender a probar software, sino que van a ser un apoyo para certificar unos conocimientos mínimos en el área de testing y calidad de software. Mi impresión es que actualmente en España, el ISTQB (Foundation Level) es el "más demandado".

La agilidad también ha jugado un papel importante en el cambio del rol de probador de software. En los desarrollos 'en cascada' existía la 'fase de pruebas', igual que existía la fase de toma de requisitos, y existía un 'equipo de pruebas' independiente del equipo de desarrollo. Todo esto ha cambiado con la implantación del desarrollo ágil.

También te recomendamos

Publicada la versión JMeter 2.5

Testing Unitario con Microsoft Fakes, un libro imprescindible

¿Cuántos años de más te echan por tus ojos?

-
La noticia Formarse en Calidad de Software. Requisitos, cursos y más fue publicada originalmente en Genbeta Dev por Raúl Hernández .

Retos de la agilidad en empresas grandes

$
0
0

King Kong 1933 King Kong 2814496 2400 1891

Son las 20:13, sonido en el móvil y el correspondiente mensaje de WhatsApp. Es de Marta. Ella trabaja con el rol de responsable de proyectos y, entre varios mensajes, quiere compartir conmigo que, después de meses de trabajo, el comité de dirección de su empresa, una de las que en el sector llamaríamos “grandes”, ha cancelado lo que allí llamaban la “transformación ágil” de su proyecto.

Marta me comenta que la dirección de su empresa ve demasiado grandes los cambios organizativos, estructurales, contractuales, etc., necesarios para poder acometer, realmente, el cambio que requiere trabajar de manera ágil.

La frustración y pérdida de ilusión de Marta queda reflejada en una frase: “Realmente nadie dirá públicamente que no trabajamos de manera ágil y esto acabará en un Scrum con peros” (argot que usamos en el sector para denominar a esos proyectos que sólo usan partes de la agilidad, por ejemplo, “usamos Scrum pero... el Testing lo hace un equipo externo”).

“Realmente nadie dirá públicamente que no trabajamos de manera ágil y esto acabará en un Scrum con peros”

El caso de Marta representa uno de tantos, pasada la moda y novedad de la agilidad en las empresas grandes viene ponerse con la transformación y ahí aparecen los verdaderos retos.

Y el caso de Marta contrasta con otro gran grupo de empresas grandes con las que hoy me encuentro, aquellas que sí, con esfuerzo, tiempo y constancia, han logrado, o están logrando, cambiar obsoletas maneras de trabajar por aquellas que hoy llamamos ágiles. Lo que augura un presente - futuro de dos velocidades: empresas grandes cuyos negocios de base tecnológica trabajan de manera mucho más eficiente (llámalo ágil) y empresas (o partes de ellas) que no pudieron salir de aquellas viejas y tradicionales maneras de trabajar.

¿Pero por qué? ¿Cuáles son esos retos que hacen que para algunos sea tan complejo el cambio? Enumerar todos ellos sería demasiado extenso para un post, pero déjame que te resalte los que en mi experiencia son los más comunes y complejos, y que sirva este como un primer post de varios en los que iremos profundizando en algunos de los siguientes retos.

Las dimensiones del desarrollo

Decía McConnell, en su “Rapid Development” (cuando aún la palabra ágil no existía como tal el mundo de la tecnología), el que para mí, aun a pesar de sus años, es uno de los mejores libros sobre gestión en tecnología, que lo “sano” que es un proyecto software se basa en cuatro dimensiones: personas, procesos, productos y tecnología. Vamos a ir repasado los mayores retos hoy de la agilidad en empresas grandes, en función de las tres primeras dimensiones de McConnell.

Personas

Un equipo multifuncional es aquel que posee todas las competencias necesarias para lograr completar el trabajo, sin depender (o dependiendo mínimamente) de otros equipos, áreas, o roles fuera del mismo

Aunque parte del sector no lo viera así durante años, las personas y equipos son, sin duda, lo más determinante. Objetivo del tradicional “Peopleware”. Como decía Cockburn, las personas son el componente no lineal de primer orden en el desarrollo software. Decía McConnell que las personas son lo que tiene más potencial para recortar el tiempo de un proyecto. Y decía Glass, que no hay que olvidar que las personas son las que hacen el software. O que “Las personas son la clave del éxito”, que dijera Davis.

Decenas de aspectos podríamos mencionar aquí en lo que refiere a personas, equipos, en empresas grandes trabajando de manera ágil, desde el talento, a la motivación, pasando hasta por el efecto del entorno. Pero hoy, y aquí, me voy a centrar en tres, aquellas que vienen de que un equipo ágil es multifuncional, auto-organizado y pequeño.

Un equipo multifuncional es aquel que posee todas las competencias necesarias para lograr completar el trabajo, sin depender (o dependiendo mínimamente) de otros equipos, áreas, o roles fuera del mismo. Dicho lo anterior, este es uno de los mayores retos en muchas empresas grandes, que se han estructurado desde hace años en base a modelos de externalización. Caso muy representativo aquí es el de Testing, en muchos lugares externalizado, lo que impide a los equipos ser realmente multifuncionales.

Un equipo auto-organizado, como explica Appleton, es un equipo dirigido y organizado por sus propios miembros, para alcanzar los objetivos especificados por la gerencia. Esto conlleva a jerarquías más planas, a revisar figuras tradicionales, como la del jefe de proyectos, etc. Un reto organizativo en toda regla.

Y, de manera general, en agilidad, se sigue la premisa, bastante antigua, por cierto (ya se citaba en el famoso “mítico hombre mes” de Brooks, 1975) de que los equipos grandes son menos productivos que los pequeños (de ahí que los equipos en Scrum sean de entre 5 y 9 personas). Otro reto organizativo si venimos de trabajar en equipos grandes y muy jerarquizados.

Procesos

“Frameworks” como Scrum o eXtreme Programming son hoy ya bastante conocidos en el sector. Pero tener un equipo y que este trabaje con sus correspondientes Sprints, su Product Backlog, etc., no es lo mismo que tener muchos equipos, tener coordinar diferentes Sprints, integrar, tener muchos Product Backlog, muchos Product Owner, muchos Scrum Master, etc.

De nuevo, aquí podríamos enumerar decenas de retos, pero déjame que te resalte, más que nada porque hoy suele ser tema común de conversación en estos ámbitos, el reto de la gestión de varios Product Backlog.

Un problema frecuente en empresas grandes es el miedo a perder la visión global, de ahí que los diferentes “frameworks” que proponen como llevar la agilidad a empresas grandes (Less, DAD, SAFe, etc.) afrontan, cada uno desde su visión, entre otros, lo que algunos llaman gestión ágil del portfolio, y ese salto desde orientar la gestión en base a proyectos para orientarla en base a equipos.

Producto

“Clean Code”, calidad software, deuda técnica, estrategia de control de versiones, Testing ágil, la lista completa sería larga, y estos son sólo algunos de muchos términos que hoy podemos asociar a esta dimensión, tratados todos ellos, de una manera u otra, cuando hablamos de agilidad.

Para cualquiera que haya trabajado en desarrollo aquí no hay ninguna duda: la calidad del código, del diseño, de sus pruebas, el grado de malas y buenas prácticas, etc., puede bloquear cualquier iniciativa de mejora en cualquiera de las anteriores dos dimensiones. Más si queremos ir sacando productos potencialmente entregables en iteraciones muy cortas.

Si la deuda técnica (el “interés” que hay que ir pagando cuando se introduce una mala práctica en el software) nos come... la mantenibilidad cada vez será más compleja y será muy difícil aguantar en ritmo de los Sprint.

Si te pasas hoy por alguna empresa de las llamadas grandes, intentando trabajar de manera ágil, verás como, sin duda, este es uno de los mayores retos, que en muchos casos es altamente complejo, más en empresas grandes, que suelen llevar en sus espaldas muchos años de desarrollo, con aplicaciones muy grandes... y mucho código “legacy”.

Rehacer de cero una aplicación “legacy” grande, con años de desarrollo, es, por muchas razones, algo irreal la mayoría de ocasiones, por lo que las actuales iniciativas que hoy nos encontramos (que darían para mucho escribir) pasan por aislar partes y buscar aquellos puntos concretos sobre los que una refactorización añade más retorno de inversión.

Futuro...

En aquel 2001 en el que participé por primera vez en un proyecto ágil... ninguno de los que nos dedicamos a ello pensábamos que con los años la agilidad iba a llegar hasta la alta dirección de muchas empresas de las que llamamos “grandes”.

Más allá de que esto haya podido ocurrir por cuestiones de moda, lo que nos encontramos hoy es una necesidad real de cambio, cambio para poder sobrevivir en un entorno cada vez más competitivo, que se basa en la tecnología, que necesita y depende del software, de acelerar el "time to market" cada vez más.

Pero nadie dijo que fuera fácil, y escalar a la agilidad hoy se traduce en un ámplio conjunto de retos. Tratar todos ellos sería demasiado extenso para un post... y probablemente este será el primero de varios, en los que iremos recorriendo varios de estos aspectos.

Nadie dijo que fuera fácil... ni imposible.

También te recomendamos

¿Cuántos años de más te echan por tus ojos?

Scrumblr, tablón Scrum para equipos de desarrolladores que trabajan a distancia

¿Es un pájaro? ¿es un avión? ¡No! ¡Es Scrum!

-
La noticia Retos de la agilidad en empresas grandes fue publicada originalmente en Genbeta Dev por Javier Garzas .

10 cosas sobre trabajar en remoto que quizá no habías pensado y deberías tener en cuenta

$
0
0

Trabajar En Remoto

Hace ya casi dos años que pisé por última vez una oficina y empecé a trabajar en Plex desde casa, en un equipo deslocalizado a lo largo y ancho del planeta.

Muchas cosas cambian cuando pasas de levantarte cada mañana para ir a tu puesto de trabajo a sentarte en un escritorio a 10 pasos de tu cama. Y aunque seguramente ya se ha escrito mucho sobre el tema (yo mismo grabé una entrevista con mi compañero Jesús Manzano), hoy quería dar un punto diferente a este tema, y buscar 10 ideas distintas que no se cuentan tan habitualmente sobre el hecho de trabajar en remoto.

1. Un equipo distribuido significa que hay gente trabajando las 24 horas

Workaholic

Y esto implica que la empresa nunca descansa, y de que tú, si te descuidas, tampoco. Siempre hay alguien avanzando trabajo y que puede necesitar tu ayuda en cualquier momento. Y si, como es mi caso, la compañía es americana, implica que la mayor parte de tus compañeros empiezan a trabajar cuando tú vuelves de comer, así que sólo hay media jornada de coincidencia.

Hay con gente que incluso menos. Tenemos reuniones en las que para mí son las 19 de la tarde y para algunas personas las 7 de la mañana.

Esto, unido a que no hay una ruptura clara entre tu puesto de trabajo y tu casa, hace que el número de horas de trabajo se te pueda ir de las manos con mucha facilidad. Por eso, marcarte un horario se vuelve imprescindible.

2. No te mueves nada en todo el día

Salud

Pero cuando digo nada, es NADA. Si no haces un esfuerzo real por moverte, salir a pasear, hacer un poco de ejercicio, tu salud corre peligro.

El día que empecé a usar una Mi Fit descubrí una dura realidad... Podía haber días en los que no alcanzaba ni los 1.000 pasos. Teniendo en cuenta que lo recomendado suele ser unos 10.000 pasos diarios, te puedes imaginar lo perjudicial que puede ser eso para tu cuerpo.

Si trabajas en casa, necesitas algún dispositivo que mida tu actividad. Lo que no se puede medir, no se puede controlar. Es increíblemente difícil llegar a los 10.000 pasos si trabajas en casa, porque todos los trayectos que inconscientemente haces en tu día a día (ir al trabajo, salir a comer, incluso ir al baño...) se pierden.

Por eso, mi propósito es salir a pasear todos los días después de comer con el fin de alcanzar al menos los 6.000 pasos diarios. Muy lejos de un objetivo saludable, pero es algo que pretendo ir mejorando con el tiempo. Y me estoy planteando seriamente adquirir un standing.desk.

3. Puedes aprovechar mucho mejor tu tiempo

Productivo

Si te organizas bien, podrás estirar tus días mucho más que yendo a una oficina, sobre todo si tu trayecto hasta el trabajo es largo.

Yo dedico todas las mañanas un rato (hora y media, dos horas) a mis proyectos personales, como pueden ser mi blog, el libro, o escribir en Genbeta Dev. Cosas que, por supuesto, podría hacer si trabajara por cuenta ajena (ya las hacía antes), pero avanzaría de forma mucho más lenta.

Para mí, ahora mismo, trabajar en remoto es indispensable para poder sacar adelante todos mis proyectos, y sería muy difícil plantearme el trabajo en una oficina.

Además, permite gestionar mucho mejor tu vida personal. Normalmente todos los trabajos en remoto permiten una flexibilidad de horarios absoluta.Y aunque es recomendable seguir un horario para no volverse loco, el tener la posibilidad de reorganizar tu día en función de tus necesidades es una maravilla.

4. Obliga a tener procesos de trabajo muy simplificados

Simple

A mí este punto me gusta especialmente. Cuando tu forma de comunicación principal es la escrita y necesitas comunicarte con gente literalmente mientras duermes, la única solución es simplificar al máximo.

Nada de metodologías complejas con cientos de reuniones, de roles, de tareas burocráticas... Las reuniones se reducen al mínimo posible y los procesos necesitan ser sencillos y fáciles de seguir por todo el mundo de forma autónoma.

Aquí cada empresa buscará su mecanismo en función de sus necesidades. A nosotros, al trabajar en un producto propio, nos es suficiente con una serie de objetivos trimestrales con responsables por plataforma, que son los encargados de dividir la tarea en partes manejables y asignarlas a las milestones quincenales.

5. Te puedes volver un ermitaño

Programador

Cuanto menos sales de casa, menos te apetece salir. Los atascos, el metro, las aglomeraciones... todo es evitable, y es muy tentador evitarlo. Esto no es bueno por muchas razones: necesitas relacionarte con otras personas y cambiar de entorno para desconectar. Cuando te pasas todo el día metido en casa sin hablar con nadie, incluso se nota en la capacidad de comunicarte.

La parte buena de esto es que tienes una excusa perfecta para hacer planes en diario cualquier día. También es muy interesante tener la posibilidad de ir a algún sitio a trabajar de vez en cuando, ya sea un coworking, una cafetería, o cualquier espacio donde te puedas relacionar con otras personas. Nosotros tenemos alquilados algunos puestos en las oficinas de Karumi, y vamos allí a trabajar de vez en cuando.

6. Es más difícil aprender de tus compañeros

Aprender

No lo vamos a negar. Para mí este es uno de los mayores inconvenientes (si no el que más) de trabajar desde casa. No puedes sentar a tu compañero al lado para que te explique cómo solucionaría esto, o cómo programó aquello.

Por supuesto que las tecnologías hoy en día permiten muchas cosas, pero al final el trato cercano se pierde. No surgen con tanta facilidad las conversaciones técnicas sobre cómo solucionar un problema, o por qué una aproximación es mejor que otra.

En este caso las revisiones de código se vuelven incluso más necesarias, no sólo para comprobar la validez de la solución, sino para aprender unos de otros.

7. Se te valora por rendimiento y no por tiempo trabajado

Horas Trabajo

Siempre se ha criticado mucho el sinsentido de las jornadas de 8 horas, y más en una profesión no mecánica como la nuestra, en la que la situación mental juega un papel esencial para poder desempeñar nuestro trabajo.

En un trabajo deslocalizado con horarios flexibles, si un día eres productivo trabajando 4 horas y al siguiente necesitas 12, o si un día no te encuentras inspirado y al siguiente rindes el doble, no hay ningún problema. Si haces bien tu trabajo, no importa cuándo.

Esto, en mi opinión, ayuda a ser más productivo.

8. Facilita la conciliación de la vida laboral y familiar

Familia

Una vez más, es una ventaja inherente al hecho de tener horarios flexibles. Puedes llevar a tus hijos a la guardería, recogerlos para la hora de comer, pasar tiempo con ellos... y trabajar en los ratos en los que no están o están entretenidos en otras cosas.

Si un día se ponen enfermos, puedes estar pendiente de ellos.

Hay padres y madres que sólo ven a sus hijos mientras cenan antes de llevarlos a dormir. Pasarnos el día entero metidos en una oficina es algo que podemos tolerar cuando no tenemos hijos, pero se vuelve una fuente de infelicidad y frustración para los que son padres.

9. Puedes trabajar desde cualquier lugar del mundo

Viajar

Literalmente. Si una semana te apetece irte a visitar a un amigo en la otra punta del mundo, lo puedes hacer sin problemas. Tus únicas limitaciones son tu portátil y una conexión a Internet.

Tengo compañeros que van cambiando de ubicación periódicamente y no hay nada que se lo impida, ni eso reduce su productividad. Las limitaciones que genera el tener que ir todos los días a un mismo sitio pueden ser complicadas, como la necesidad de alquilar o comprar un piso cerca de tu zona de trabajo.

Sin embargo, al poder trabajar desde cualquier lugar, puedes llegar a reducir muchísimo tus gastos si lo necesitas, pudiendo moverte a ciudades (o incluso países) donde el precio de la vida sea mucho menor.

10. Te acerca más a la felicidad

Felicidad

Obviamente este es un punto muy personal, pero el poder ajustar tu vida personal y profesional de tal forma que puedas disfrutar de ambas cada día me parece clave para poder sentirte realizado en todas las facetas de tu vida.


Conclusión

Como todo en la vida, trabajar desde casa tiene sus pros y sus contras, pero yo no lo cambiaría por volver a trabajar en una oficina. Me da la libertad para organizar mi vida personal, profesional y mis proyectos personales de una forma que no podría hacer si tuviera que ir cada día a un puesto de trabajo y hacer un número fijo de horas.

¿Y tú qué opinas? ¿Crees que podrías trabajar desde casa o prefieres una oficina? Y si ya lo haces, ¿qué otras ventajas o inconvenientes destacarías?

También te recomendamos

Portal del estudiante de Microsoft España, una pasada

¿Cuántos años de más te echan por tus ojos?

Encuesta Stack Overflow 2016 (III)

-
La noticia 10 cosas sobre trabajar en remoto que quizá no habías pensado y deberías tener en cuenta fue publicada originalmente en Genbeta Dev por Antonio Leiva .

Sobre la pureza de las funciones, ¿están realmente desacoplados los sistema tal como idealizamos?

$
0
0

Funciones Puras

Salvo en programas funciones sencillas, estar seguro, comprender las interrelaciones entre las partes resulta muy complicado. Idealizamos nuestros sistemas y pensamos que están desacoplados pero realmente éstos son porosos y con frecuencia los efectos fluyen entre ellos sin que nos demos cuenta... hasta que es tarde. Esta porosidad puede resultar en una interrelación no deseada (un bug) o en un enraizamiento en que el desacople ha desaparecido. Existen muchas técnicas que pretenden mantener el aislamiento pero la mayoría son patrones o guías cuyo única garantía reside en la entereza del equipo de desarrollo para seguirlas. Existen sin embargo, lenguajes que garantizan firmemente el aislamiento de las partes, con sus ventajas y sus inconvenientes.

Funciones puras, funciones impuras

Una función, o es pura, o es impura. Y es pura cuando cumple las dos siguientes condiciones:

  1. independientemente de la situación cambiante del Universo, si se le entregan los mismos valores en sus parámetros devolverá, exactamente y siempre, el mismo valor resultante.

  2. cuando es invocada, la función no produce absolutamente (e idealmente) ningún efecto en la situación del Universo.

Lo primero significa que el comportamiento de la función no depende en absoluto de cualquier valor, configuración, parametrización, estado, ... exterior a la propia función y sus parámetros explícitos de entrada.

Lo segundo significa que el único efecto detectable sobre dicha función es el valor que devuelva como resultado, la función no realizará ni interactuará en absoluto con el "exterior". La puntualización de "idealmente" ha sido añadida únicamente porque vivimos en un mundo físico en el que realizar cualquier operación (ej. 3 + 7) requiere energía, tiempo de procesamiento de alguna CPU, etc...

Una función impura podría ser:


// invoca al Universo para obtener un estado aleatorio
int aleatorio_con_paridad(int paridad) {
    return rand() & paridad;
}

Otra pura podría ser:


// obtiene el valor máximo desde una posición de memoria hasta centinela
int maximo(int *x) {
    int m = *x;
    while(*++x) if(*x > m) m = *x;
    return m;
}

¿Seguiría siendo la función pura si las posiciones de memoria involucradas cambian caprichosa y constantemente sus valores?, ¿es el puntero el argumento o es el conjunto de valores?.

Implicaciones de la pureza de una función

Obviamente existen funciones impuras muchísimo más simples y fáciles de comprender que otras puras pero, en general, en una función pura será mucho más fácil comprender las interacciones con otras partes, básicamente porque sólo con ver su firma, somos capaces de percibir todo el alcance posible de dicha función, mientras que en una función impura nunca podemos asegurar que existan relaciones ocultas.

Podría poner ejemplos sencillos como que una función pura nunca nos sorprenderá llenándonos el disco de entradas de log, que siempre será thread-safe, que puede ser memoizada, etc... sí, con sólo saber que una función es pura podemos, sin mayor información, asegurar todo lo anterior. Pero en la práctica no es tan sencillo.

Para mí las implicaciones prácticas de la pureza de una función son:

  1. en funciones "sencillas" (ej. algoritmos completos como Floyd–Warshall, clustering, ...), la seguridad total de todo lo comentado anteriormente: sin efectos, paralelizable, distribuíble, memoizable, auto-testeable, ...

  2. en funciones programas complejos, la seguridad total de que el contexto de ejecución, aunque potencialmente complejo, es conocido, pues está perfectamente acotado por la firma de la función.

Por ejemplo, si tienes un sistema de facturación, con diversos archivos de configuración, accesos a bases de datos, direcciones de servicios web, etc... podrías tener una función tarea como:


consolidarInventario :: FacturaSis Bool
consolidarInventario = ...

Aunque la pureza de nuestra función ha quedado diluida en la ingente cantidad de cosas que se puede hacer dentro de nuestra biblioteca FacturaSis, sigue siendo pura y si nosotros conocemos bien nuestro sistema FacturaSisnada de lo que haya podido codificar cualquier programador dentro de esa tarea escapa a mi conocimiento. Sí, quizás lo haya codificado mal y al fin y al cabo dicha tarea borre todos los datos ¡pero soy consciente de ello!. Podríamos perfectamente añadir una limitación como


consolidarInventario :: FacturaSis ReadOnly ConsolidaciónDeInventario
consolidarInventario = ...

Y ahora estoy seguro que ese código, haga lo que haga, no tendrá ningún efecto sobre, por ejemplo, el estado persistente.

Otros ejemplos más sencillos de cómo la pureza de una función nos permite conocer propiedades que, de ser impura no podríamos son:


miConstante :: Num a => a

Una función con la firma de miConstanteúnicamente puede generar un valor que siempre será el mismo y en la que toda la información necesaria para generarlo está codificada en el propio cuerpo. No hay ninguna otra posibilidad. Por ejemplo:


pi :: Floating a => a
pi = sqrt 12 * sum [(-3)**(-k) / (2*k+1) | k <- fromIntegral <$> [0..100]]

Otro ejemplo sencillo de cómo puede deducirse sin lugar a dudas el comportamiento de una función sólo con la firma es:


const :: a -> b -> a
const u v = ...

La función anterior no puede hacer nada con el parámetro v y tampoco tiene información de cómo construir datos del tipo a, por lo que lo único que puede hacer esa función es devolver el valor de u.

¿Cómo puede ser útil un lenguaje que sólo admita funciones puras?

Si una función es pura, significa que no puede interactuar con el mundo exterior, ¿cómo entonces las funciones puras solicitan y muestran datos a los usuarios?.

Si recuerdas el ejemplo de la función máximo anterior, ¿sigue siendo pura aunque las posiciones de memoria que accesa cambien caprichosamente?, la respuesta es que sí, de forma similar, piensa en la siguiente función pura:


teletipo :: String -> String
teletipo entrada = ... salida ...

Si nuestra función teletipo procesa toda la cadena de entrada para generar la salida, entonces no hay interacción posible con el usuario pero, ¿y si nuestra función va generando la salida a medida que va consumiendo la entrada?. En lenguajes como Python, C#, Clojure, ... podemos usar secuencias perezosas, entonces podrías pensar en la función teletipo como


teletipo :: LazyStringSequence -> LazyStringSequence
teletipo entrada = ... salida ...

En que el usuario ahora puede escribir parte de la entrada e ir leyendo la salida, cerrando el "bucle interactivo" que buscábamos ¡y teletipo sigue siendo pura!.

Funciones puras en la práctica

Las propiedades que poseen las funciones puras aportan un conocimiento y seguridad mucho mayor que si no lo fueran, además, permiten al compilador o recolector de memoria deducir comportamientos que en otros lenguajes no es posible (por ejemplo en Android, un objeto puede ser liberado de la memoria ¡cuando se espera una llamada después que realice una acción!), por contra, introducir efectos y acoplar comportamientos entre las partes se hace más difícil, seguramente porque el nivel de abstracción requerido para conseguirlo está más alejado de nuestra intuición, o quizás, porque somos perezosos y preferimos no tener las ataduras que impone una función pura y poder escribir, en cualquier lugar:


....
printf("Hello World!\n");
....

También te recomendamos

¿Cuántos años de más te echan por tus ojos?

Programación imperativa vs declarativa I

Programación funcional, un enfoque diferente a los problemas de siempre

-
La noticia Sobre la pureza de las funciones, ¿están realmente desacoplados los sistema tal como idealizamos? fue publicada originalmente en Genbeta Dev por Jose Juan .


Modelos de aprendizaje para el programador ágil ¿Cómo ser efectivo en nuestro aprendizaje constante?

$
0
0

Ne Kung Fu Download After

Cómo podemos evolucionar como profesionales en nuestro sector y cómo abordamos o gestionamos el conocimiento que podemos encontrar a nuestro alrededor, es algo que personalmente me lleva obsesionando desde hace mucho tiempo.

Con la carga habitual del trabajo, la vida personal y el resto de actividades que componen nuestro día a día, es todo un reto poder diseñar un plan de crecimiento profesional a corto, medio y largo plazo de una forma verdaderamente efectiva.

En este artículo, analizaré algunas de las prácticas con las que he experimentado en algún momento de mi carrera profesional y que en mi opinión, pueden ayudar a conseguir centrar nuestros objetivos de aprendizaje.

Motivaciones

Estamos en un sector en el que el ritmo de evolución de los entornos y tecnologías es verdaderamente difícil de seguir.

Evidentemente, estamos en un sector en el que el ritmo de evolución de los entornos y tecnologías es verdaderamente difícil de seguir. Por una parte, esto hace que poco a poco nos especialicemos de alguna forma en una serie de disciplinas en las que queremos alcanzar la maestría. Para llegar a dicha maestría, debemos completar un largo camino en el que tendremos que dedicar muchas horas de nuestro a tiempo antes de poder ser considerados de alguna forma maestros en la materia. Es en este contexto en el que estamos pensando a largo plazo.

Esta especialización tan clara nos lleva a colgarnos etiquetas que nos imponemos a nosotros mismos y que nos marcarán profesionalmente en nuestro entorno y proyectos. Por supuesto, no digo que la especialización sea mala para nada, sino que existen una serie de skills que analizaremos más adelante que añadirán valor a mi perfil profesional en el futuro con independencia del entorno o el framework que esté utilizando hoy. ¿Qué más da si ahora estoy trabajando con Android, Python o PHP? Como profesional, estos entornos no tienen porque definirme.

Y es que hay muchas teorías sobre la "zona de confort", "pensar fuera de la caja" y otras situaciones en las que se busca que el trabajo en distintas disciplinas pueda con el tiempo enriquecer nuestra área de interés personal, complementándola y haciéndonos en definitiva profesionales más completos y capaces de generar soluciones más globales.

Si crees como yo que hay que trabajar para todos y cada uno de los estadios del proceso de aprendizaje, sigue adelante y exploremos posibilidades juntos :)

Mecanismos generales de aprendizaje

conocer como funcionan estos modos de procesamiento del conocimiento por parte de nuestro cerebro nos puede ayudar a crear las condiciones necesarias para conseguir ser más efectivos en el modo de aprendizaje

En el excelente curso de Coursera "Learning how to learn", podemos aprender como funciona a nivel cognitivo el proceso de aprendizaje humano cuando afrontamos tareas ya aprendidas de nuestro día a día, en contraposición a la incorporación de nuevo conocimiento o habilidades que no poseemos.

En pocas palabras, nuestro cerebro actúa en dos modos muy distintos y nos permite de esa forma ser más efectivos en cada uno de estos escenarios. El primero es más mecánico y se activa cuando ejercitamos habilidades ya adquiridas frente al segundo que es más deductivo y que aparece cuando nos preparamos para aprender algo nuevo. Es por esto que, conocer como funcionan estos modos de procesamiento del conocimiento por parte de nuestro cerebro nos puede ayudar a crear las condiciones necesarias para conseguir ser más efectivos en el modo de aprendizaje, haciendo que nuestro cerebro esté más tiempo en su modo "aprender".

NOTA: Si te gusta la perspectiva de "aprender a aprender", quizá te interese saber que uno de los libros en los que se basa el curso es A Mind For Numbers.

9780399165245

Al margen de entender el proceso cognitivo con el fin de sacarle el máximo partido posible, otro aspecto a tener en cuenta es en qué nivel de experiencia nos encontramos ahora mismo dentro de nuestros propósitos de maestría a largo plazo. Es curioso, pero raramente esta percepción coincide con la realidad de forma exacta tal y como analiza Pragmatic Thinking and Learning.

Pragmatic Thinking And Learning 1100x1100 Imaeasdkrhaghgtj

En este libro, se explora el Dreyfus Model of Skill Acquisition, el cual define una escala de referencia en la que situarnos en función de nuestras habilidades adquiridas (en el libro se sugiere que en muchos casos la práctica deliberada nos puede llevar a la maestría en un plazo no muy inferior a las 10.000 horas de dedicación en un área determinada), dejándonos ver que en muchas ocasiones creemos ser expertos en una materia cuando no somos más que principiantes avanzados o simplemente hemos conseguido algo de competencia.

A689d31b 78fb 4d4c 8bff A198387832c11

Planificación personal

Está claro que únicamente disponemos de unas horas para dedicar al proceso semanalmente, así que es importante ser efectivo

En base a los mecanismos descritos anteriormente podemos planificar nuestro tiempo de aprendizaje a corto, medio o largo plazo.

Está claro que únicamente disponemos de unas horas para dedicar al proceso semanalmente, así que a continuación me gustaría compartir con vosotros alguna de las formas de planificarnos que más efectiva ha resultado ser en mi caso (evidentemente, no lo toméis como un dogma, ya que este tipo de técnicas pueden tener un efecto distinto según la persona o el contexto).

El principal objetivo consisten en prestar atención a qué parte de nuestro tiempo dedicamos al aprendizaje. Como a largo plazo queremos convertirnos en maestros en nuestra área y sabemos que este proceso será costoso, podemos ir sumando conocimientos poco a poco dedicando la mitad de nuestro tiempo disponible. Durante esta porción de tiempo, iremos incorporando a nuestro background capacidades que nos ayudarán a largo plazo y que no dependen del entorno o lenguaje en el que voy a trabajar: Arquitectura, Patrones, Testing, paradigmas de desarrollo como orientación a objetos, programación funcional o programación reactiva son algunos ejemplos representativos.

Al mismo tiempo, como no queremos descuidar el medio plazo, comenzaremos a adquirir conocimientos que tengan una durabilidad más baja pero que me ayuden a complementar mis habilidades principales con aspectos más técnicos pero igualmente necesarios. En este sentido podemos incluir conocimientos de base de datos, lenguajes en los que estoy centrado, herramientas para mi entorno de desarrollo ágil, nuevos protocolos, etc, dedicando una porción del tiempo más reducida que en el caso anterior y que puede estar alrededor de una tercera parte.

Por último y para satisfacer las necesidades técnicas más concretas, en el tiempo restante dedicaré mi tiempo de estudio a frameworks específicos que necesite, lenguajes nuevos o entornos de los que aún no se nada, pero de los que me gustaría tener al menos algo de criterio en el futuro. Podemos incluir incluso temas no relacionados directamente con tecnología y sí con el diseño, las artes, el UX, organización y colaboración en equipos, etc, con el fin de no renunciar al pensamiento paralelo y/o a pensar fuera de la caja.

NOTA: El reparto del tiempo disponible que hemos realizado es meramente ilustrativo y no debe ser tomada al pie de la letra, ya que en función de nuestra situación u objetivos deberemos adaptar el proceso de forma conveniente.

Gestión de materiales

Con el fin de llevar un tracking de todos los materiales que emplearemos en cada uno de nuestros escenarios de foco, es interesante trabajar con herramientas como Pocket, la cual nos permite almacenar, clasificar y etiquetar los contenidos que queremos consumir. Disponer de etiquetas como longterm, mediumterm o shortterm pueden ayudarnos en el proceso de clasificación.

En cualquier caso, sea vía Pocket o con cualquier herramienta, no viene mal tener unas reglas de adición de contenido a la misma con el fin de que no metamos contenido sin parar y luego seamos totalmente incapaces de procesarlo.

En este sentido, una manera de mantenerlo bajo control puede ser la siguiente: Encontramos un recurso interesante y antes de nada hacemos una lectura en diagonal del mismo. Si el contenido se puede procesar al instante y extraer la idea en menos de 5 minutos, lo consumimos y no lo añadimos a la pila, si en la exploración realizada vemos que es interesante pero largo, entonces ya decidimos añadirlo a Pocket y lo planificamos según el esquema de etiquetas que hayamos decido.

Esto mismo es factible en el caso de los vídeos de charlas o conferencias en los que habitualmente la decisión de ver un vídeo supone un "compromiso" de 40 minutos a 1 hora de nuestro tiempo disponible (un gran compromiso en realidad). Para evaluarlo podemos hacer un visionado en diagonal, el cual podría realizarse dando algunos saltos y visionando partes concretas o pasando parte del vídeo a una velocidad más elevada.

Mentoring

Como en nuestro aprendizaje no tenemos que estar siempre solos, hemos podido comprobar con los años cómo la aparición de la figura del mentor puede acelerar en gran medida el proceso de aprendizaje.

Dentro de Agile como disciplina general, es sorprendente lo presente que está la figura del mentor, el cual puede guiar a sus aprendices en el proceso de mejorar como desarrolladores con el fin de que puedan ganar experiencia de forma rápida y efectiva.

Lamentablemente, este modelo no está del todo extendido, por lo que tendremos que acudir a las comunidades locales de nuestro interés para buscar este tipo de figuras si en nuestro entorno habitual o laboral no están disponibles.

Proyectos como la Devscola de Valencia son un claro ejemplo de este tipo de iniciativas que se promueven dentro de la comunidad sin un coste asociado.

Captura De Pantalla 2016 02 29 A Las 10 54 50

Aprendizaje colectivo

Al margen de tener la suerte de encontrar un mentor o de cómo puedo gestionar mi tiempo como aprendiz, existe un último escenario en el que puedo seguir desarrollándome: Las actividades alrededor de las comunidades. El aprendizaje colectivo.

Katas y Coding Dojos

Las Katas son un mecanismo por el cual podemos ejercitar nuestras habilidades con el código afrontando un problema cuya complejidad permite que nos centremos en cómo hacemos las cosas en lugar de en resolver el propio problema. En este sentido, podemos aprender mucho asistiendo a los Coding Dojos que organizan algunas comunidades locales con el objetivo de practicar con una Kata establecida previamente haciendo pair-programming y TDD.

Header

Durante estos practicas deliberadas, tendremos la posibilidad de aprender nuevas técnicas programando con otros, podremos probar distintos lenguajes, distintas aproximaciones al problema o incluso distintos paradigmas de programación. Es una manera segura y divertida de aprender.

Mob Programming

Quizá estamos acostumbrados a las revisiones de código en las que mediante algún mecanismo como el "pull request", revisamos el código del resto de nuestros compañeros intentando aportar nuestro conocimiento a la hora de mejorar la calidad del mismo. Este espacio en el que entre todos razonamos acerca del código del proyecto puede potenciarse aún más si, además de revisar cada uno el código individualmente, nos reunimos todos delante de un proyector y lo hacemos juntos. A esto se denomina "Mob Programming" y si aún no lo habéis probado en vuestros equipos, os aseguro que es una de las maneras más productivas que he visto de hacer equipo, compartir una serie de criterios y maneras de ver el código y, en definitiva, de revisar y planificar el refactoring de las partes de nuestro código que lo requieran.

Mobprog

Conclusiones

La gestión del proceso de aprendizaje puede ayudarnos a cimentar nuestro futuro éxito profesional. Conocer nuestras limitaciones y habilidades es fundamental a la hora de planificarnos, así que reflexionar acerca de cómo lo hacemos o de cómo lo vamos a hacer en el futuro nos puede ayudar a optimizar nuestro tiempo, por muy limitado que sea.

¿Estás preparado para pasar al siguiente nivel?

También te recomendamos

Code-Kata. Mejorando con la práctica.

MVA Microsoft Virtual Academy, formación Online gratuita

Dime de qué color es tu batido y te diré en qué te beneficia

-
La noticia Modelos de aprendizaje para el programador ágil ¿Cómo ser efectivo en nuestro aprendizaje constante? fue publicada originalmente en Genbeta Dev por Ricardo Borillo .

Usar mónadas es mucho más fácil de lo que crees, empezando con la programación funcional

$
0
0

Crskrs9uwaaj7ci

Seguramente todos tenemos formada una buena idea sobre lo que es una "propiedad", un "método estático", un "singleton" u otros términos de uso común. Nos resultan algo más exóticos e infrecuentes términos como "clase abstracta" o "función virtual pura". Todos éstos son términos habituales en la programación orientada a objetos. Lo que seguramente ya no tengamos tan claras son todas las ramificaciones, implicaciones, interacciones que todos éstos conceptos poseen y sin embargo los usamos. Usar una mónada es tanto o más fácil de usar que, por ejemplo, un objeto. Pero una mónada no es un objeto, y quien quiera comprender cómo usar una mónada tendrá que hacer el esfuerzo por desprenderse de viejas y apoltronadas preconcepciones.

¿Qué es una mónada?

Una mónada está bien definida. Podemos usar la definición de la foto de la portada si queremos adquirir las profundas y sesudas implicaciones que las mónadas poseen (y que yo desconozco por incapacidad manifiesta) o bien podemos usar otra más útil y pragmática como la usada en diversos lenguajes de programación y en particular la de Haskell. Sin embargo, para aprender informalmente lo que es una mónada, creo que es un error tomar como base la definición de mónada, la cual sólo es útil cuando ya se está cómodo usándolas.

¿A qué huelen las mónadas?

Huelen a "contexto". Cuando estás tumbado en el sofá de tu casa, estás en un contexto. Cuando estás conduciendo, estás en un contexto. Cuando estás buceando en el mar, estás en un contexto. Así, podríamos decir que las mónadas son contextos:


dormirLaSiesta :: Sofá ()
dormirLaSiesta = ...

regresarAlFuturo :: DeLoreanDMC12 ()
regresarAlFuturo = ...

brazada :: Buceando ()
brazada = ...

Por tanto, una mónada es fácil de usar pero lo más importante es que es segura de usar porque no habría ningún problema en que te quedaras dormido en el sofá, pero sí desastroso si te da por dormirte en el coche o mientras buceas.


irAlPueblo :: DeLoreanDMC12 ()
irAlPueblo = do
                ...
                encenderMotor
                meterPrimera
                acelerar
                dormirLaSiesta        -- por fortuna no compila
                ...

No veas posibles similitudes con los objetos. Un objeto protege sus datos y define sus métodos, pero no controla quién ni cómo es usado y es difícilmente extensible (ej. mixings). Una mónada controla quién y cómo es usada, no sólo protege posibles datos, sino todo el contexto en que se ejecuta y es trivial y necesariamente extensible.

¿Para qué sirven las mónadas?

Simple y llanamente para definir una computación un proceso que se ejecuta en un contexto. El ejemplo anterior irAlPueblo es un sencillo ejemplo, pongamos ahora otro más interesante.

Supón que tenemos tres contextos situaciones completamente diferentes:

  1. una lista de números.
  2. un único número pero que quizás esté o no definido (el típico "opcional").
  3. un teletipo por el que un usuario introduce números.

Para cada situación, debemos implementar un proceso que sume 2 a los números involucrados. Es decir, el contexto con la lista de números se convertirá en un contexto con los números incrementados en dos unidades, el contexto que quizás tiene o no un número se verá incrementado o no en dos unidades y los números que el usuario introduce por el teletipo se verán incrementados en dos.


suma2_lista :: Lista Número -> Lista Número
suma2_lista lista = ...

suma2_quizás :: Quizás Número -> Quizás Número
suma2_quizás quizás = ...

suma2_teletipo :: Teletipo Número -> Teletipo Número
suma2_teletipo teletipo = ...

¿Cómo implementarías los tres procesos que te han solicitado?, ¿qué diferencias hay entre unos y otros?.

Al contrario de lo que ocurría con dormir la siesta en que una acción sí podía realizarse en un contexto pero no en otros, aquí es precisamente el mismo proceso el que puede efectuarse en cualquiera de los tres procesos pero, ¿cual es entonces el contexto sobre el que definiremos nuestro proceso?, ¿qué nombre tiene o como se define un contexto que a la vez sea una lista, un quizás y un teletipo?. Veámoslo:


suma2 :: Mónada m => m Número -> m Número
suma2 cosa_que_devuelve_números = ...

En lugar de concretar la mónada el contexto sobre el que sumaremos, decimos que "nos sirve cualquier mónada cosa que devuelva números". Ahora, las tres funciones anteriores son exactamente la nueva función suma2 y realmente no las necesitamos porque los tres procesos solicitados son:

> suma2 [1..5]
[3,4,5,6,7]> suma2 (Just 10)
Just 12> suma2 Nothing
Nothing> suma2 (putStr "Número: " >> readLn)
Número: 34
36

Procesos sobre las mónadas

Ahora ya podemos empezar a definir un poco mejor ésto de las mónadas y para ello, únicamente necesitamos introducir dos símbolos:

  1. el símbolo que, dado un contexto, me devuelve algo. Por ejemplo si estoy en el coche, quiero obtener la velocidad actual, entonces tendrá que haber una función como dameVelocidad que en algún sitio (digamos variable) me entregue esa velocidad.
  2. el símbolo con el que devuelvo el resultado de mi definición. Por ejemplo si estoy pasando la velocidad de kilómetros/hora a millas/hora, tras hacer la conversión tendré que devolver el resultado.

Veamos los símbolos con un ejemplo:


-- Ésta nos la dan de serie con el coche
velocidadEnKilómetrosHora :: DeLoreanDMC12 KilómetrosHora

-- Queremos convertir de Kilómetros a Millas
velocidadEnMillasHora :: DeLoreanDMC12 MillasHora
velocidadEnMillasHora = do
                            kmh <- velocidadEnKilómetrosHora
                            return ( kmh / 1.609344 )

Y ya está, ya sabes usar las tan complicadas y difíciles mónadas.

Tejiendo con mónadas

Creo que resultará interesante contrastar las funciones suma2 y velocidadEnKilómetrosHora e implementar ambas. ¿Porqué en suma2 aparece la mónada dos veces (como argumento de entrada y como argumento de salida) y en velocidadEnKilómetrosHora sólo de salida?.

La razón es que en suma2 tomamos algo con números y devolvemos otro algo diferente con números diferentes mientras que velocidadEnKilómetrosHora es el mismo coche el que nos devuelve la velocidad (no hay dos coches). Veamos si comparando las definiciones se ve mejor:


-- Dada cualquier mónada que devuelve números, podemos sumar 2 a cada uno de esos números
suma2 :: Mónada m => m Número -> m Número
suma2 algo_que_devuelve_números = do
                                     x <- algo_que_devuelve_números
                                     return (x + 2)

-- La velocidad está en el coche, no necesitamos ningún argumento de entrada
velocidadEnKilómetrosHora :: DeLoreanDMC12 KilómetrosHora
velocidadEnKilómetrosHora = do
                               km <- distanciaRecorridaEnLosÚltimos (5 :: Segundos)
                               return (3600 * km / 5)

¿A donde ha ido la pureza?

Alguien puede pensar que velocidadEnKilómetrosHora no es una función pura, porque aparentemente devuelve un valor sin ningún argumento de entrada. Ésto no es así.

Lo que devuelve la función velocidadEnKilómetrosHora es en realidad una función de la forma \datos_coche -> .... Como devuelve una función, no requiere ningún argumento de entrada. Quizás te resulten familiares los términos deferred o promise en que una computación se realizará cuando cierto valor esté disponible. En este caso la función velocidadEnKilómetrosHora define una computación que promete devolver la velocidad del coche cuando esté disponible. El mecanismo usado en diversas mónadas es sencillo, pero los detalles requieren sentirse cómodo usando las mónadas.

Conclusión

Obviamente no hemos introducido los ingredientes necesarios para poder trabajar con mónadas en ningún lenguaje, no es el objetivo. Pero hemos dado una aproximación sobre lo que definen y cómo se opera "dentro" de ellas. Utilizar las mónadas no es más difícil que usar otros mecanismos que nos encontramos en los lenguajes de programación, pero al sernos extraños, debemos hacer un esfuerzo por no "cerrarnos en banda" y ser pacientes a que los nuevos conceptos vayan posándose en nuestro cerebro. Sólo la práctica nos permitirá percibir y poder enjuiciar adecuadamente las ventajas e inconvenientes de cada enfoque, en este caso el uso de mónadas para definir procesos que se ejecutan en cierto contexto.

Extra

Una mónada no es una lista de cosas, no es un opcional, no es un teletipo, no es una promesa, no es algo que contenga cosas ni es aquello que puede invocarse. Si eres capaz de ver que una mónada es tan sólo la concatenación de esos procesos ("promesas") que podemos definir sobre ciertos contextos, al fin y al cabo, quizás sí comprendes que una mónada ¡tan sólo es un monoide en la categoría de endofunctores!

También te recomendamos

Programación imperativa vs declarativa I

Dime de qué color es tu batido y te diré en qué te beneficia

Programación funcional, un enfoque diferente a los problemas de siempre

-
La noticia Usar mónadas es mucho más fácil de lo que crees, empezando con la programación funcional fue publicada originalmente en Genbeta Dev por Jose Juan .

Mejora tu código Java usando Groovy

$
0
0

Logo Groovy

¿Y por qué querríamos mejorar nuestro código Java? Seguro que en más de una ocasión escribiendo Java has pensado que es muy verboso o que seguro que tiene que haber una forma más fácil y sencilla de hacer esto. En ese caso, Groovy es para ti.

Apache Groovy es un lenguaje dinámico, opcionalmente tipado, con posibilidad de tipado y compilación estáticos para la JVM. Tiene como objetivo multiplicar la productividad de los desarrolladores gracias a una sintaxis concisa, familiar y fácil de aprender. Se integra sin problemas con cualquier programa Java e inmediatamente proporciona a una aplicación poderosas características como scripting, DSLs, metaprogramación en runtime y compile-time y programación funcional.

Características más importantes

Entre las características más importantes de Groovy, destacan:

  • Tipado dinámico: Si sabemos el tipo de una variable podemos definirlo como en Java, pero en ocasiones, para variables locales de métodos el código es más legible si no lo hacemos. En ese caso usaremos la palabra reservada def como tipo.

  • Compilación estática opcional: Desde la versión 2.0 (hace más de 4 años) Groovy soporta compilación estática, es decir, el bytecode generado es muy similar al que generaría el código Java equivalente. Con esta característica Groovy puede llegar a ser tan rápido y eficiente como Java a costa de sacrificar su dinamismo, que, siendo realistas, no necesitaremos en el 90% de nuestro código.

  • Perfecta integración con Java: Desde Groovy podemos utilizar cualquier biblioteca Java existente en la actualidad sin necesidad de adaptarla ni de hacer nada especial. Simplemente añadimos la dependencia al classpath y listo, ya podemos utilizarla desde Groovy.

  • Sintaxis nativa de listas, mapas y rangos: Groovy propocina una sintaxis nativa y muy explícita para listas, mapas y rangos con la que podemos conseguir que nuestro código sea muy legible y conciso.

  • Las excepciones son unchecked: Se han escrito ríos de tinta sobre las checked exceptions de Java pero la gran mayoría de los defensores del lenguaje y Java Champions coinciden en que ha sido uno de los errores en el diseño del lenguaje. En Groovy todas son unchecked, por lo que no es necesario ensuciar de manera innecesaria la signatura de los métodos con throws que no van a ningún sitio ni tener bloques catch en blanco o con un simple System.out.println.

Diferencias con Java

Podría escribir varios artículos sobre las diferencias entre Java y Groovy, pero las más importantes son:

Uso de properties

En multitud de ocasiones definimos una clase con atributos privados y un montón de getters y setters para acceder a ellos. En Groovy no es necesario, el compilador se encarga de definirlos por nosotros.

class Persona {
    String nombre
    int edad
}

Con este código estamos definiendo la clase pública Persona y los atributos privados nombre y edad. El compilador generará los getters y setters necesarios y podremos escribir el siguiente código que llamará al setter. También podemos escribir el código entre comentarios que sería el equivalente en Java.

persona.nombre = 'Iván' // Igual que persona.setNombre('Iván')

Adicionalmente si anotamos la clase con @Canonical tendremos una implementación para equals, hashCode, toString y tendremos constructores para utilizar los atributos definidos en la clase.

Strings interpolados (GStrings)

Creo que lo mejor es verlo con un ejemplo:

println "El precio de la acción $accion a día $fecha es $valor"

Se sustituirá el valor de las variables en el string sin necesidad de ir construyendo el string con fragmentos y variables. El código queda mucho más sencillo y fácil de leer.

Además, si en lugar de una comilla ponemos tres, podremos escribir strings multilinea:

String multilinea = """Podemos escribir
    el string en
    varias líneas
"""

Listas y mapas

Es muy común manipular listas y mapas en nuestro código, por lo que una sintaxis concisa hace que el código sea mucho más legible.

def lista = [1, 2, 3, 4] // ArrayList

// O también
List<Integer> lista = [1, 2, 3, 4]
def mapa = [nombre: 'Iván', edad: 36] // HashMap
println mapa.nombre // mapa.get("nombre");
mapa.edad = 37 // mapa.put("edad", 37);

Closures vs Lambdas

Java soporta Lambdas desde la versión 8 pero en Groovy tenemos el concepto de Closures desde el principio. Aunque no se comportan exactamente igual, como regla podemos decir que podremos utilizar una closure de Groovy en cualquier código que acepte una lambda de Java.

// Java
Arrays.asList(1, 2, 3).stream()
    .map(i -> i * 2)
    .filter(i -> i > 3)
    .findFirst()
    .orElseThrow(IllegalArgumentException::new);

// Groovy
[1, 2, 3].stream()
    .map { i -> i * 2 }
    .filter { i -> i > 3 }
    .findFirst()
    .orElseThrow(IllegalArgumentException.metaClass.&invokeConstructor)

El código es prácticamente el mismo y vemos que la versión Groovy, en los métodos map y filter usamos una Closure en lugar de la Lambda.

Operador safe navigator

¿Cuántas veces hemos tenido que proteger nuestro código Java contra NullPointerExceptions. Imaginemos el siguiente código en Java:

if (order != null) {
    if (order.getCustomer() != null) {
        if (order.getCustomer().getAddress() != null) {
            System.out.println(order.getCustomer().getAddress());
        }
    }
}

Cuanto menos se puede decir que es verboso y que es fácil cometer un error y finalmente tener nuestro famoso NPE. Escribamos ese código en Groovy:

println order?.customer?.address

El operador safe navigator ?. genera prácticamente el mismo código (o bytecode) que la versión en Java. Si order es null, devolverá null. Sino, evaluará si order.customer es null y sólo en el caso de no serlo evaluará order.customer.address. El resultado de la ejecución del código anterior sólo podrá ser null o la dirección del cliente, pero nunca tendremos un NullPointerException.

Groovy dinámico

Hay ocasiones en las que el dinamismo de Groovy hace que podamos solucionar un problema de una forma muy sencilla y elegante. Imaginemos que queremos generar el siguiente JSON:

{
  "speaker": {
    "firstName": "Iván",
    "lastName": "López",
    "address": {
      "city": "Madrid",
      "country": "España",
      "zip": 12345
    },
    "conferences": [
      "SpringOne 2GX",
      "Codemotion",
      "Greach",
      "JavaCro",
      "..."
    ]
  }
}

Lo único que hay que hacer es utilizar la clase JsonBuilder y hacer una correspondencia uno a uno entre el json y el código.

import groovy.json.JsonBuilder

def builder = new JsonBuilder()
builder.
    speaker {
        firstName 'Iván'
        lastName 'López'
        address(
            city: 'Madrid',
            country: 'España',
            zip: 12345,
        )
        conferences(
            'SpringOne 2GX',
            'Codemotion',
            'Greach',
            'JavaCro',
            '...'
        )
    }

println builder.toPrettyString()

Como os podeis imaginar en la clase JsonBuilder no existe un método speaker y tampoco acepta los parámetros firstName ni lastName. Ese código se resuelve en runtime.

Closures para definir un DSL

Con Groovy podemos crear DSLs muy sencillos pero muy útiles. Imaginemos que tenemos un recurso que al utilizarlo puede lanzar una excepción y además tenemos que inicializarlo antes de usarlo y no olvidarnos de cerrarlo después de su uso. Si dejamos eso en manos del usuario de nuestra API, puede que no haga un buen uso y ocurran errores inesperados. Con Groovy podemos solucionarlo implementando el siguiente método safeResource:

def safeResource(Closure cl) {
    def resource = new ExpensiveResource()
    try {
        resource.open()
        cl(resource)
    } finally {
        resource?.close()
    }
}

// Y así lo usaríamos sin preocuparnos de inicializar o cerrar el recurso.
safeResource { ExpensiveResource er ->
    er.writeData('Hola Genbeta Dev')
}

Syntactic sugar

Groovy añade en el Groovy Development Kit: GDK una gran cantidad de métodos y clases al JDK para hacerlo más Groovy. Conociéndolos podremos escribir nuestro código de una manera más concisa e idiomática.

Un ejemplo muy claro es leer el contenido de una URL. En Java, el código necesario sería algo parecido a lo siguiente:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

public class GetURLContent {
    public static void main(String[] args) {

        try {
            URL url = new URL("http://www.google.com");
            URLConnection conn = url.openConnection();
            BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String inputLine;

            while ((inputLine = br.readLine()) != null) {
                System.out.println(inputLine);
            }

            br.close();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

¿Quereis saber cómo se escribe el código anterior en Groovy?

println 'http://www.google.com'.toURL().text

¡Y mucho más!

Me dejo muchas cosas fuera: parseo de json y xml, creación del DSLs, transformaciones AST, métodos con valores por defecto, operador elvis, power asserts (que ya vimos en el artículo sobre Spock), la Groovy truth, sintaxis nativa para expresiones regulares,... y muchos más.

Empieza sin instalar nada: Groovy web console

Has leido todo lo anterior y te apetece probar Groovy ya. La forma más rápida de probar Groovy es con la Groovy web console ya que no es necesario instalar nada, simplemente nos conectamos a esa web y podemos ejecutar de una manera sencilla y muy cómoda nuestros snippets Groovy e incluso salvarlos y compartirlos.

Instalación

Una vez que hemos decidido dar el paso e instalar Groovy, en función de nuestro sistema operativo tendremos distintas opciones. Si usamos Windows debemos descargar el instalable de la web de Groovy.

Por otro lado si utilizamos Linux o Mac, aunque también es posible descargar los binarios desde la misma web, no es la opción recomendada. En su lugar utilizaremos SDKMAN que nos permite gestionar distintas versiones de SDKs relacionados con el mundo Java: Groovy, Grails, Scala, Play, Kotlin, Spring Boot, Gradle... Y poder actualizar y cambiar de versiones de una manera sencilla y cómoda. Para instalar SDKMAN, simplemente hacemos:

$ curl -s "https://get.sdkman.io" | bash

Abrimos un nuevo terminal para que se carguen las variables de entorno correspondientes y ejecutamos:

$ sdk install groovy

Y listo, tendremos disponible la última versión de Groovy:

$ groovy -version

Ecosistema

Otro aspecto en donde brilla especialmente Groovy es en su ecosistema. Existen multitud de proyectos, herramientas y plataformas que utilizan Groovy de una manera u otra. En sucesivos artículos iremos viendo muchos de ellos con detalle pero aquí os dejo una lista: Grails, Gradle, Spock, Ratpack, SDKMAN, Geb, GPars, Griffon, Grooscript y un largo etcétera.

Conclusiones

Todo esto está muy bien, pero ¿Groovy se usa? Te sorprendería saber que hay muchas grandes empresas que utilizan Groovy entre ellas Google, Netflix o LinkedIn.

Companies Using Groovy

Groovy no es sólo un lenguaje de scripting igual que tampoco es lento. Groovy es la elección natural para cualquier desarrollador de la JVM que quiere ser más productivo desde el principio por su escasa curva de aprendizaje y su gran compatibilidad con Java.

Si te interesa conocer Groovy con más profundidad te recomiendo los siguientes libros Groovy in Action Second Edition, Making Java Groovy o Programming Groovy 2.

Además, si estás en Madrid o alrededores puedes asistir a las reuniones mensuales del Grupo de Usuarios de Groovy de Madrid en las que hay charlas de todas las tecnologías del ecosistema Groovy.

Si quieres darle un boost a tu proyecto Java, añade Groovy y lo tendrás.

También te recomendamos

Dime de qué color es tu batido y te diré en qué te beneficia

El gobierno de USA se pone del lado de Oracle en la guerra de las APIs

Tendencias de desarrollo en Android y qué mejorar de la plataforma: los ponentes de la Droidcon Spain 2015 nos dan su visión

-
La noticia Mejora tu código Java usando Groovy fue publicada originalmente en Genbeta Dev por Iván López .

Los 14 podcasts de desarrollo en español que merece la pena seguir

$
0
0

Podcast

Los podcasts están de moda. Para estos programas de radio online vía subscripción no hay género o temática que se les resista, ni siquiera algo a priori tan visual como puedan ser el desarrollo y la programación. En inglés tienes centenares de podcasts entre los que bucear (aquí realizan una selección muy apañada) pero nos vamos a centrar en podcasts de desarrollo en español que merece la pena seguir, tanto en activo como aquellos que ya no actualizan pero siguen estando disponibles para nuestro uso y disfrute. Decenas y decenas de horas de entretenimiento y sabiduría developera en el idioma de Cervantes en formato audio.

Los que están al pie del cañón

Disclaimer: he considerado que siguen en activo aquellos que han emitido algún capítulo nuevo en 2016

We.Developers

Es una pena que lleve unos meses parado porque el podcast de José Antonio Blanco es francamente interesante y desde 2011 nos ha ilustrado de diversos lenguajes de programación, frameworks, herramientas y tecnología en general. Además siempre cuenta con invitados de postín y en la web cada capitulo viene acompañado de un gran surtido de enlaces.

Web | En iTunes | RSS

Preceptos Digitales

El chileno Sebastián Barría lleva comandando desde 2014 este podcast sobre desarrollo, diseño, web, SEO, cultura digital, productividad y otros muchos temas variados. Ameno, interesante y con una periodicidad bastante apañada (36 episodios en 2 años).

Con el propio @sebastianbarria hemos hablado sobre las razones que le llevaron a iniciar un podcast sobre desarrollo: "Por qué yo soy desarrollador web y buscando podcasts en español acerca de este tema nunca encontré ninguno que fuese constante y que se tratara exclusivamente de este tema. Además tengo una empresa de desarrollo web y me ha tocado muchas veces explicarles estos mismos temas a las personas que entran a la oficina y un día decidí plasmar todo eso en un podcast para poder ayudar a los demás".

"Originalmente intenté publicar una vez a la semana pero no me alcanzó el tiempo al final y tuve que empezar a publicar con menos constancia. De todas formas intento seguir publicando siempre cada dos o tres semanas para no perder la constancia" prosigue Sebastián, que en cuanto a la temática del blog nos comenta que "Creo haber hablado acerca de todos los temas que tenía en mente originalmente, pero todavía me gustaría hablar de temas como web responsivas y profundizar en otros temas como usabilidad o accesibilidad".

Web | iTunes | RSS

Captura De Pantalla 2016 06 29 A La S 17 28 18

Hablemos de Web

Diseño, desarrollo y cultura web cada lunes y jueves (gozada de cadencia) desde México por parte de Natalia y Ángel. Distendido, agradable e interesante. Como curiosidad: es accesible y ofrece en la web las transcripciones de todos los capítulos (88 a día de hoy).

Web | iTunes | RSS

Nación Lumpen

TDD, legacy code, desarrollo móvil, papers de moda o bitcoins son algunos de los temas sobre los que han debatido en este joven podcast (apenas un año y 10 capítulos de vida). Programas bastante entretenido pero ojo a la duración, que menos de hora y media no dura ninguno. Llevan un par de meses parados, a ver si vuelven con fuerzas.

Web | Spreaker | RSS

Captura De Pantalla 2016 06 29 A La S 17 32 22

ViveCodigo

Desde México un podcast distendido con escasa periodicidad pero muy buen contenido: desde frameworks y herramientas a fondo hasta pláticas sobre productividad o la profesionalización del desarrollo. A veces se les va de madre la duración pero, como podemos comprobar en las versiones en vídeo del podcast, suelen grabar acompañados con unas cervezas y así es normal.

Web | iTunes | RSS

Código Fuente

Podcast muy instructivo y de duración ajustada por parte de Jose María Ramírez, profesor de ciclos formativos de Informática. Desde estructuras básicas a C, Python o microservicios de forma muy didáctica, con abundante bibliografía y ejercicios propuestos. Ideal para los que están empezando.

Web | iTunes | iVoox | RSS

Hecho en Laravel

Un podcast más especializado que los vistos hasta ahora (obviamente trata del framework PHP Laravel) pero bastante activo y currado por lo que resulta muy útil tanto para los profesionales de la tecnología como novatos en el framework. Además el podcast se acompaña con una serie de workshops muy interesantes.

Web | iTunes | RSS

Código Podcast

Desde Andalucía un entretenido podcast sobre desarrollo de videojuegos que lleva un par de meses parado pero que esperamos que vuelva pronto porque tiene mucha calidad. Engines, noticias, técnicas, trucos... un poco de todo en un formato muy dinámico.

Foro | iVoox | RSS

Caídos en combate

Captura De Pantalla 2016 06 29 A La S 17 39 28

Basta ya de picar

Ya hablamos en su día en Genbeta Dev de este podcast... y lamentablemente desde aquella época, 2014, no nos ofrece nuevos contenidos Sebastian Hermida. Y es una lástima porque los 20 capítulos que siguen estando disponibles son canela en rama.

Web | iTunes | RSS

javaHispano

El gran clásico de la blogosfera javera también lo fue durante mucho tiempo de los podcasts de desarrollo hasta que en 2013 lo dejaron. Eso sí, 162 programas que todavía tienes disponibles para escuchar y descargar. Conocimiento por un tubo.

Web | RSS

Podgramando

¿Y qué decir de este otro clasicazo surgido de la mente y el buen saber hacer de José M. Beas? Buenas temáticas y grandes invitados en un podcast que fue pionero y que a pesar de todos los años que han pasado (y de que tampoco es que fuera muy prolífico) sigue siendo un referente.

iVoox | RSS

Code On The Rocks

Una gran idea (developers reunidos en torno a unos copazos desvariando sobre lo humano y lo divino) que lamentablemente sólo duró 6 capítulos. Ojalá decidan tirarse de nuevo al río y volver a grabar (y beber).

Web | iTunes | Soundcloud

Podcast 4 Geeky Theory Wearables Ivoox Itunes Youtube Radio Juegos

Geeky Theory

Menos capítulos todavía (4 tan sólo) duró el podcast de Geeky Theory. Aún así les dio tiempo para hablar de temas tan dispares como wearables, productividad o la rivalidad Apple Vs. Microsoft.

Web | Youtube

32minutos.net

Otro clásico sudamericano que durante 4 años y 3 temporadas nos dejó un buen puñado de podcasts. De agile a desarrollo de apps pasando por NoSQL, TDD y lenguajes de programación variados. Una pena que desde 2013 no se haya vuelto a saber nada de ellos.

Web | iTunes | RSS

Good Morning Vietnam Robin Williams 25340627 2560 1524

Y hasta aquí nuestro recopilatorio. Quedan abiertos los comentarios para incluyáis vuestros favoritos con total libertad.

También te recomendamos

Basta Ya de Picar, podcast para programadores

Dime de qué color es tu batido y te diré en qué te beneficia

Windows Phone Controla, podcast y screencast de desarrollo en wp7

-
La noticia Los 14 podcasts de desarrollo en español que merece la pena seguir fue publicada originalmente en Genbeta Dev por Fernando Siles .

La metáfora de la “deuda técnica”

$
0
0

Marx Bros 940x615

La primera referencia al concepto “deuda técnica”, en el contexto del desarrollo software, viene del año 92 (aquí tienes el enlace a aquel primer documento en que se citó la idea). Otra evidencia más de que muchos temas y términos de moda hoy... llevaban ya muchos años con nosotros.

El creador del término fue Ward Cunningham, nombre poco popular en el sector, pero tras el que están, más allá del concepto deuda técnica, aportaciones como el desarrollo de la primera wiki, ser uno de los firmantes el manifiesto ágil, ser uno de los pioneros en introducir el concepto patrón, y los primeros catálogos, en el mundo del desarrollo software, las antiguas tarjetas CRC, contribuciones a eXtreme Programming, etc.

Cunningham introdujo el concepto de deuda técnica como eufemismo que refiere al coste e intereses que una organización tiene que pagar por hacer mal las cosas. El sobre esfuerzo a pagar para mantener un mal desarrollo software, malos diseños, malas prácticas de programación, altas complejidades ciclomáticas, etc..

Aunque el concepto, originariamente, se aplicaba a malas prácticas de programación, con el tiempo su uso se fue extendiendo a otras áreas, como la deuda técnica del Testing, la deuda de equipos, deuda de la arquitectura, etc.

Deuda técnica, esas cosas mal hechas que no se ven “desde fuera”…

Con el tiempo, muchos otros han ido perfeccionado y ampliado el concepto de deuda técnica. Por ejemplo, Fowler con sus cuatro cuadrantes de deuda técnica. O, en 2004, Joshua Kerievsky, que en Refactoring to Patterns introducía un concepto similar llamado “negligencia arquitectónica”. También Kruchten aportaba su definición, contextualizando, entre otros, en una matriz, que te dejo más abajo, a qué refiere deuda técnica. 4colours

La matriz muestra como a diferencia de los bugs o caídas de las aplicaciones, la deuda técnica refiere a esas cosas negativas que no se ven (desde fuera). Vamos, que cuando hablamos de deuda técnica hablamos de “caja blanca” frente a “caja negra”.

Otro autor destacado que se ha referido al término es Steve McConnell, con su taxonomía de deuda técnica, en la que hablaba de que cuando hay deuda técnica puede ser de dos tipos (I) Deuda incurrido involuntariamente debido a trabajos de baja calidad o (II) Deuda incurrida intencionalmente.

Los generadores de deuda técnica: desconocimiento e intentar recortar tiempos haciendo cosas mal (o saltándose tareas que había que haber hecho)

McConnell, coincidiendo con prácticamente todos los autores que ha hablado de ello, marcaba ahí las dos principales causas de que se genere la deuda técnica: desconocimiento de cómo se deben hacer las cosas y/o buscar atajos para entregar las cosas antes. El desconocimiento está claro, no saber programar con unos mínimos de calidad, no saber unos mínimos de diseño, etc. Los atajos, un clásico, frente a la presión de clientes, gerentes, usuarios, presupuestos bajos, etc., muchos gerentes fuerzan a los equipos a “saltarse” cualquier cosa que no sea tirar líneas de código.

Así, cosas como dedicar tiempo a pensar un buen diseño, las pruebas, dedicar tiempo a dejar lista la integración continua, etc., salen del proyecto, “consumen tiempo” y, a corto plazo (repito, corto plazo) a ojos de mucho, con visión cortoplacista... parecen frenar a la hora de lograr llegar a la fecha de entrega.

Deuda técnica a corto y largo plazo

El mayor peligro viene de esa deuda técnica que no se paga y va quedando ahí, de esa deuda técnica que lleva ahí años, esa por la que ya han pasado muchos veranos.

Decía Cunningham que “un poco” de deuda técnica, esa deuda técnica a corto plazo, acelera el desarrollo, siempre que se page con prontitud y no pase a ser deuda técnica a largo plazo. El mayor peligro viene de esa deuda técnica que no se paga y va quedando ahí, de esa deuda técnica que lleva ahí años, esa por la que ya han pasado muchos veranos.

Esa acumulación de deuda técnica de años es la que a día de hoy tiene frenada a un numero demasiado alto de organizaciones, que viven hoy bajo la presión de tener que ofrecer sus productos y servicios más rápido y el freno de una tecnología copada de deuda técnica de años. Y esto te lo digo por experiencia porque, porque este problema me lo encuentro día sí y día también, demasiados años haciendo las cosas mal para salir al paso y parece que ha llegado el bloqueo para muchos, que incluso intentan a la desesperada solucionarlo, intentando aplicar, por ejemplo, modelos ágiles, que se derrumban al enfrentarse a la deuda técnica.

¿Y cuanto es corto plazo en deuda técnica?

Henrik Kniberg, autor de “Scrum and XP from the trenches”, que en su experiencia las cosas mal hechas solo debería aguantar ahí unos cuantos días.

Otra popular regla es, si utilizas Scrum, “limpiar” en cada Sprint, lo que implica, ojo, dejar explícitamente tiempo para ello (hay incluso patrones de Scrum que hablan de ello, como el Teams that Finish Early Accelerate Faster).

Y, no en vano, no olvides nunca que el ciclo de vida ágil es incremental... pero también iterativo y el concepto iterativo está relacionado con ir “limpiando” en cada iteración. Mucho ojo con el riesgo de olvidarse del iterativo y quedarse solo con el incrementar.

Esa visión cortoplacista, que es como vender el alma al diablo

Hay muchas causas por las que se general deuda técnica, desconocimiento, no querer mirarlo, etc. Pero hay uno que para mi es mucho más preocupante: una visión de negocio (ya no hablo técnica) cortoplacista.

Salir al paso, entregar algo, acallar clientes, facturan antes, hacerlo lo más rápido posible aunque esté muy mal hecho, que viene a ser, tirando aún más de símiles, esta vez de terror (te dejo unas diapositivas en slideshare resumiendo el concepto deuda técnica con símiles de terror), como esas aquellas películas y novelas en las que el protagonista vende su alma al diablo para salir al paso de un problema, el diablo le salva.... pero tiempo después vendrá a por tu alma.

Y terminando con un símil económico más... estoy deseando que algún “famoso” del sector ponga de moda también la “prima de riesgo” técnica de las empresas.

También te recomendamos

Los 17 momentos por los que merece la pena ser desarrollador

Equipos dispersos: teletrabajo en un entorno ágil

La tecnología necesita más mujeres para una nueva edad de oro

-
La noticia La metáfora de la “deuda técnica” fue publicada originalmente en Genbeta Dev por Javier Garzas .

Automatizando el testing de web móviles: Appium + Nightwatch.js

$
0
0

Automatización de pruebas web móviles: Appium + Nightwatch.js

Cada vez más, el tráfico que reciben los sitios web procede de dispositivos móviles, y nuestras pruebas, como los desarrollos, deben ir cada vez más hacía el 'mobile first', es decir, nuestras pruebas web deben realizarse pensando primero en los dispositivos móviles. Según el artículo 'Internet stats & facts for 2016' de hostingfacts.com:

There are more mobile internet users than desktop internet users; 52.7% of global internet users access the internet via mobile, and 75.1% of U.S. internet users access the internet via mobile

A esto debemos unir que en los entornos encaminados hacía el 'continuous delivery' en los que trabajamos, no tiene sentido que estas pruebas sean manuales. Si queremos ser eficientes, y rápidos en la entrega de valor, debemos tener baterías de pruebas automáticas, que se ejecuten en una cierta variedad de dispositivos, y que nos permitan asegurar que nuestros sitios web cumplen con el nivel de calidad que hemos decidido.

Vale, me has convencido pero... ¿cómo automatizo mis pruebas web en móviles?

Una opción interesante es utilizar la siguiente combinación de herramientas: Appium + Nightwatch.js. A estas tendríamos que añadir una opción como Jenkins o Bamboo, que se encargue, por ejemplo, de lanzar las pruebas de forma automática cada vez que se suban cambios al repositorio.

Appium

Appium es el estándar en automatización de pruebas para móviles. Se trata de un framework open source que permite probar aplicaciones nativas, híbridas o, como en nuestro caso, aplicaciones web. Se dice de appium que 'es como selenium, pero para aplicaciones móviles'.

Appium se va a encargar de ejecutar las pruebas en el dispositivo móvil. Tiene varias características que lo hacen interesante:

  1. Nos vale tanto para dispositivos Android como para iOS.
  2. Podemos escribir los tests en el lenguaje que más nos guste: Java, Objective-C, JavaScript con Node.js, PHP, Python, Ruby, C#, Clojure, o Perl, en todos los casos usando el API de Selenium WebDriver.
  3. Tiene un grado de madurez alto, y apunta a ser el estándar para pruebas en dispositivos móviles de los próximos años.

Nightwatch.js

Nightwatch.js es un framework para pruebas web automáticas. Lo habitual es utilizarlo para lanzar las pruebas en dispositivos 'no móviles', ya que nightwatch.js ejecuta llamadas contra un servidor de selenium usando el protocolo JsonWireProtocol. En este caso vamos a combinarlo con appium, lo que nos va a permitir hacer pruebas web automáticas en tablets y móviles.

Instalando las herramientas

Los requisitos previos son tener instalado Node.js (incluido npm), y Java. Para verificar que efectivamente cumplimos estos requisitos, abrimos una ventana de línea de comandos (terminal en linux y mac) y verificamos las versiones instaladas de node.js y java.

Para saber la versión de node.js (recomendado tener al menos la v4.4.7):


node -v 

Para la versión de java (recomendado tener a partir de la v1.8.0):


java -version
Versionnode Java Primero confirmamos nuestra versión de Node y Java

Una vez confirmado que tenemos node.js instalado con una versión actual, tanto appium como nightwatch.js pueden ser instalados directamente desde su gestor de paquetes (npm). Desde línea de comandos ejecutamos los siguientes comandos para instalar las herramientas globalmente (anteponiendo 'sudo' , o haciendo 'su' antes en equipos linux):


npm install -g appium

De esta forma instalamos appium. Cuando finalice el proceso instalaremos nightwatch:


npm install -g nightwatch

En los siguientes enlaces tenéis más información sobre la instalación y primeras pruebas con nightwatch.js en Windows y tambien instalación y primeras pruebas con nightwatch.js en Mac OS.

Además de estas herramientas, necesitaremos alguna herramientas específicas para poder conectarnos a cada tipo de dispositivo, android o iOS. En el caso de android, necesitaremos tener instalado como mínimo el adb Universal Windows ADB Driver y el sdk de android, para lo que es recomendable instalar android studio. En iOS el mayor requisito es que necesitamos ejecutar las pruebas desde un MAC.

Creando el proyecto

Lo primero que vamos a hacer es crearnos una estructura de carpetas que posteriormente nos va a facilitar la labor de administrar nuestro proyecto de pruebas automáticas.

En la ruta que queramos de nuestro sistema vamos a crear una carpeta a la que nosotros hemos llamado nightwatch. Dentro de esta carpeta vamos a crear dos carpetas más. La primera será 'config' y la segunda 'src'. En 'config' tendremos el fichero con la configuración del proyecto, y en la carpeta 'src' estarán los ficheros con el código de las pruebas, por lo que crearemos una carpeta aquí llamada tests.

Creación y estructura de carpetas

En la carpeta config vamos a crear un nuevo archivo con el nombre 'nightwatch.json' (es necesario que podamos ver las extensiones de nuestros archivos). Cuando nos pregunte que si estamos seguros, le decimos que si. Posteriormente, abrimos este archivo con algún editor de código fuente como sublime text (importantísimo que no nos introduzca caracteres extraños):


{
    "src_folders": ["./src/tests"],
    "output_folder": "./logs/",
    "selenium": {
        "start_process": false,
        "log_path": "./logs/"
    },
    "test_settings": {
        "default": {
            "launch_url": "http://localhost/",
            "selenium_host": "127.0.0.1",
            "selenium_port": 4444,
            "silent": true,
            "screenshots": {
                "enabled": true,
                "on_failure": true,
                "on_error": true,
                "path": "./screenshots/errors/"
            },
            "desiredCapabilities": {
                "browserName": "firefox",
                "javascriptEnabled": true,
                "acceptSslCerts": true
            }
        },
        "iphone": {
            "launch_url": "http://www.google.com",
            "selenium_port": 4723,
            "selenium_host": "localhost",
            "silent": true,
            "screenshots": {
                "enabled": false,
                "path": ""
            },
            "desiredCapabilities": {
                "browserName": "iphone",
                "platformName": "iOS",
                "deviceName": "iPhone Simulator",
                "version": "7.1",
                "app": "PATH TO YOUR IPHONE EMULATOR APP",
                "javascriptEnabled": true,
                "acceptSslCerts": true
            }
        },
        "android": {
            "launch_url": "http://www.google.com/",
            "selenium_port": 4723,
            "selenium_host": "localhost",
            "silent": true,
            "screenshots": {
                "enabled": false,
                "path": ""
            },
            "desiredCapabilities": {
                "browserName": "chrome",
                "platformName": "ANDROID",
                "deviceName": "CB51249FHF",
                "version": "",
                "javascriptEnabled": true,
                "acceptSslCerts": true
            }
        }
    }
}

Escribiendo nuestro primer test

Ahora vamos a crear nuestro primer test. Vamos a la carpeta src/tests y dentro de esta creamos un nuevo archivo al que llamaremos ejemplo1.js. Después lo abrimos con el editor de código y escribimos lo siguiente:


module.exports = {
 "Demo test Google" : function (browser) {
   browser
     .url("http://www.google.com")
     .waitForElementVisible('body', 1000)
     .setValue('input[type=search]', 'genbetadev.com')
     .waitForElementVisible('button[name=btnG]', 1000)
     .click('button[name=btnG]')
     .pause(1000)
     .assert.containsText('#main', 'genbeta')
     .end();
   }
};

En la siguiente imagen podéis ver el "proyecto completo". A la izquierda del todo podéis ver la estructura de carpetas, en el centro el archivo de configuración de nightwatch.js, y a la derecha el archivo con el test en si.

Proyecto en Atom Como se ve nuestro proyecto en el editor Atom

Ejecutando la prueba

Para lanzar nuestra prueba lo primero que necesitamos es arrancar appium. Vamos a una ventana de línea de comandos, escribimos 'appium' y le damos a intro. Si lo hemos instalado globalmente como indicamos, veremos que la consola nos muestra algo similar a esto:

El servidor de Appium nada más arrancar El servidor de Appium nada más arrancar

Después abrimos otra ventana de línea de comandos, desde la que vamos a ejecutar el runner de nightwatch.js. Vamos hasta la ruta de nuestra carpeta nightwatch, y ejecutamos lo siguiente:


nightwatch -c config/nightwatch.json -e android

Nightwatch es la orden para lanzar los tests. Con -c le especificamos la ruta del archivo (config/nightwatch.json) de configuración que deseamos que utilice y con -e le indicamos el entorno con el que queremos ejecutar las pruebas (android).

Si todo va bien en la ventana de línea de comandos iremos viendo como se ejecutan los pasos, en el móvil veremos como se abre chrome y ejecuta la navegación indicada, y en appium veremos todo lo que va haciendoen cada momento.

Ejemplo de Appium + Nightwatch.js A la izquierda el runner de nightwatch.js, en el centro el navegador chrome ejecutándose en un móvil android, y a la derecha el servidor de appium

En nuestro caso, hemos instalado una herramienta -Vysor- que nos permite acceder desde el ordenador al móvil android, y confirmar que todo se ejecuta correctamente.

Siguientes pasos

Una vez que tenemos automatizado nuestra primera prueba, lo siguiente que tendríamos que hacer es seguir creciendo en pruebas, hasta tener una batería de pruebas mínima que podamos ejecutar automáticamente desde jenkins (por ejemplo) con la periodicidad que queramos, y que permita asegurar que nuevo código no rompa nuestro sitio web.

También te recomendamos

La tecnología necesita más mujeres para una nueva edad de oro

Desarrollo en Android y IOS con F#

Mi experiencia en la BilboStack

-
La noticia Automatizando el testing de web móviles: Appium + Nightwatch.js fue publicada originalmente en Genbeta Dev por Raúl Hernández .

To throw or not to throw o para que sirven las excepciones

$
0
0

Ttontt

En el mundo impuro en el que vivimos se producen situaciones inesperadas que escapan a nuestro control. Es por ello que los programas necesitan un mecanismo mediante el cual poder controlar dichos casos excepcionales, al más común de esos mecanismos se le llama Exception handling. Sin embargo, el uso de excepciones tiene consecuencias en la calidad de nuestro código haciéndolo más frágil. ¿Podemos hacer algo al respecto?

Acción fantasmal a distancia

El principal problema con las excepciones es que realizan una acción fantasmal a distancia esto es, una situación excepcional ocurrida en cierto proceso inmerso en cierto contexto eleva esa situación sin concierto previo de ello a todos los procesos superiores en sus contextos superiores. Por ejemplo, tu tienes cierto código cuyo proceso consiste en sumar los importes de unas facturas y algún proceso profundo eleva una excepción cuando los datos de una factura están corruptos ¿que haces?, ¿dejas que la excepción se eleve e impides que los usuarios trabajen hasta que todas las facturas en liza se "arreglen"? no, seguramente con la idea de descartar las que "estén mal" intentarías capturar dicha excepción en el cuerpo que itera las facturas pero ésto, por desgracia, sólo agrava el problema que nos ocupa (aunque quizás tu aplicación funciona bien unos meses o incluso años si tienes suerte y no te piden modificárla jamás).

La cuestión es, que las excepciones suponen una interrelación tácita entre procesos en sus propios contextos, por lo que es difícil razonar y ser consciente de las implicaciones cuando ocurren.

El uso de excepciones hoy en día

Es completamente utópico pensar que vamos a poder establecer un marco que sustituya las excepciones fantasmales sin embargo, descontextualizaré torticeramente el artículo de Eric Lippert sobre Vexing exceptions para mostrar que el marco actual es notablemente mejorable. Él argumenta que no es posible actuar controladamente (sin usar excepciones) frente a, por ejemplo, el acceso a un fichero, dado que por muchas verificaciones que realices antes (existe, es de cierto tamaño, tienes permisos, ...) siempre puede ocurrir algo que rompa tu proceso de lectura. Es obvio que algo puede romper el proceso de lectura ¡pero no hay porqué andar lanzando excepciones a diestro y siniestro! la operación de lectura que eleva una excepción si ya no puede leer el fichero ¡está asumiendo que siempre podrá leer el fichero abierto! y eso, para nosotros, es mucho suponer (o no, y en tal caso no nos tendríamos que preocupar porque tal excepción se eleve).

Mi opinión es que cuando lanzamos una excepción, debemos asumir que el proceso entero que depende (directa o indirectamente) del que elevó la excepción se ha roto también y sólo es recuperable cuando no existe tal dependencia. Por ejemplo, el correcto funcionamiento del sistema operativo no depende del éxito o fracaso de la ejecución de mi programa (¿o sí?: isolation, containers, ...), luego si yo elevo una excepción él puede capturarla y decir, simplemente "abnormal program termination".

Otro ejemplo de uso "legítimo" podría ser la digestión de mensajes, nuestro worker debe seguir digiriendo mensajes aunque el proceso de uno de ellos falle estrepitosamente (ej. un bug que provoca NullPointerException) ¡pero sólo si el proceso entre mensajes es independiente!

Por supuesto, las excepciones son fantásticas para mantener de forma cómoda las aserciones en nuestro código y nos permiten validar importantes invariantes que, de no cumplirse, nos revelarán un bug.

Excepciones y recursos

Si el problema de la ruptura del proceso, no obtener el resultado esperado y que la acción fantasmal nos impide percibir adecuadamente las interrelaciones en nuestro código no te parecen pocos problemas, el hecho de lanzar una excepción obliga a todos los procesos intermedios a liberar todos los recursos que hubieran acaparado. Por fortuna en este caso, las interrelaciones suelen estar más claras, pues el contexto dentro de un } finally { normalmente estará bien definido.

La acumulación de ficheros temporales, un bloqueo sobre un fichero no liberado, la corrupción del estado persistente y otros similares son síntomas de que el programa falló sin una adecuada liberación de recursos. Este tipo de errores los vemos con frecuencia en el software que utilizamos.

Alternativa a throw

Strf

Hemos visto casos en los que las excepciones son un útil mecanismo. Huelga decir que el "uso creativo" de las excepciones como la famosa alternativa a la validación anidada estaría desaconsejada en general. Pero entonces ¿que alternativas tenemos para gestionar lo excepcional entre nuestros procesos interrelacionados?.

De las que yo conozco la que a mí me parece mejor resuelve el problema es la applicative style programming (o applicative functors) pues de una forma elegante permite mantener simultáneamente, cual programación orientada a aspectos se tratara, la ortogonalidad dualidad que nuestros procesos mantienen entre las acciones requeridas y las acciones excepcionales.

Pero eso mejor, otro día.

También te recomendamos

El verdadero coste de los bloques try/catch

Patrones de diseño: Adapter

¡Concurso! Tus momentos WTF tienen premio: un Xiaomi MI5 o uno de los 25 WTF Smart Sticker pueden ser tuyos

-
La noticia To throw or not to throw o para que sirven las excepciones fue publicada originalmente en Genbeta Dev por Jose Juan .


Por qué prefiero trabajar en una factoría de software en vez de en una Startup

$
0
0

Software Lab

En el mundo de la programación (al menos en España), las factorías de software tienen la imagen de ser uno de los peores lugares para desarrollarnos como profesionales.

Suele estar extendida la idea de que las denominadas "cárnicas" y, aún peor, las factorías de software que han ido creando durante los últimos años para delegar la implementación de los proyectos, sólo se preocupan por finalizar los proyectos de la forma más rápida posible, sin ningún tipo de calidad, y que a sus trabajadores los explotan por cuatro duros. Yo mismo he escrito sobre el tema anteriormente.

Es por eso que en Genbeta Dev queríamos escuchar la voz de personas que trabajan en ella y disfrutan de su trabajo día a día. Me puse en contacto con tres grandes profesionales que trabajan en las factorías de software de Indra, y esto es lo que me han contado.

Chema Perez

José María Pérez Ramos

El crecimiento dentro de una empresa, sea una factoría o una StartUp, va ligado a la persona. Cuanto más profesional seas en tu trabajo, más respeto se tendrá a lo que haces.

Cuéntanos un poco sobre ti ¿Cuánto tiempo llevas trabajando en una factoría de software y qué tipo de trabajo realizas?

Hace poco más de tres años dejé una StartUp para incorporarme al departamento de movilidad de la Software Labs de Salamanca. El motivo del cambio fue porque la factoría me iba a permitir a dedicarme en exclusiva al desarrollo de aplicaciones móviles que es lo que estaba buscando.

Desde el día uno hasta hoy, me he dedicado al 100% a desarrollar aplicaciones móviles.

¿Qué tipo de proyectos realizas? ¿Trabajas en uno o varios proyectos?

En la factoría desarrollamos aplicaciones móviles para iOS y Android. En mi caso, me dedico preferentemente a desarrollar para Android.

Aquí desarrollamos todo tipo de aplicaciones: banca, elecciones, control de dispositivos inalámbricos, gestión de tiendas de ropa, inspecciones de edificios, etc.

Esta variedad nos permite enfrentarnos a problemas nuevos en cada proyecto y coger experiencia en un ámbito mayor a cuando se trabaja en un único proyecto. Lo habitual es que sólo trabajemos en un único proyecto.

¿Que ventajas le ves a trabajar en una factoría de software sobre otro tipo de alternativas?

La principal ventaja que veo es que en una factoría cada proyecto es diferente al anterior. Suelen ser proyectos entre seis meses y un año por lo que no caes en la monotonía de trabajar en un único proyecto.

Además, que al ser proyectos completamente diferentes, constantemente estas aprendiendo cosas nuevas. Cuando trabajas en un único proyecto, tu aprendizaje gira en torno a la solución de ese proyecto.

Rompe algún mito ¿Qué cosas se suelen oír sobre las factorías de software que no son verdad en tu día a día?

En la factoría puedes perfectamente desarrollar tu carrera profesional como desarrollador al igual que lo hace el que toma el camino de la gestión

El mito que más oigo y que me gustaría romper, es que las factorías tienen famas de ser 'zulos donde se pica código sin sentido'. Los programadores tenemos gran parte de culpa del trabajo que se realiza día a día.

El crecimiento dentro de una empresa, sea una factoría o una StartUp, va ligado a la persona, cuanto más profesional seas en tu trabajo más respeto se tendrá a lo que haces. Si no respetas tu trabajo, no lo harán por ti, estés donde estés.

Y esa es nuestra filosofía. Para conseguirlo, hacemos formación interna donde estudiamos buenas prácticas, patrones de diseño, arquitectura clean, testing, etc. que luego aplicamos a nuestros proyectos. También acudimos a eventos nacionales como Droidcon o Codemotion, y participamos en eventos locales como Betabeers o Meetups. Todo esto para conseguir que nuestro código mejore día a día.

Otro mito que escucho mucho, es que para seguir creciendo dentro de la empresa tienes que dejar la programación y enfocar tu carrera interna hacía la consultoría. A mi me gusta programar y tengo claro que es a lo que me quiero dedicar.

En la factoría puedes perfectamente desarrollar tu carrera profesional como desarrollador al igual que lo hace el que toma el camino de la gestión. Son dos caminos paralelos pero con las mismas compensaciones.

Carlos Martin

Carlos Martín Acera

Trabajar en proyectos más grandes me ha permitido asentar y expandir mis conocimientos.

Cuéntanos un poco sobre ti ¿Cuánto tiempo llevas trabajando en una factoría de software y qué tipo de trabajo realizas?

Actualmente llevo 9 meses trabajando en este puesto como desarrollador iOS, y mi labor es analizar las diferentes funcionalidades que la app requiere junto con el resto del equipo y programar la solución con todo lo que ello conlleva: arquitectura, tests...

¿Qué tipo de proyectos realizas? ¿Trabajas en uno o varios proyectos?

En este tiempo he participado en dos proyectos. El primero en colaboración con otra factoría de software de la misma empresa y ahora en uno que se gestiona totalmente en la que yo estoy.

Ambos son proyectos para empresas multinacionales, de gran alcance en cuanto a desarrollo se refiere.

¿Que ventajas le ves a trabajar en una factoría de software sobre otro tipo de alternativas?

Para mí, la primera ventaja que vi en el momento que me incorporé, fue tener estabilidad laboral. Venía de trabajar en una empresa pequeña que por la crisis tuvo que cerrar y después estuve como freelance. Durante ese tiempo había muchos altibajos y era algo que no me gustaba.

Ahora con el tiempo que ha pasado, veo ventajas más importantes como por ejemplo trabajar en proyectos más grandes que me han permitido asentar y expandir mis conocimientos y formar parte de un equipo con diferentes perfiles con los que poder aprender y compartir experiencias.

Rompe algún mito ¿Qué cosas se suelen oír sobre las factorías de software que no son verdad en tu día a día?

Pues siguiendo el hilo de la estabilidad laboral, veo que la gran mayoría de los compañeros siempre tienen algún proyecto en el que trabajar, y concretamente en mi caso pasé de uno a otro en cuestión de días. Nada de estar sin proyecto asignado como se puede escuchar alguna vez.

Alejandro Sanchez

Alejandro Sánchez Yuste

La diversidad de clientes nos hace tener una visión más amplia del mercado

Cuéntanos un poco sobre ti ¿Cuánto tiempo llevas trabajando en la factoría de software y qué tipo de trabajo realizas?

Llevo trabajando en la misma Software Lab desde abril de 2013 (3 años y unos pocos meses). Junto con otros tres compañeros formamos el departamento de movilidad en el cual soy desarrollador Android. En la actualidad somos casi 30 personas dedicadas a las tecnologías móviles.

¿Qué tipo de proyectos realizas? ¿Trabajas en uno o varios proyectos?

En el departamento trabajamos con todo tipo de clientes: bancarios, telecomunicaciones, administraciones públicas, e incluso proyectos internos. La línea de trabajo individual es estar en un único proyecto al mismo tiempo para que la dedicación a este sea completa.

¿Que ventajas le ves a trabajar en una factoría de software sobre otro tipo de alternativas?

La diversidad de clientes nos hace tener una visión más amplia del mercado. No nos enfocamos en un solo producto. La posibilidad de ver los sistemas a los que tenemos que conectarnos (y las dificultades que eso conlleva) hace que aprendamos día a día.

Solemos ir a eventos como Droidcon, Codemotion, UXSpain, para poder aprender de la comunidad y no solo por nuestra cuenta.

Por ejemplo: trabajar con un cliente en el que solo puedes probar sus servicios desde una red privada o trabajar con servicios REST y en el proyecto siguiente con servicios SOAP, hace que nuestro aprendizaje sea casi obligatorio.

Por otra parte, al trabajar en diferentes proyectos podemos hacer tareas más diferentes que las habituales. Por ejemplo integración con impresoras térmicas, lectura de códigos QR invertidos, integración con routers, o llamadas VoIP.

Rompe algún mito ¿Qué cosas se suelen oír sobre las factorías de software que no son verdad en tu día a día?

Una de las cosas que se suelen oír es que no puedes tener una carrera como desarrollador no pudiendo avanzar si no es subiendo a consultor, dejando el desarrollo (que es lo que nos gusta). En las factorías existen los perfiles "Experto" en los que los que puedes desarrollar tu carrera como tu prefieras.

Por último, querría desmentir el mito "En las factorías se pica código sin pensar". Solemos ir a eventos como Droidcon, Codemotion, UXSpain, para poder aprender de la comunidad y no solo por nuestra cuenta.

En los proyectos en los que estamos hacemos las cosas como tienen que hacerse y no solo en sacar el producto. Aplicamos buenas prácticas, arquitecturas clean, herramientas de medición de calidad del código, integración continua que nos permiten ser mejores profesionales.

En resumen

Tras leer los comentarios de los tres entrevistados, se observan puntos comunes en todos ellos:

  • Especialización: se puede desarrollar perfectamente una carrera profesional como desarrollador sin necesidad de acabar realizando tareas de gestión.
  • Formación: están en constante aprendizaje realizando formaciones internas y asistiendo a eventos para conocer las tendencias y conocer otros profesionales con los que intercambiar conocimientos.
  • Profesionalización: todos coinciden en que no se limitan exclusivamente a hacer su trabajo, sino que se preocupan por hacerlo bien.
  • Variedad: al participar en distintos proyectos con problemáticas muy diferentes, el abanico de conocimientos se expande.

¿Y tú qué opinas de las factorías de software? ¿Has trabajado en alguna de ellas? Cuéntanoslo en la sección de comentarios.

También te recomendamos

¡Concurso! Tus momentos WTF tienen premio: un Xiaomi MI5 o uno de los 25 WTF Smart Sticker pueden ser tuyos

Fabric, la suite para desarrollo de apps móviles de Twitter

Desarrollo en Android y IOS con F#

-
La noticia Por qué prefiero trabajar en una factoría de software en vez de en una Startup fue publicada originalmente en Genbeta Dev por Antonio Leiva .

SDKMAN!: Un gestor de SDKs para dominarlos a todos

$
0
0

Logo

¿Trabajas en entornos de la JVM y a menudo tienes que cambiar de versión de los distintos SDKs? ¿Programas en Ceylon, Groovy, Kotlin o Scala?, ¿generas tus builds con Ant, Maven, Gradle o SBT?, ¿eres de Spring Boot, Grails o Vert.x? Entonces SDKMAN! es para ti.

SDKMAN! es una herramienta para manejar múltiples versiones de distintos SDKs en sistemas Unix (aunque también existe una versión alternativa para Windows). Proporciona una interfaz de línea de comandos y un API para instalar, cambiar, eliminar y mostrar la lista de candidatos. Anteriormente se conocía como GVM: Groovy enVironment Manager porque sólo se centraba en herramientas relacionadas con el ecosistema Groovy pero desde hace más de un año sirve para instalar más herramientas, SDKs y lenguajes de la JVM.

En este artículo veremos cómo instalarlo, utilizarlo y sacarle partido y además hablaremos con Marco Vermeulen, su creador, que amablemente nos ha respondido unas preguntas sobre SDKMAN!

Instalando SDKMAN!

La instalación es muy rápida y sencilla, abrimos un terminal y ejecutamos:

$ curl -s "https://get.sdkman.io" | bash

Y a continuación, tal y como indica al terminar la instalación podemos abrir un nuevo terminal para que se carguen las variables de entorno necesarias y esté todo disponible.

Empezamos: Listando los candidatos

Probablemente lo primero que queramos hacer una vez instalado sea ver la lista de todo lo que podemos gestionar.

$ sdk list

Este comando muestra los veinticuatro toolkits, frameworks, lenguajes y herramientas que actualmente se pueden gestionar a través de SDKMAN!

El siguiente paso es decir cual queremos instalar y ver las versiones disponibles. Utilizaremos Groovy:

$ sdk list groovy
================================================================================
Available Groovy Versions
================================================================================
     2.4.7                2.3.2                2.1.2                1.8.6
     2.4.6                2.3.11               2.1.1                1.8.5
     2.4.5                2.3.10               2.1.0                1.8.4
     2.4.4                2.3.1                2.0.8                1.8.3
     2.4.3                2.3.0                2.0.7                1.8.2
     2.4.2                2.2.2                2.0.6                1.8.1
     2.4.1                2.2.1                2.0.5                1.8.0
     2.4.0                2.2.0                2.0.4                1.7.9
     2.3.9                2.1.9                2.0.3                1.7.8
     2.3.8                2.1.8                2.0.2                1.7.7
     2.3.7                2.1.7                2.0.1                1.7.6
     2.3.6                2.1.6                2.0.0                1.7.5
     2.3.5                2.1.5                1.8.9                1.7.4
     2.3.4                2.1.4                1.8.8                1.7.3
     2.3.3                2.1.3                1.8.7                1.7.2

================================================================================
+ - local version
* - installed
> - currently in use
================================================================================

Para instalar la última versión disponible sólo es necesario ejecutar:

$ sdk install groovy

Y listo, ya podemos usar Groovy.

$ groovy -version
Groovy Version: 2.4.7 JVM: 1.8.0_91 Vendor: Oracle Corporation OS: Linux

Gestionando distintas versiones

La verdadera ventaja de SDKMAN! es cuando tenemos que trabajar con distintas versiones y tenemos que cambiar entre ellas.

Partiendo del ejemplo anterior, imaginemos ahora que queremos cambiar a una versión más antigua de Groovy.

$ sdk install groovy 2.4.1

# Cambiamos a esta versión de Groovy
$ sdk use groovy 2.4.1
Using groovy version 2.4.1 in this shell.

$ groovy -version
Groovy Version: 2.4.1 JVM: 1.8.0_91 Vendor: Oracle Corporation OS: Linux

Y así de sencillo, no tenemos que preocuparnos de nada más. No es necesario ir a la web y buscar en enlace de descarga de la versión anterior. Descargarla, descomprimirla, cambiar el classpath para utilizar ésta en lugar de la anterior,... Nada, simplemente instalarla y comenzar a utilizarla.

¿Qué puedo instalar y gestionar con SDKMAN!

Como comentamos al principio del artículo SDKMAN! permite gestionar, instalar y utilizar más de veinte toolkits, frameworks, herramientas y lenguajes:

  • Lenguajes: Ceylon, Groovy, Kotlin y Scala.
  • Herramientas de Build: Ant, Gradle, JBoss Forge, Kobalt, Maven y SBT.
  • Documentación: AsciidoctorJ y Gaiden.
  • Frameworks y tookits de desarrollo: Activator, Grails, Glide, Griffon, SpringBoot y Vert.x.
  • Varios: CRaSH, GroovyServ, JBake, JBakery, Lazybones y Sshoogr.

Involucrando a la comunidad

Probablemente estás pensando que todo esto está muy bien pero seguro que te haces la siguiente pregunta ¿y cuánto tarda en actualizarse SDKMAN! con la nueva versión de Grails, Groovy, SpringBoot o Kotlin? La respuesta es muy sencilla: Nada, es instantáneo. Esta es una de las razones por las que SDKMAN! se ha convertido en el estándar de facto para la gestión de las distintas versiones. ¿Y cómo es eso posible? Marco ha creado un API para que los distintos vendors puedan notificar automáticamente a SDKMAN! de las nuevas releases.

Si nos fijamos en la hora de los tweets vemos que ambos son de las 17:40 del día 4 de Julio. En el mismo momento que el equipo de Pivotal publica y anuncia la nueva release de Spring Boot notifica a SDKMAN! para que haga lo propio. A partir de ese momento, la nueva versión de SpringBoot está lista para su descarga desde SDKMAN!

Springboot 1 3 6Springboot 1 3 6 Sdkman

Incluso ocurren situaciones curiosas como que la nueva versión de Grails es anunciada dos horas antes en SDKMAN! que por el equipo de Grails.

Grails 3 1 9 SdkmanGrails 3 1 9

Bonus track: Entrevista con su creador, Marco Vermeulen

Marco Vermeulen

Me encanta desarrollar y contribuir al open source. Es una forma de devolver algo a las comunidades de las que recibimos tanto cada día.

Como parte final a este artículo hemos aprovechado para hacerle unas cuantas preguntas a Marco que amablemente nos ha contestado:

¿Por qué y cómo decidiste desarrollar SDKMAN!?

El proyecto nació debido a la frustración de tener que trabajar con SDKs en mi entorno de desarrollo local. Por aquel entonces estaba trabajando mucho con Grails y, cuando desarrollaba plugins tenía que cambiar continuamente de versión de Grails para probar la compatibilidad. Decidí que tenía que haber una manera más fácil así que me embarqué en construir un SDK manager.

Decidí escribir la aplicación siguiendo totalmente BDD así que empecé escribiendo un montón de especificaciones que subí a github para que la comunidad me diera feedback. Cuando todos estuvimos contentos con las especificaciones empecé a desarrollar las funcionalidades.

¿Puedes explicar el stack tecnológico de SDKMAN!? La arquitectura, lenguajes de programación utilizados, frameworks, toolkits,...

El stack tecnológico es diverso y al final he terminando utilizando la tecnología adecuada según las necesidades. Básicamente se trata de una aplicación cliente/servidor aunque no en la manera tradicional. El cliente es una interfaz de línea de comando (CLI) y necesita funcionar en cualquier plataforma, así que elegí Bash. No sólo está disponible en cualquier sistema Unix sino que el tiempo de arranque es instantáneo. El cliente Bash utiliza curl, zip awk y sed como dependencias y éstas se encuentran disponibles en cualquier plataforma.

La parte servidora tiene una arquitectura de microservicios. Aquí tomé la decisión pragmática de exponer los endpoints del API como REST CSV en lugar de utilizar JSON. Esto es así porque un CSV es muy fácil de manejar con bash.

El API que sirve las peticiones del CLI consiste básicamente en tres servicios: Candidates, Broadcast y Download Broker. Están escritos con diferentes tecnologías y lenguajes (Vert.x, Spring Boot y Ratpack, utilizando Groovy y Java como lenguajes). La persistencia está en MongoDB.

Además de esto tenemos unas APIs de vendors que utilizan los distintos equipos tecnológicos para publicar sus versiones en SDKMAN. También estan escritas en una variedad de tecnologías como Spring Boot, Play, Scala y Groovy.

¿Cómo se testea todo?

El CLI y todos los componentes del servidor tiene una suite de tests de Cucumber con definiciones escritas en Groovy. También usamos Spock y Scalatest para los test unitarios. Todo está escrito desde una estricta aproximación test-first.

¿Dónde está alojado?

Todos los servicios se construyen cuando se hace push a Github utilizando Travis CI. Cada build produce una imagen de Docker que finalmente se publica en Docker Hub. El deploy se hace utilizando Docker Compose en Digital Ocean.

El proyecto ha sido open source desde el principio. ¿Hay alguna mejora o feature que te gustaría que alguien de la comunidad desarrollara y te enviara un pull request?

Sí, me encanta desarrollar y contribuir al open source. Es una forma de devolver algo a las comunidades de las que recibimos tanto cada día. Actualmente tenemos un tablón de ZenHub (se necesita plugin del navegador para verlo) para el proyecto y tiene un backlog con todas las issues y nuevas funcionalidades pendientes. Nos encanta recibir pull requests pero estate preparado primero para tener una conversación con nosotros antes de empezar a desarrollar. Además, la mayoría de los pull requests requieren una amplia batería de tests acompañando al código.

¿Cuáles son los planes de futuro? ¿Veremos los JDK publicados en SDKMAN!?

Actualmente estoy trabajando en la infraestructura que nos permitirá soportar binarios multiplataforma (¡como los JDKs!). Espero terminar esta funcionalidad en uno o dos meses. ¡Sí, definitivamente tendremos los JDKs disponibles pronto! Después de eso tengo planes para re-escribir y mejorar algunas de las APIs actuales de los servicios de backend.

Más información | SDKMan

También te recomendamos

Migraciones al cloud en primera persona

Introducción a Maven

¡Concurso! Tus momentos WTF tienen premio: un Xiaomi MI5 o uno de los 25 WTF Smart Sticker pueden ser tuyos

-
La noticia SDKMAN!: Un gestor de SDKs para dominarlos a todos fue publicada originalmente en Genbeta Dev por Iván López .

Desarrolladores metidos a emprendedores: ésta es su historia

$
0
0

Autonomo

El mercado laboral en la industria del desarrollo de software, está que arde. Las empresas se enfrentan diariamente a la frustrante búsqueda de perfiles técnicos que, simplemente, no existen en número suficiente como para cubrir la demanda.

Sin embargo, el establecimiento y fomento de una industria basada en las horas vendidas “al peso”, por la continuada permisividad del estado ante el constante infringir de las leyes de cesión de trabajadores, ha influido con fuerza en el crecimiento de la vía del autoempleo. En donde el programador toma las riendas y riesgos de su profesión, y se establece como trabajador autónomo por cuenta propia.

Para hablar sobre este tema he organizado una mesa redonda (HangOut) en donde nos reunimos cuatro amigos a compartir nuestras experiencias como trabajadores autónomos de la informática, desde puntos de vista diferentes.

Y de esta entrevista colectiva, han surgido ideas que quiero compartir contigo, lector de Genbeta Dev.

Me acompañaron en la mesa redonda…

Genbetadev Autonomos

Sergio León

Desarrollador web de soluciones basadas en tecnologías Microsoft. Miembro activo de la comunidad .NET, mantiene regularmente un blog de desarrollo. Lo que más le gusta es compartir y aprender. twitter @panicoenlaxbox blog http://panicoenlaxbox.blogspot.com/

Sergio tiene experiencia en más de una década como autónomo, llegando a tener trabajadores contratados en su equipo. Ahora mismo está en una etapa nueva cuando se ha integrado en uno de sus principales ex clientes, aportando a la mesa redonda la visión de quien recién ha vuelto a trabajar por cuenta ajena.

Pedro J. Molina

18 años desarrollando Software y especialmente enfocado en Software de Modelado y Generación de código. Es Ingeniero y Doctor en Informática por la Universidad Politécnica de Valencia donde realizó investigación en Ingeniería del Software. En los últimos 5 años ha sido Director de I+D y CTO para Icinetic en Sevilla y Seattle donde ha participado en los productos: Radarc, Windows Mobile AppStudio, Buildup.io o Hivepod.io.

Esta especializado en Microservicios, backends y despliegues en nube; además de dar ayuda a los equipos de desarrollo a mejorar y optimizar sus procesos para ganar en agilidad y mejorar la calidad del software. Twiter: @pmolinam

Pedro aporta la visión del némesis de Sergio. Siempre con puestos de responsabilidad en empresas, ahora está preparando el salto a ser su propio jefe y tomar su propias decisiones y riesgos. De forma planificada, meditada y con una potente visión empresarial.

Roya Chang

Desde hace años la gente suele llamarla "incombustible". Quizás sea porque, a sus 26 años, ha trabajado como profesora, estilista o incluso intérprete de chino para la Policía Nacional; además de sacar el título como Ingeniera Informática. Su amor por la tecnología la ha llevado hasta grandes empresas como Microsoft, trabajando en el rol de Evangelista Técnico responsable de los programa para estudiantes y contacto con universidades y centros educativos o BQ, como Product Manager en I+D de software.(www.flexcomtec.com/flexbot). Puedes contactar conmigo a través de mi Twitter: @RoyaChang

Roya, actualmente trabaja como desarrolladora freelance Full-Stack.Creando su propia línea de Electrónica y robótica educativa para colegios. Está recién iniciada en el autoempleo, enfrentándose a las complejidades del sistema para ser autónoma, con un empuje e ilusión que se apoya en su juventud. Aporta una visión de cuando estaba integrada en grandes multinacionales en relación a trabajar para uno solo. Además de resaltar la importancia de la inteligencia emocional imprescindible para lanzarse al ruedo.

¿Qué hay que hacer para entrar?

Puertas De Entrada

Lo primero que debes tener meridianamente claro es que tus circunstancias personales y profesionales sean positivas para ello. Como comentábamos en la mesa redonda, el autónomo nace con la inquietud y con el arrojo necesario para “buscarse la vida”, pero se hace con experiencia laboral previa y mucho estudio.

Lo que quieres hacer te debe apasionar y ser tu hobbie. Es decir, que no te duelan prendas el tener que dedicarle todo o casi todo tu tiempo libre. Porque, si no es así (como puede pasar en un trabajo por cuenta ajena), tu labor diaria se puede convertir en un infierno.

También es crítico que tu entorno y, sobre todo, tus compañeros vitales (pareja, padres, etc.) estén plenamente de acuerdo y dispuestos a echarte una o dos manos en tu emprendimiento. No tanto de forma activa, es decir apoyando positivamente la nueva posición laboral, sino teniendo cuidado de no “trolearte: convertirse en un lastre o impedimento que te obligue a elegir.

Es imprescindible tener un apoyo emocional y moral en las personas de tu alrededor que van a sufrir tanto las alegrías, las penas y las tensiones al tomar el control de tu trabajo.
-- Roya Chang

Pedro J. Molina también señalaba la importancia de preparar una estrategia de ventas y marketing. El decidir cuáles van a ser las apuestas de valor que te van a diferenciar del resto de la competencia (que es bastante dura). Y qué recursos económicos vas a poder disponer en el mejor y en el peor de los casos.

Cuanto mejor lo lleves pensado, más posibilidades tienes de tenerlo previsto. Aunque luego la realidad deja casi siempre en agua de borrajas nuestras predicciones, y es necesario desarrollar una cintura ágil y mucho teflón para que te resbalen las preocupaciones y no te bloqueen.

Hacienda somos todos

Ministerio De Hacienda

Como todo vecino en este país, lo primero que debes hacer para empezar a trabajar como autónomo es pagar. Pero si es tu primera vez, o llevas más de 5 años sin haberte dado de alta, puedes solicitar la “tarifa plana” que ofrece los siguientes descuentos:

  • Primeros seis meses: se paga una cuota fija de 50 euros mensuales, lo que supone un ahorro de 209,13 € sobre la tarifa normal. Esto es así si el autónomo elige su base de cotización mínima. Si elige otra mayor, tendrá una reducción del 80% de la cuota.
  • Del mes 7 al 12: una reducción del 50% (ahorro de 129,57 €)
  • Del mes 13 al 15: una reducción del 30% (ahorro de 77,74 €)
  • Del mes 16 al 18: una reducción del 30% (ahorro de 77,74 €)
  • Del mes 19 al 30: se mantiene una reducción especial del 30% (ahorro de 77,74 %), que no hayan sido autónomos en los 5 años anteriores.

Además, una vez iniciado los trabajos, vas a tener que hacer la declaración del IVA cada tres meses, en donde deberás abonar el IVA de todas las facturas emitidas durante ese periodo lo hayas cobrado o no. Sí, es esa la broma pesada del pago adelantado del IVA.

También tienes que hacer la declaración de Beneficios anual (ingresando en Haciendo un 30% de los mismos), y llevar al día todo el tema de las cuentas.

No delegues sin supervisión. Una mala praxis te puede meter en un “pufo importante”.
-- Sergio León.

Por todo ello, todos los presentes en la mesa redonda estábamos plenamente de acuerdo en que es imprescindible el buscar y contratar una buena gestoría. Y si, además, lo juntas con un buen despacho de abogados, tendrás cubierto un aspecto crítico de tu trabajo.

No lo intentes llevar tú porque, en la mayoría de los casos, termina en un caos que desemboca en sanciones por parte de los organismos gubernamentales recaudatorios.

Sin embargo, aun delegando en profesionales del sector, no te desentiendas del todo de los asuntos administrativos y legales. Debes de hacer el seguimiento y tutelaje de las operaciones porque, finalmente tú y solo tú, eres el último responsable.

Por último, como consejo, asegura que las incidencias económicas y legislativas que pudieran surgir de tu acción laboral, no impacten sobre los bienes de tu familia y la gente más cercana. Salvaguardando así el “bote salvavidas” que necesitarás si las cosas van mal o muy mal.

La satisfactoria dura realidad

Realidad Dura

Bueno ahora ya eres autónomo, eres tu propio jefe y tienes el control absoluto de tu tiempo. Ahora debes de tener muy en cuenta los principales riesgos que te pueden llevar a salir corriendo en busca de un medio de supervivencia. Y con los cuales todos nos hemos tropezado en mayor o menor grado.

El primero es justamente el trabajar demasiado. Está claro que todo desarrollador tiene a un Mister Hyde en su interior que le empuja a seguir codificando durante horas, sufriendo y padeciendo hasta llegar al orgásmico momento en que todo funciona.

Y también es cierto que tenemos a un Jekyll que nos empuja suavemente al caos, al último momento de máximo agobio y a esos esfuerzos hercúleos para poder cumplir el plazo acordado con un cliente feroz o – aún peor – con nuestras propias e irreales fechas de entrega.

Para ello, como bien dice Roya, es imprescindible una organización y disciplina férrea. El hacer de habito el trabajo, sin permitir que el que esté en el hogar me lleve a trabajar en pantuflas y pijama, con todos los riesgos de ostracismo y alejamiento de la realidad que conlleva largos transcursos de tiempo sin una conversación cara a cara con humanos.

Recuerda y tener muy presente que se trabaja para vivir y no al revés. No permitas que lo urgente te arrebate lo importante, defiende el espacio vital que requiere tu salud mental y la gente que tienes a tu alrededor que te apoya y te da estabilidad emocional y moral. Y aquí cobra especial importancia esa pareja que te “obliga” a salir del zulo en donde estas 16 horas al día, y compartir el tiempo con las personas que te quieren y te aprecian.

Otro factor de gran importancia es ser extremadamente estricto con los gastos de la empresa. No los confundas con tus gastos personales, ni tengas el dinero mezclado en la misma cuenta. Recuerda que el IVA no es tuyo, y que tu único sagrado propósito para Hacienda es transmitir ese dinero en las declaraciones trimestrales.

Y prepárate para los llamados “gastos extraordinarios” que, como bien dice Sergio León, son inesperados, insospechados y abundantes.

Venderte no es opcional, es crucial

Venderse

La mayoría de los programadores que conozco tiene un conocimiento pobre sobre las complejidades de vender, del trabajo de un comercial e – incluso – de la utilidad del rol. Pero eso se va a acabar en cuanto empieces a trabajar como autónomo, porque el trabajo no viene a llamarte a la puerta de tu oficina/casa más que en casos extraordinarios.

Por ello es imprescindible hacerte una buena y sólida imagen de calidad en Internet, y en todos los medios posibles. Incluso dedicar tiempo a labores de preventa y prospección, restándole del dedicado a picar código y hacer cosas productivas.

Hacer networking es obligatorio, y por ende el asistir a los eventos de la comunidad o de los círculos de tus clientes es obligatorio. Es más, deberías ir más allá del mero partícipe y convertirte en ponente o patrocinador, para darle un empaque más profesional a tu experiencia. Además, es el sitio excelente para aprender y ser consciente de las cosas que te quedan por estudiar o ponerte al día.

Dedica tiempo a aprender, a mejorar y a compartir tu conocimiento. Huye del acomodo que se produce cuando tienes controlada una herramienta o una tecnología. Y mantén siempre viva la llama de la curiosidad y la inquietud por conocer y explorar nuevas formas de abordar los retos.

“Si eres autónomo y no ganas dinero, algo estás haciendo mal”. Sergio León

También debes tener un precio por tu trabajo que te permita vivir holgadamente. Como indica Sergio León:. Debes tener presente que, sobre el coste de la hora que te puede permitir un sueldo “decente”, debes sumar los impuestos, algún tipo de protección frente a las bajas por enfermedad o accidente, los tiempos muertos sin trabajo (que no se cobra), las vacaciones, tu jubilación, la reinversión, el crecimiento de la empresa, los gastos corrientes, y los benditos imprevistos.

O sea que cobrar 3.000€/mes bruto es ir casi al límite de la mendicidad. No estás preparando nada para el futuro, y el presente debe ser perfecto para no encontrarte con serios problemas económicos en cualquier momento.

Pero para llegar y superar holgadamente esas cifras, deberás ser especial y especialista. Demostrar que, en tu sector, eres el mejor o uno de ellos. Y para eso hay que luchar por ser bueno o muy bueno en el nicho de mercado en donde vas a centrar el tiro, y tus esfuerzos.

Recuerda que al autónomo se le supone mucha capacidad de ser proactivo y que no se le pasa una. Cuan cierto es el dicho que dice: “Mil horas para ganar un cliente, un minuto para perderlo”. Y a sus conocidos, añadiría yo.

Los principales peligros en la selva del autónomo.

Selva

En la selva de los autónomos hay mucho peligros y obstáculos que pueden llevar a un mal termino la aventura laboral por cuenta propia. Y de entre ellos quiero destacar tres en especial que tienen una incidencia importante en los motivos del fracaso.

El primero es el peligro económico de morir por asfixia económica, y que es principalmente motivado porque en España se paga tarde y mal. Este país debe tener una de las legislaciones de impagados más laxas del mundo, en donde todos los estamentos – privados o estatales – se basan en la presunción de que nadie paga según lo convenido; y si se puede, pues terminan por escaquearse de pagar.

Es paradójico que cuanto más grande sea la empresa deudora, más tarde paga, y más obliga a soportar los gastos financieros al proveedor. Incluso se llega al obsceno caso de que pagan tan tarde, que te ofrecen sus propios servicios financieros que adelantan lo que te deben por una comisión sobre lo que ellos te deben. O, el vergonzante ejemplo del estado y sus plazos de pago de uno, dos o tres años para abonar lo que se debe; a lo que se añade el chantaje de “no te doy nada más” si te atreves a plantear una demanda por vía judicial.

Otro problema muy serio es cuando te resistes o no tienes talento para las labores comerciales. Es decir, no creces porque no te vendes. Y no te vendes porque no tienes tiempo. Y ese circulo vicioso te lleva a abandonar tarde o temprano por asfixia o cansancio.

También existe la vertiente más sibilina en donde tienes un cliente del que depende la mayoría de tu facturación y que termina devorándote y haciéndote una oferta como trabajador a cuenta ajena; o desaparece obligándote al cierre por quiebra (esto último lo he vivido en primera persona).

Y la última, e ilegal, sucede cuando este cliente se convierte en el único. Para el cual trabajas con todas las obligaciones de un trabajador por cuenta ajena, y con todos los inconvenientes y riesgos de un trabajador por cuenta propia. Y sin ningún derecho.

Eso que se denomina “falso autónomo”. Y que puede durar décadas hasta que un imprevisto te hace ver de forma cruda lo inconveniente de esta situación para el trabajador.

Buscando la salida

Salir

Ha llegado el momento. Ya sea por qué no puedes seguir, no quieres seguir o has crecido tanto que debes montar una empresa,** la cuestión es que vas a dejar el régimen de autónomo en busca de nuevas formas** de relaciones laborales. Y en ese momento verás como terminas como empezaste: pagando.

Recuerda, una vez más, que el IVA no es tuyo. Por lo cual cierra bien el último trimestre de la declaración para dejar saldadas todas las deudas que pudieras tener con la administración. También señala con fuego en el calendario la fecha de la declaración de Beneficios y tu próxima declaración de Hacienda que siempre sale a pagar.

Es decir, asegúrate que nada del pasado pueda aparecer en el futuro para amargarte la vida con responsabilidades no cubiertas. Y que, además, llegaran multiplicadas por comisiones de demora, premura, costes financieros y judiciales.

Si vuelves a ponerte en búsqueda activa de empleo a cuenta ajena, prepárate para que tus años de experiencia no tengan la validez que esperabas. Cuenta mucho más tu imagen en la Red y tu reputación en la comunidad, que los trabajos que hayas realizado. De hecho, volver al mercado laboral produce desasosiego y se puede hacer una tanto complicado si no tienes bien preparado el Currículo y las entrevistas.

En cambio, si lo que haces es crecer hacia convertirte en una empresa, los riegos y los beneficios se multiplican y nos salimos absolutamente del ámbito de este artículo. Por suerte hay mucha literatura para emprendedores y el emprendimiento. Alguna muy buena, pero cuidado con la morralla centrada en la autoayuda y en hacer negocio con las ilusiones de las startups.

Pero entonces, ¿por qué hacerse autónomo?

Exito

Puede dar la sensación que este artículo hace hincapié en las dificultades y riesgos del trabajo por cuenta propia. Pero no es así. De hecho, el espíritu al escribir este post es el animar a aquellos que sientan que es el momento para encontrar su propio camino, el lanzarse al ruedo y coger el toro por los cuernos.

No hay mejor manera de explicar con una sola frase, el sentimiento que te lleva a buscar tu propio camino y seguir tus decisiones, después de años trabajando para los demás. Para bien o para mal. Pero con la certeza e ilusión de quien conoce en profundidad el mercado, el negocio y la industria.

“Esta vez no va a ser culpa de mis jefes. Esta vez la culpa va a ser mía”.
-- Pedro J. Molina

A Roya Chang le motiva que sus proyectos personales vean la luz, le fascina y le encanta la robótica educativa y lucha por un futuro en donde la infancia acceda de forma natural a la programación, convirtiendo a España en un país puntero en el sector del desarrollo de aplicaciones informáticas.

Y Sergio León, la voz de más de una década de experiencia, rezuma nostalgia de los tiempos de autónomo en que “vivía muy bien”, aun cuando su puesto de responsabilidad actual, a cuenta ajena, represente nuevos retos, satisfacciones y oportunidades.

Sin duda el cimiento básico que ofrece trabajar para uno mismo, es el tener el control de tu vida laboral. El ser “diferente” a la generalidad de la sociedad y apostar tus conocimientos y esfuerzos para alcanzar una calidad de vida superior a la media.

Todos en la mesa redonda, incluyéndome, estuvimos de acuerdo en que el ser autónomo es algo positivo y que debiera ser una experiencia personal que todos debiéramos vivir.

Y así obtener el reconocimiento que más difícil es de alcanzar: el propio.

También te recomendamos

¡Concurso! Tus momentos WTF tienen premio: un Xiaomi MI5 o uno de los 25 WTF Smart Sticker pueden ser tuyos

Los 17 momentos por los que merece la pena ser desarrollador

Estado actual de la profesión de desarrollador en Europa

-
La noticia Desarrolladores metidos a emprendedores: ésta es su historia fue publicada originalmente en Genbeta Dev por Juan Quijano .

Aterrizando en la programación funcional

$
0
0

Fp

¿Por qué la programación funcional suscita tanto interés?, ¿qué la diferencia del principal paradigma imperativo usado en la industria?, ¿en que grado deberías/podrías sacar partido a la programación funcional? Este tipo de cuestiones aparecen de forma recurrente entre aquellos que observan con curiosidad o recelo los movimientos de los lenguajes por incluir características de programación funcional.

Aunque el tema es amplísimo, complejo e inevitablemente propenso al partidismo y subjetividad, intentaré desde mi modesta experiencia apuntar algunas ideas que quizás, te respondan a estas cuestiones.

La programación funcional puesta en práctica

En un sentido ontológico práctico y dejando de lado definiciones formales, yo diría que la programación funcional consiste en determinar, entender y fijar las relaciones existentes entre los objetos que utilizamos al programar.

Por ejemplo, el principio de sustitución de Liskov determina y permite entender una relación existente entre una jerarquía de objetos en la programación orientada a objetos. Esa conexión, encontrada, entendida y fijada por Barbara Liskov es en cierto sentido, un ejercicio de programación funcional.

Es muy posible que todo esto de relaciones, principios, teoremas, ... te parezca demasiado profundo para total, escribir tan sólo algo de código que lea un archivo por aquí, imprima algunas líneas por allá, ... pero parece razonable pensar que la calidad del código que escribamos estará directamente relacionada con el conocimiento que tengamos sobre qué significa escribir código.

Veamos las siguientes líneas de javascript:


var x = ~~cadena;
if( a ) {
  y = f(x, a);
} else {
  y = g(x);
}

Muchos programadores no verán ningún problema con este código y no le darían mayor importancia pero, pensemos por un momento en algunas de las relaciones que no hay ahí:

  • parece que cadena debería ser una secuencia de dígitos quizás precedida por un + o un - pero nada impide que sea un objeto Date, un número, undefined, ...
  • existe una relación obvia entre el chequeo de "nulidad" de a y que se usen las funciones f o g pero nada impide intercambiar las expresiones y evaluar f cuando a es nulo
  • y deberíamos suponer que los comportamientos de f y g están relacionados de alguna forma, aunque nada impide usar ahí cualquier otra función h, i, ... o que hagan y devuelvan cosas diferentes

Así, seamos o no conscientes, existen multitud de relaciones tácitas en el código que escribimos, que forman parte de la implementación aunque el lenguaje no las considere y que podrían ser utilizadas para escribir código más seguro, eficiente y conciso.

Seguramente una de las relaciones más obvias que pueden fijarse cuando programamos son los tipos pues, al escribir int y = g(x) se está poniendo de manifiesto una relación entre y y la función g. Pero la programación funcional establece muchas relaciones que no se limitan al sistema de tipos del lenguaje.

Con la programación funcional, de forma similar al principio de sustitución de Liskov, se busca encontrar, poner de manifiesto todas las relaciones posibles y utilizarlas para escribir código mas eficaz.

En C#, podríamos utilizar la sintaxis de LINQ para enlazar código (fijar relaciones) que requiere cierto valor pero que quizás está o no disponible y la sobrecarga de operadores para seleccionar el primero por la izquierda que sí posea un valor, algo como:


Quizás<int> y = from x in atoi(cadena)
                from r in (from o in notNull(a) select f(x, o)) | g(x)
                select r;

En el código anterior, la función atoi y la función g devuelven quizás un entero (Quizás<int>) y la función notNull devuelve quizás un objeto nulable (Quizás<T>) pero la función f requiere valores y sólo se evalúa cuando notNull(a) contiene un valor. La tubería devuelve el primer valor por la izquierda que sí posea valor (o ninguno si ninguno lo tiene) en expresiones como q1 | q2 | q3. Es la estructura interna codificada (en otro sitio) usando la sintaxis LINQ y operador | la que realiza la lógica de los Quizás y es tan general y reusable como las propias del lenguaje: if, switch, ...

Revisemos de nuevo algunas de las relaciones anteriores:

  • podemos usar x con seguridad, puesto que las computaciones debajo de from x no serán evaluadas si atoi falló. Y no hay otra forma de acceder a x (la compilación fallaría).
  • podemos usar o con seguridad por la misma razón, es imposible acceder a a si es nulo.
  • la relación entre f y g está implícita pues la familia de computaciones admitidas está restringida a las que devuelven Quizás<int>. Y eso, que el tipo de retorno de f y g es diferente.

En lenguajes con sintaxis más adecuadas podría quedar (ej. Haskell):


let y = do  x <- atoi cadena
            (f x <$> notNull a) <|> g x 

La programación funcional busca esas relaciones y define estructuras y estrategias que, como el ejemplo de C#, refinan y aseguran otras previas.

Por tanto, la programación funcional no es hacer un "reduce-map" o usar listas por comprehensión, sino entender y usar relaciones de una forma que, en la práctica, está mostrando algunas ventajas frente a otros paradigmas.

Comparativa de algunas estrategias

El ejemplo anterior muestra como controlar el flujo según el resultado de las operaciones intermedias. Un ejemplo real (en el que he cambiado los nombres de los símbolos para respetar la fuente) transformado a un estilo funcional podría ser la siguiente función:


        bool ShowControl(Request request) {
            IControlFinder finder;

            if (!Api.TryResolveInjection(out finder)) {
                return false;
            }

            var control = finder.FindControl(request);
            if (control == null) {
                return false;
            }

            if (control.ViewData != null) {
                return true;
            }

            var service = Api.ResolveInjection<IViewDataTransformer>();
            var viewData = service.ViewFromData(request);
            control.ViewData = viewData;
            return true;
        }

como en el ejemplo anterior, hay unas cuantas relaciones "no resueltas" como que la inyección de la dependencia a IViewDataTransformer puede fallar o, quizás, la generación de los datos de la vista. También se observan diferentes convenciones para indicar éxito como en Try o los chequeos de null. Quien lo codificó decidió no añadir ahí aserciones como comentábamos en To throw or not to throw o para que sirven las excepciones.

Usando una estilo aplicativo y la notación LINQ anterior podría ser algo como



Quizás<Void> ShowControl(Request request) {
   return from finder  in Api.GetFinder()
          from control in finder.FindControl(request)
          from success in control.ViewData
                        | from service  in Api.GetService()
                          from viewData in service.ViewFromData(request)
                          from result   in control.SetViewData(viewData)
                          select result
          select success;
}

o de forma similar en Haskell algo como


viewFromRequest :: Request -> Control -> API ()
viewFromRequest r c = withService (viewFromData r) >>= setViewData c

showControl :: Request -> API ()
showControl request = do  control <- withFinder $ findControl request
                          viewData control <|> viewFromRequest request control

Otro pequeño ejemplo consiste en cómo se realiza la inyección de dependencias o, mejor dicho, cómo no se realiza ningún tipo de inyección de dependencias.

En el código anterior hemos visto que nuestra Api hace uso de cierto servicio (Api.GetService) para realizar la acción que sea. Con el fin de desacoplar esa acción que necesitamos con quien finalmente realizará la acción se tiene la inyección de dependencias.

Muy por encima, la inyección de dependencias se puede dividir en dos aspectos:

  1. cual es la acción que queremos independizar desacoplar.
  2. de qué forma consigo yo un objeto que me proporcione dicha acción.

La forma más básica (de inversión) es mediante callbacks, cuya firma resuelve el primer punto. Pasarlos como argumento es también la forma más básica de resolver el segundo punto.

Pero pasarlo como argumento requiere ir arrastrándolo "por ahí", por lo que se suele tirar de reflexión para inyectarlo resolverlo en tiempo de ejecución a partir de algún fichero de configuración (ej. Web.config), anotaciones (@Inject), singleton global (ej. Routes.cs), ...

En la programación funcional y usando mónadas, las computaciones se definen dentro de un contexto sobre el que el programador ha decidido abstraer su problema, formalmente, nada que no se haya previsto en ese contexto está permitido realizar (puedes leer sobre ello en Usar mónadas es mucho más fácil de lo que crees, empezando con la programación funcional) y por tanto si nuestra función showControl va a necesitar instanciar un Finder nuestro contexto debe permitirlo. A partir de ahí, cualquier computación dentro de ese contexto tiene disponible esas computaciones definiciones sin necesidad de arrastrar explícitamente el contexto. Muy, muy burdamente sería como que nuestra Api entera consiste en una única clase parcial y la instancia concreta de cierto interface (ej. IHttpProvider) la tenemos accesible mediante algún getter (por hacerlo lazy).

En el ejemplo, los withService"recuperan" una computación permitida en el contexto, cuyas definiciones pueden estar en cualquier sitio (no dentro de una gran clase Api).

Otra estrategia muy usada en la programación funcional es la currificación o (no siendo exactamente lo mismo) aplicación parcial en que cierta función con argumentos es reducida a otra función con menos argumentos. De forma similar a la inyección de dependencias, aquí podemos tener computaciones configurables sin que haya que arrastrar la configuración (o inyectarla).

Por ejemplo, si tenemos cierta función que renderiza un informe, no hace falta pasar explícitamente las propiedades "locales" que tendrá el título (color, tipo de letra, ...) sino que ignoraremos esas propiedades dándolas por asumidas y sólo definiremos lo que queremos abstraer a ese nivel, en el ejemplo, la inversión se produce en el texto que habrá en el título:


renderizaInforme :: (String -> Picture) -> ... -> Picture
renderizaInforme titulo ... = do
  ...
  let tituloPic = titulo "Informe"
  ...
  pictures [ ..., tituloPic, ... ]

desacoplando la lógica de renderizado que sea con las particularidades del título. Posteriormente se podría definir como


data Mostrar = Informe | Menú | ...

interfazGráfica :: Mostrar -> Render ()
interfazGráfica Informe = withRender $ renderizaInforme (textPicture Red Bold)
interfazGráfica Menú = ...

-- donde cierta API gráfica define
data Color = Red | Blue | ...
data FontWeight = Normal | Bold | ...

textPicture :: Color -> FontWeight -> String -> Picture

Exponer aunque fuera sucintamente otros aspectos como la reducción (o fusión) total o parcialmente automática de computaciones enlazadas, la elevación al sistema de tipos de invariantes en nuestra aplicación (por ejemplo el routing en un servicio REST) o que la facilidad de crear DSL permite construir entornos seguros (el contexto del que hablábamos antes) sería largo y seguramente no los sabría exponer adecuadamente, pero espero que estos ejemplos hayan dado una pequeña idea.

Automatizando el principio de sustitución de Liskov

Las estrategias mostradas anteriormente suelen poderse aplicar a cualquier lenguaje, pero ya hemos apuntado la idea de que la programación funcional no es la aplicación de esas estrategias sino la capacidad intrínseca del paradigma para razonar, obtener conocimiento y aprovecharnos de ello.

¿No sería genial que el propio compilador nos advirtiera de que nuestra jerarquía de objetos está incumpliendo el principio de sustitución de Liskov?

Ese es el enfoque que motivan y potencian ciertos lenguajes resultando en herramientas como Proving Type Class Laws for Haskell (vía @Jose_A_Alonso) que permiten de forma automática probar que todas las instancias de cierto interface cumplen las leyes propiedades obligadas por el interface. O como fitspec que de forma automática nos indica si nuestros test de invarianzas (ej. la concatenación de cadenas implica suma de longitudes) cubren el dominio.

Problemas de la programación funcional

Un estilo funcional no está exento de inconvenientes, igual que otros paradigmas sufre del problema de expresividad de forma inversa a como ocurre con la POO por lo que dependiendo del problema podría no ser el enfoque más adecuado. La facilidad con la que pueden definirse estructuras globales (vía DSL, aplicación parcial, ...) supone con frecuencia que debemos "estudiar" el enfoque particular de ciertas apis que al principio puede sorprender, pues parecen otro lenguaje diferente. Por uno u otro motivo, las estructuras que suelen definirse provienen de las matemáticas, lo que supone por un lado una asunción de un conocimiento previo de las mismas (monoide, functor, ...) que quizás no existe y por otro lado un nivel de abstracción mayor, complicando la adopción de ciertas estrategias.

En todo caso, consigue un curioso efecto en el que las abstracciones quedan más desacopladas que con otros paradigmas y a la vez, son las definiciones las que tienden a estar mucho más acopladas llevándonos al dicho de que "si te compila Haskell, seguramente sea correcto".

También te recomendamos

El enumerador genérico IEnumerable. Fundamentos de LINQ II

Conociendo los métodos de extensión. Fundamentos de LINQ I

Cuántas muertes han evitado los móviles en las conquistas de las montañas más peligrosas del mundo

-
La noticia Aterrizando en la programación funcional fue publicada originalmente en Genbeta Dev por Jose Juan .

Mantra. Pruebas de seguridad desde el navegador.

$
0
0

OWASP Mantra - Security Framework

Mantra es una colección de más de 40 herramientas gratuitas y libres integradas en un Navegador Web. Es decir, es un navegador web, gratis y de código abierto, diseñado para pruebas de seguridad. Se trata de un proyecto amparado por OWASP (Open Web Application Security Project), y liderado por Abhi M Balakrishnan y Yashartha Chaturvedi.

Se trata de una herramienta muy útil para penetration testers, desarrolladores de aplicaciones web, profesionales de la seguridad de la información o incluso administradores de sistemas, dada la variedad de utilidades que están incluidas. Nos va a permitir gestionar y modificar la información de las cookies, utilizarlo en una auditoria de seguridad durante la etapa de fingerprinting para recopilar información, interceptar las peticiones GET/POST, modificar el campo User-Agent del navegador o conectarnos a nuestras máquinas por SSH o FTP, entre otras cosas.

Mantra está desarrollado a partir de Firefox, modificando la apariencia original de este, y añadiéndole una serie de plugins que nos van a permitir:

  • Manipular cabeceras HTTP
  • Fingerprinting WEB (similar a Wappalyzer)
  • Interceptación de peticiones GET y POST
  • Manipular inputs de entrada
  • Sustitución del User-Agent
  • Capacidad para operar con Proxys
  • Editar cookies del navegador (cookies manager +)
  • Comprobaciones (básicas) de inyecciones

Descargar e instalar Mantra

En la página de descargas de Mantra encontraremos versiones para Windows, Linux y Mac:

Mantradownload

La instalación en windows es bastante sencilla. Al hacer doble click en el instalador vamos a poder elegir el idioma en el que queremos que se instale, y la ruta dónde queremos instalarlo. En esa ruta nos va a crear una carpeta con la versión 'portable' de mantra.

Instalacion De Owasp Mantra Portable Installer

C Mantra Mantraportable

Qué pruebas podemos hacer con Mantra

Mantra pone a nuestra disposición una selección de las mejores extensiones de Firefox para pruebas de seguridad web, en un sentido muy amplio. Nos va a permitir modificar cabeceras, manipular cadenas de entrada, reemplazar peticiones GET y POST, editar cookies, utilizar diferentes tipos de proxy y obtener mucha información de los sitios web que probamos, de una manera más rápida y sencilla.

Al abrir el navegador Mantra y navegar a cualquier sitio web empezaremos a obtener información interesante:

El sitio web de GenbetaDev en el navegador Mantra El sitio web de GenbetaDev en el navegador Mantra

Como podéis ver, a la derecha de la barra de navegación ya nos está mostrando información interesante sobre las tecnologías usadas en esta web: Google Analytics, comScore analytics, Backbone.js, Chartbeat, jQuery, Modernizr, RequireJS, Underscore.js, y la ubicación del servidor.

Hackbar es una herramienta creada por Johan Adriaans y Pedro Laguna para facilitar ciertas pruebas de inyección de código que requieren saltarse filtros de codificación. Entre otras cosas, este plugin te va a permitir codificar y decodificar diferentes tipos de cifrado. Aquí tenéis un vídeo con más información sobre cómo usar Hackbar.

Foxy Proxy es un plugin de tipo proxy para Firefox. Proporciona una configuración bastante más completa que la del propio navegador por defecto, ampliándola por ejemplo para generar listas blancas/negras, o incluso permitiendo incorporar patrones de direcciones con expresiones regulares, asteriscos, etc. Lo habitual será configurar Foxy Proxy de manera que nos permita, por ejemplo, simular una ubicación diferente de la nuestra. Otro proxy incluido con Mantra es Proxy Tool, un potente proxy orientado a facilitar nuestro anonimato en internet, con rotación automática de proxys:

Proxy Tool Proxy Tool cuenta con opciones como la rotación automática de proxys
Foxy Proxy para Firefox Foxy Proxy proporciona una configuración más completa que la del navegador por defecto

El último proxy incluido es Tamper Data. Tamper Data nos permite ver y modificar las cabeceras HTTP/HTTPS y modificar los parámetros POST. Puede ser muy útil a la hora de comprobar que las validaciones se hacen tanto en el lado del cliente como en el servidor.

Live HTTP Headers nos permite ver la información de las cabeceras HTTP de los sitios que visitemos. La información que obtengamos con este plugin puede ser utilizada después en combinación con otras herramientas, o puede mostrarnos errores en la configuración de nuestros servidores.

Con Cookies Manager + podremos gestionar nuestras cookies, de manera que podamos visualizar la configuración de nuestras sesiones, o suplantar cookies durante un ataque de tipo hijacking de sesión.

FireSSH convierte nuestro navegador en un cliente SSH. De esta forma no necesitamos salir de nuestro navegador ni siquiera para conectarnos a las máquinas por SSH. Su uso es muy sencillo, basta con introducir en las casillas los datos de conexión del servidor SSH.

Mantrafiressh

Por supuesto, si no necesitamos salir del navegador para conectarnos por SSH, pues tampoco para conectarnos por FTP, gracias al plugin FireFTP. Soporta comparación de directorios, SFTP, SSL, hashing, etc.

Si lo que queremos es hacer pruebas de tipo SQL Injection, podemos usar SQL Inject Me. Esta herramienta sustituye los valores de los formularios web por valores representativos de un ataque SQL Injection, envía el formulario, y busca mensajes de error renderizados dentro del HTML de la página. Es un plugin que nos ayuda a encontrar posibles puntos vulnerables a este tipo de ataque.

User Agent Switcher es un plugin con el que podemos modificar el user agent con el que navegamos, de manera que podamos verificar cómo se comporta el sitio web bajo pruebas ante determinados casos, como dispositivos móviles, web crawlers de los buscadores, lectores de pantalla o navegadores en Braille usados por personas con discapacidades.

Más herramientas interesantes incluidas son QuickNote, DomainTools y Netcracft. También nos da la posibilidad de lanzar Fiddler desde el navegador. Os dejo un enlace a la lista de todas las herramientas incluidas en Mantra.

Aspectos positivos

Dicho todo lo anterior, resumiría los aspectos positivos en que Mantra pone a nuestra disposición un montón de herramientas muy útiles para determinadas pruebas sobre aplicaciones y sitios web, sin necesidad de realizar nosotros esa búsqueda de herramientas, y sin tener que instalarlas.

Otro aspecto interesante de Mantra está en su sección de marcadores, que tras su instalación ya contiene un montón de recursos muy útiles sobre revistas de hacking, metodologías, OSINT, y otros enlaces interesantes relacionados con la seguridad web.

Marcadores Mantra

Aspectos negativos

El principal problema de Mantra es que el proyecto está bastante parado. Además de esto, está basado en una versión de Firefox que podríamos considerar casi obsoleta y, aunque nos da la opción de actualizar, esto acaba generando un error que hace que deje de funcionar.

Una alternativa podría ser instalar todos estos plugins, o al menos los que necesitemos, en una versión actual de Firefox.

Existe una versión de Mantra sobre Chrome, sólo disponible para Windows, y está en una fase de desarrollo muy inicial. Dicho esto, si queremos una "alternativa" a Mantra, pero en Chrome, podemos instalar algunas de estas extensiones, o similares, disponibles para este navegador. Algunas de las extensiones más interesantes para Chrome serían:

También te recomendamos

Cómo Taiwán se ha convertido en una de las potencias líderes en tecnología

Extensiones de Firefox para desarrolladores web

Publicado Firefox 9: mejoras notables en Javascript

-
La noticia Mantra. Pruebas de seguridad desde el navegador. fue publicada originalmente en Genbeta Dev por Raúl Hernández .

Viewing all 564 articles
Browse latest View live