Un año de investigación UNTreF

Esta semana está terminando el cuatrimestre en UNTreF (ayer fue la última clase de Ingeniería de Software) y me parece un momento apropiado para repasar lo que ha sido para mi este primer año de trabajo en investigación.

Si bien las primeras charlas del proyecto fueron a fines del año pasado, no fue hasta Enero que comenzamos a trabajar formalmente. Prácticamente todo trabajo de todo este año estuvo centrado en actividades de formación y en la realización de un primer estudio de índole exploratoria sobre el uso de prácticas en la comunidad ágil.

Este estudio tomo la forma de una encuesta la cual realizamos en el contexto del Agile Open Camp 2016. Luego de realizada la encuesta pasamos un buen tiempo analizando los datos recogidos y finalmente escribimos paper compartiendo nuestros hallazgos.

Respecto de la actividades de formación yo personalmente participé de las siguientes:

  • Seminario de Introducción a los métodos experimentales de investigación en Ingeniería de Software, dictado por Alejandro Oliveros de la Universidad Nacional de Tres de Febrero (quien es al mismo tiempo el director de nuestro proyecto de investigación)
  • Taller de redacción de tesis, dictado por Zulma Cataldi (Universidad Nacional de La Plata)
  • Curso Empirical-Based Software Engineering, dictado por Marcela Género (Universidad de Castilla La Mancha)
  • Seminario Estructura de los Artículos Científicos, lineamientos generales para la escritura de un paper, dictado por Carlos Neil (Universidad Abierta Interamericana)

Por otro lado participé de los congresos:

  • International Conference on Agile Software Development, XP 2016.
  • Congreso Nacional de Ingeniería Informática / Sistemas de Información, CONAIISI 2016.

En el primero estuvimos dando un Taller sobre Modern XP mientras que en el segundo fue donde presentamos el paper resultante de nuestra investigación. La semana próxima se publicarán las memorias del congreso en las cuales estará disponible nuestro trabajo.

Personalmente estoy muy conforme con este primer año de trabajo, ha sido una experiencia muy interesante y espero que el año se ponga aún mejor.

 

Una alternativa al Double Dispatch

Double Dispatch es un patrón de diseño para resolver situaciones en las que el comportamiento resultante no depende solamente del objeto que recibe el mensaje sino también de parámetro enviado en ese mensaje. Veamos un caso concreto para entender mejor esta situación.

Supongamos que debemos modelar un juego de naves espaciales tipo Galaga donde tenemos distintos tipos de objetos espaciales como ser Naves, Estaciones y Asteroides. Estos objetos pueden colisionar entre si y el resultado de dicha colisión depende particularmente de quienes son los objetos involucrados y del estado de los mismos. Veamos un ejemplo:

  • Si una nave colisiona con un asteroide la nave es destruida (vida = 0) y el asteroide disminuye su velocidad en 3 unidades
  • Si una nave colisiona con una estación a baja velocidad (velocidad < 10), entonces la nave se detiene (velocidad = 0) y la estación no sufre ningún cambio de estado
  • Si una nave colisiona con una estación a alta velocidad (velocidad >= 10), entonces la nave es destruida (vida = 0) y la estación disminuye su vida en 4 unidades.

Una solución trivial podría ser que cada objeto tenga un método «collideWith» en el que se verifique contra quien está chocando y se actúe en base a ello:

// SpaceShip
public void collideWith(SpaceObject otherObject) {

    if (otherObject.getClass() == Asteroid.class) {
        this.life = 0;
    }

    if (otherObject.getClass() == Station.class) {
        if (this.speed < 10){
            this.speed = 0;
        }
        else{
            this.life = 0;
        }
    }
}

Código completo Java de esta solución disponible aquí.

spacewar_trivial

Las clases Asteroide y Estación tendrían métodos análogos.
Si bien esta solución funciona, resulta un poco «rústica» en términos de Orientación a Objetos porque viola algunos principios de diseño, entre ellos viola el principio abierto-cerrado, ya que en caso que aparecer un nuevo tipo de objeto (como por ejemplo Cometa) habría que modificar cada uno de los métodos CollideWith para contemplar los nuevos casos.

Es aquí donde el Double Dispatch nos propone una alternativa un poco más elegante. La idea es que cuando un objeto recibe una colisión, delega la resolución al otro objeto invocando a un método más concreto como se muestra en el siguiente fragmento de código:

// SpaceShip
// Dado que aquí "this" es SpaceShip, se terminará ejecutando
// el método collideWith(SpaceShip) del otherObject
public void collideWith(SpaceObject otherObject) {
 otherObject.collideWith(this); 
}

protected void collideWith(Asteroid asteroid) {
 this.life = 0;
}

protected void collideWith(Station station) {
 // do something
}

protected void collideWith(SpaceShip ship) {
 // do other something
}

Código completo Java de esta solución disponible aquí.

spacewar_doubledispatch

Esta solución implica que cada clase tendrá un método collideWith por cada clase con la que pueda llegar a colisionar. En este caso particular donde tenemos 3 clases, tendremos 9 métodos (dependiendo del comportamiento particular que definamos para resolver la colisión podríamos tener tal vez algunos métodos menos).  En cierto modo esta solución también viola el principio abierto-cerrado, porque en caso de aparecer un nuevo tipo de objeto es necesario modificar todas las clases para agregar un nuevo método que resuelva la colisión aunque a diferencia de la solución anterior, aquí no modificamos un método existente sino que agregamos un nuevo método, lo cual es menos rústico.

Finalmente la solución a que mi gusta para esta situación entra en la categoría que Steve McConnell denomina Table-Driven methods (capítulo 18 de libro Code Complete). La idea es emular una tabla de métodos virtuales que es lo que usan algunos lenguajes a bajo nivel para resolver el late binding. Más concretamente lo que se hace es que cada objeto tenga una tabla o mejor dicho un diccionario (collisionMap) donde la clave es la clase contra la cual colisiona y el valor es un closure/lamba con la lógica a ejecutarse al colisionar contra ese tipo de objeto. Implementar esto en Smalltalk y/o Ruby es trivial, pero en Java tiene una vuelta de rosca extra, simplemente por la forma en que se implementan los lambdas en Java.

// Cuando se crea el objeto debe inicializarse el collitionMap
protected void initCollisionMap() {
    collisionMap = new HashMap<>();
    collisionMap.put(Asteroid.class, (x) -> collideWithAsteriod(x));
    collisionMap.put(Station.class, (x) -> collideWithStation(x));
}

// Este el punto de entrada en la colision
// Notar que la busqueda en la tabla es polimorfica
public void collideWith(SpaceObject otherObject) {
 CollitionHandler handler = this.collisionMap.get(otherObject.getClass());
 handler.collideWith(otherObject);
}

private void collideWithAsteriod(SpaceObject other) {
 this.life = 0;
}

private void collideWithStation(SpaceObject x) {
   // do something
}

Código completo Java de esta solución disponible aquí.

spacewar_table

A la hora de agregar un nuevo tipo de objeto, esta solución requiere agregar una nueva entrada al collisionMap y un nuevo método si es que la interacción con este nuevo tipo de objeto es distinta a las ya existentes. Otro punto interesante de esta solución es la posibilidad de variar el comportamiento de cada instancia de la misma clase, ya que el collisionMap puede alterarse en tiempo de ejecución.

Continuará…

Developing .Net on Mac

Developing .Net on Mac

I am not talking about .Net Core that runs on MacOS out-of-the-box. I am talking about .Net Framework 4.5 that only runs on Windows. This means that you need a Windows installation.

One option is to install Windows directly on Mac hardware, but this was never an option for me.

So the other option is to virtualize Windows. But this option implies 2 more concerns: which virtualization technology to use and which Windows version to virtualize.

Regarding virtualization I am using Oracle Virtual Box, it is free, works fine and I have been using it for years, so I didn’t even try other tool.

Regarding Windows, I tried different options and finally I decided to use what  worked best for me: Windows 7 (64 bits) but with an «special setup»: no antivirus and updates turned off.

And finally, beyond Visual Studio and the usual stuff for .Net development I added the following software:

  • Cmder, a great console emulator
  • Notepad++, a lightweight file editor
  • FireFox, the browser

 

Refactoring .Net applications Series

The main project I am currently working on, is composed of hundred of C# projects, all of them grouped into 3 git repositories: user-facing apps, background-apps and commons. The main webapp project in placen on the user-facing repo but depends on other projects that are placed in the other repositories. Because of this, to build the main webapp you have to clone then 3 repositories.

This situation has some drawbacks:

  • It is uncomfortable for developers working on the webapp
  • The high coupling between repositories/projects brings a big complexity when you have several teams working in parallel
  • The maintenance/evolution of the system gets too complex

To deal with this situation we decided to «cut» the system in several dimensions: functional, technical and SCM. So in the upcoming post I will share the different strategies we are using.

La pesada herencia

La pesada herencia

La pesada herencia es una frase que ha sonado bastante en el terreno político en Argentina en los últimos meses, pero no voy a hablar de política. Sino del código legacy que he heredado en el proyecto que estoy trabajando.

Esta semana completamos la tercera iteración del proyecto, todo en orden hasta el momento. Pero en esta cuarta iteración comenzamos a integrar el módulo que veníamos desarrollando con el resto del sistema, el cual es un sistema legacy: sin pruebas, con muy alto acoplamiento, baja cohesión, código oscuro, etc. El cliente es consciente de esto y por ello no se sorprendió cuando le dijimos que la fecha de salida a producción que habíamos hablado no sería factible. En cierto modo entendió «la pesada herencia». Ok, bien, es la realidad y no es fácil pero debemos afrontarla.

Pero de aquí a un año ya no podremos culpar a «la pesada herencia» porque si dentro de un año el sistema sigue siendo legacy, entonces no será «la pesada herencia» sino nuestra triste incompetencia.

NetConfUY 2016, pensamientos finales

Mi balance de la conferencia es muy positivo, llevé más de lo que esperaba. La organización estuvo impecable y el contenido fue de primer nivel.

Por otro lado, hacía bastante que no asistía a un evento «Microsoft-related», en general en los últimos años me he inclinado más por eventos/conferencias más relacionadas a «ingeniería de software» (xpconf, uqbar, socrates, etc) que a tecnologías específicas. Un patrón que noto en los eventos/conferencias centrados en tecnología es que casi todos el contenidos (o al menos la mayoría) está centrado en mostrar nuevas tecnologías, algunas de las cuales están aún en estado «beta» sin prestar mayor atención a «buenas prácticas». Un ejemplo concreto: en ninguna de las sesiones que asistí en la NetConf se hizo mención a como testear software construido con las tecnologías presentadas. Obviamente alguien podrá decir con toda razón que esas cuestiones estaban fuera del alcance de la conferencia, pero personalmente son cosas sobre las que me hubiera gustado escuchar.

NetConfUY 2016, día 3

NetConfUY 2016, día 3

La jornada comenzó con una charla no tan técnica de Alvaro Lame (un referente de la industria uruguaya de software) quien habló sobre la actualidad y los desafíos de la economía digital en Uruguay. La exposición fue muy buena y con un montón de datos interesantes.

A continuación Diego González y Lucas Pallarés dieron una sesión de programación sobre Hologens y codearon un juego en 40 minutos, impresionante. La sesión fue interesante y arriesgada pero todo salió impecable.

En el siguiente bloque escuché a Mariano Vazquez hablando sobre micro-servicios. Comenzó explicando los fundamentos y luego compartió varias de sus lecciones aprendidas en el día a día con este tema.

Ya cerrando la mañana Victor Silva habló sobre DevOps, PowerShell y Windows Containers. Esta fue una de las sesiones que me resultó más útil, ya que no estaba al tanto de varias de las cuestiones mencionadas y al mismo tiempo resultan ser todas cosas aplicables a mi proyecto actual. No voy a entrar en mayor detalle sobre la sesión pero les dejo algunas «keywords» para googlear: Windows Nano Server y PowerShell DSC.

Luego del almuerzo estuve rondando de un lado a otro haciendo sociales. En ese contexto estuve hablando con Dalmiro Granias, un desarrollador del equipo de Octopus y con Kevin Pilch, del equipo de C# en Microsoft.

Ya en el último bloque de la tarde escuché a Hernán Guzmán hablando sobre Serverless Computing usando Azure Functions (un análogo a Webtask de Auth0). Como la sesión terminó un poco antes de lo planeado, llegué a ver el cierre de la sesión de RodolfoF sobre Asp.Net Core, un tema con el cual vengo experimentando desde hace un tiempo y que sin dudas es uno de los temas calientes en la actualidad del mundo .Net.

La jornada finalizó con un after en el que compartimos empanadas, cerveza y música con la compañía de un mago que nos entretuvo con muy buenos trucos con cartas y sogas.

NetConfUY 2016, día 2

El día comenzó con el Keynote de Edu Mangarelli, como siempre, un excelente orador. Su keynote rondó alrededor de 3 temas calientes: Machine Learning, Bots

A continuación Gabriel Cor habló sobre Hologens, entre anécdotas y chistes contó un algunos casos del uso de Hologens en proyectos reales. Muy interesante.

El siguiente bloque de charlas estuvo dedicado a servicios cloud: primero MatiasQ habló sobre Azure Search y luego Tony Poza habló sobre Cognitive Services. Dos temas interesante que habilitan (o facilitan muchísimo) la resolución de ciertas situaciones.

Ya por la tarde Mariano Sanchez habló sobre TypeScript, la charla comenzó bien, pero me fui antes del final porque para mi gusto TypeScript intenta «mejorar JavaScript» pero paradójicamente «le quita a JavaScript» las cuestiones que más me gustan. En fin, más allá de esta cuestión de gustos, la sesión de Mariano estuvo muy bien (al menos la parte que escuché). La siguiente sesión fue muy útil e interesante: Kevin Pilch habló sobre el futuro de C#. Mi evaluación de los futuros cambios de C# tiene resultado «neutro» en el sentido que la mitad de las cosas me gustaron mucho mientras que la otra mitad me parecieron «aterradoras».

En el siguiente bloque estuve «saltando» de una sala a otra y la verdad no puedo opinar sobre las sesiones.

Ya en el último turno estuve en la sesión de Azure Stream Analytics de Leo Micheloni. Me gustó mucho que además de explicar el producto, Leo compartió varias recomendaciones consecuencia de su experiencia real con el producto.

Y así se fue el día 2.

NetConfUY 2016, día 1

NetConfUY 2016, día 1

El primer día de la conferencia estuvo dedicado por completo a workshops, dos tracks en paralelo, con sesiones de 2 horas para poner manos en la masa. Dado que las sesiones tenían un cupo de 40 asistentes la cantidad total de gente de este primer día estuvo acotada. Resumo brevemente las sesiones a las que yo asistí.

La primera sesión fue Prototipado de aplicaciones Moviles con Xamarin Forms y estuvo a cargo de Sorey García. Este es uno de los temas con los que me sentía en deuda y por ello decidí asistir. El contenido no fue muy profundo pero para mi que estaba totalmente en cero, me vino de muy bien. Con lo que vi creo que ya tengo una idea suficientemente para imaginar los casos específicos en los que Xamarin podría resultar la opción apropiada.

Mi segunda sesión del día fue IoT para principiantes: Mis primeros pasos con Arduino y fue facilitada por Leo Micheloni. Este es otro de los temas que tenía pendiente hace muchísimo tiempo. La sesión estuvo excelente, los asistentes nos repartimos en varias mesas (entre 4 y 6 por mesa) y Leo nos repartió un kit de Arduino y unos pendrives con el SDK para instalar. Inicialmente hizo una explicación general y luego pusimos manos a la obra armando distintas configuraciones sobre la plaqueta y programando distintas «lógicas» usando: leds, pulsadores, sensores de proximidad, etc, etc. El modelo de programación y «ensamble» de Arduino es realmente muy simple.

Las sesiones 3 y 4 fueron como «hermanas»: primero Asp.Net & ReactJS y luego Asp.Net Core & Angular 2. Estas sesiones estuvieron a cargo de Mariano Vazquez y Nico Bello respectivamente (dos miembros de la familia FIUBA, ¡que chico parece el mundo a veces!).  Desde el punto de vista del contenido y la dinámica, ambas sesiones estuvieron muy bien.

Ya cerrando el día participé de la sesión de MauroG y RodolfoF sobre Asp.Net Core en Linux. La sesión estuvo bien pues el ejemplo sobre el que se trabajó cubrió la un caso web típico de punta a punta: UI-Controllers-Models-DB.

Al finalizar la última sesión, ya eran más de las 21, ¡upa! vaya que fue un día intenso y aún quedan dos días más  😉

Configuring Jenkins Authentication with Auth0

The procedure described here is based on Jenkins 2.7.4 but I think it should also work with other (not so distant) versions.

First of all, log into your Auth0 account.

Then create a new client applicationClients» item in left-hand menu).

auth0_1

In  the «Create Client» dialog set the name of your client application (for example «MyJenkins«) and choose the application type «Regular Web Applications«, finally click «Create«.

auth0_2

Once the application is created, go to «Settings» and set the value of the «Allowed Callback URLs» to «http://YOUR_JENKINS_URL/securityRealm/finishLogin«. Click «Save Changes«.

auth0_4

Scroll down to the «Advanced Settings» section, click on «Endpoints«. Take the SAML Metadata URL and save the content in that URL into a file (remember this file because we will use it later when configuring Jenkins).

auth0_9

Go to the «Addons» tab and enable «SAML2» option.

auth0_5

In the Addon configuration dialog edit the settings to set the «audience» and «recipient» values to «http://%5BYOUR_JENKINS_URL%5D/securityRealm/finishLogin«.

auth0_6

Click «Save» and close de dialog. Now you should see the SAML2 option is enabled.

auth0_7

 

That’s all on Auth0 size, now let’s work on Jenkins.

To perform the following steps, you need to be logged in with a user with administrator profile. I assume the reader is already familiar with Jenkins so the instructions won’t be so detailed.

First of all we need to install the «SAML Plugin«.

auth0_8

Once the installation is ready go to «Manage Jenkins > Configure Global Security«. In the «Security Realm» pick «SAML 2.0» and in the «IdP Metadata» box paste the content of metadata file you saved on before.

Scroll down to the «Authorization» section and ensure the option «Logged-in users can do anything» is selected (authorization  is something we will work on later). Scroll down to the bottom of the page and click «Save«.

That’s all.  Close the browser [*] and the next time you try to log in you will be redirected to Auth0. Now every user enabled in your Auth0 account will be able to log into Jenkins.

In the next article I will explain how to configure authorization.

[*] at the moment of this writing there is bug in the SAML plugin that affect a logout feature https://issues.jenkins-ci.org/browse/JENKINS-37311.