Preparando Análisis y Diseño Orientado a Objetos en UNTreF

Por estos días me encuentro preparándome para dictar esta materia el primer cuatrimestre de este año. Si bien ya he dictado este materia en otras ocasiones esta vez tengo el desafío de dictarla solo, las veces anteriores la dicté en conjunto con @dfontde. En base al feedback obtenido de las dictadas anteriores y de algunas ideas que probando en otras materias, he decido hacer algunos ajustes a la dinámica de dictado de la materia.

El avance de internet, las redes sociales y la sobrecarga de información requieren que la dinámica de las materias se adapte, por ello más allá de la clase presencial semanal tendremos un modelo de aula extendida basado en un plataforma web. En base a esto se espera que los alumnos tengan una interacción constante con todo el grupo de estudio. Por cada hora de clase presencial se espera una dedicación de al menos una hora de trabajo fuera del aula. Dicho esto y pasando en limpio: los alumnos que cursen la materia deberán dedicar al menos 8 horas semanales todas las semanas. Dependiendo de cuanta maña pueda darse cada alumno, puede que la materia le insuma unas 6 horas semanales o puede que le insuma unas 10. El punto clave aquí es que a diferencia de otras materias no es posible llevar esta materia “haciendo la plancha” y estudiando a 30 horas seguidas los días previos a la evaluación. Se quiere una dedicación constante.

Respecto del mecanismo de evaluación no me gusta tomar examen escrito (aunque no lo descarto) y por ello estoy diseñando un mecanismo de evaluación basado en tareas semanales. La mayoría de estas tareas será de índole individual. Las tareas consistirán principalmente en lecturas con cuestionarios asociados y resolución de problemas de modelado y programación.

Sobre el TP final de algo3 (2015-1)

A fines de mayo lanzamos el TP final de Algo3. En el curso de los miércoles tenemos poco más de 30 alumnos repartidos en equipos de 3 integrantes, cada equipo con un docente tutor. En mi caso soy tutor de 4 equipos.

Este cuatrimestre el trabajo prácticos se llama AlgoCraft y como su nombre lo sugiere es una variante del clásico juego StarCraft.

Como de costumbre desde el comienzo del trabajo práctico configuré un Jenkins para que los alumnos pudieran hacer integración continua. Esto también me permite tener métricas de su trabajo. Este cuatrimestre incorporé PMD al conjunto de tareas ejecutadas en el proceso de integración continua. PMD es un herramienta que entra en la categoría de “Linter” y como tal, lo que hace es analizar el código fuente realizando un conjunto de verificaciones relacionadas al cumplimiento de estándares y buenas prácticas de programación del lenguaje en cuestión.

algo3_20151

Preparando mi visita a la Universidad Piloto (Colombia)

La semana próxima (11 de Mayo) estaré de visita en la Universidad Piloto de Colombia (Girardot) para participar del V Foro Internacional en el contexto de la celebración de los 30 años del Programa de Ingeniería en Sistemas en la región.

Una de las actividades que realizaré durante mi visita será una Clínica de Programación Orientada a Objetos. Es la primera vez que voy a realizar esta actividad como tal. La misma reúne varias cuestiones que son parte del temario de las materias que suelo dictar y que estarán incluida en mi próximo libro sobre el tema.

Quiero agradecer especialmente a Elkin Forero y a Luis Carlos Garzón por la invitación

clinica_oo

 

Experiencias de Enseñanza de POO en WISIT 2014

El sábado pasado estuve participando del WISIT 2014. Junto con Pablo Suárez presentamos el enfoque estamos utilizando en FIUBA para enseñar Programación Orientada a Objetos.

En nuestra sesión destacamos 4 puntos que consideramos centrales en nuestro enfoque:

  • Uso de técnicas de educación centrada en el alumno (Learner Centered Teaching)
  • Uso de herramientas informáticas: Campus Virtual de la universidad, Foros, Sistema de gestión de TPs (alfred) y videos explicativos.
  • Uso de dos lenguajes: Smalltalk y Java
  • Test-Driven: no solo enseñamos y usamos TDD, sino que también el desarrollo de los trabajos tiene algo de TDD pues las especificaciones de los que los alumnos deben resolver, la entregamos siempre en forma de pruebas.

Creemos que la presentación salió muy bien y notamos a la audiencia muy interesada. De hecho al finalizar nuestra exposición recibimos varias consultas y más de una persona manifestó intenciones de probar Alfred.

Para facilitar la sesión sesión utilizamos un Prezi que armó Pablo y que está disponible aquí. También armamos este póster que enviamos en su momento a los organizadores del evento como parte de nuestra propuesta de sesión.

Curiosamente hubo otras dos sesiones en las que también se presentaron enfoques de enseñanza de POO. Una de esas sesiones estuvo a cargo de Alfredo Sanzo y Lucas Spigariol quienes contaron su enfoque fuertemente basado en actividades de representación/actuación y en el uso de objetos físicos.

La otra sesión sobre POO estuvo presentada por Nico Passerini, Javi Fernández y Pablo Tesone, quienes mostraron Wollok, una herramienta basada en Eclipse y un lenguaje desarrollado por ellos mismo con el fin específico de enseñanza de POO.

Ambos enfoques me parecieron muy interesantes.

Celebro la iniciativa Uqbar Project de llevar adelante este evento. ¡Que se repita!

Probando excepciones

¿Como probar que un método lanza una excepción ante una determinada situación excepcional? Usando NUnit o JUnit 4, basta con escribir el método de prueba y poner una simple anotación indicando el tipo de excepción esperada.

@Test(expected = ExceptionEsperada.class)  
public void xxxxxx(){
      // ejecutamos la código que debiera lanzar la excepción
}

Pero no todos los xUnit brindan esta posibilidad, entonces debemos apelar a una estrategia similar a la siguiente.

public void test_xxxxxx(){
     try{
         // ejecutamos la código que debiera lanzar la excepción
         fail(); // si ejecución llega hasta esta línea, entonces significa que no se lanzó la excepción esperada y por ende la prueba ha fallado
      }
      catch(ExceptionEsperada ex){
          /* si estamos aqui, entonces se ha producido la excepción esperada y no es necesario
             hacer nada pues a menos que se indique que algo ha ido mail, se asume todo estuvo 
             bien */
       }
       catch(Exception ex){
          // si estamos aqui, es que la excepción que se ha lanzado, no es la esperada, por lo tanto la prueba ha fallado
          fail();
       }
    }

Asi de simple, espero les resulte útil.

Escribiendo pruebas unitarias para código legacy

Desde que volví a trabajar en consultoría este es uno de los temas que más me he encontrado. Sinceramente no me sorprende pues:

  • TDD y la automatización de pruebas, son dos temas que están en claro ascenso de popularidad
  • Casi toda la bibliografía de TDD parte de la base de la creación de aplicaciones desde cero
  • Pero en una porción importante de casos, la gente ya cuenta con una aplicación, la cual muchas veces no ha sido diseñada de forma de facilitar su prueba

Casualmente ayer me crucé con un caso extremo. Resulta que hace un par de semanas dicté un workshop de TDD. Ayer me contactó uno de los asistentes para hacer una consulta de como encarar un caso concreto: tenia que agregar una funcionalidad a la una clase existente. La clase en cuestión tenia más de 3000 líneas de código. Si si, leiste bien, son tres ceros después del tres, o sea, tres mil líneas de código. El problema de una clase tan grande, es que resulta dificil que sea cohesiva. Se supone que pasar ser cohesiva, una clase debe hacer UNA cosa y hacer bien. Con tantas líneas, es muy posible que dicha clase esté haciendo demasiadas cosas.

Pero el problema que motivaba la consulta no eran las 3000 líneas de código, sino el constructor de dicha clase. Resulta que el constructor además de recibir varios parámetros, instanciaba un componente para conectarse a la base de datos. Eso impedia realizar una prueba unitaria de la clase, pues el solo hecho de instancialar implicaba conectarse a la base. Tampoco no habia chances de mockear la conexión pues era instanciada directamente dentro del constructor. ¿que hacer entonces?

Lo primero que uno intentaria es hacer un refactoring de la clase, pero dado que no existian pruebas de la misma, cualquier modificación implicaba un gran riesgo. Luego de analizar varias alternativas llegamos a una solución de compromiso, que nos permitiria escribir tests unitarios: agregar un constructor sin parámetros, que tenga la lógica para lanzar un excepción si era invocado en un ambiente distinto al de desarrollo/test. De esta forma podriamos instancias la clase en forma aislada en un ambiente de test y  aseguramos que no sea instanciada de esta forma en caso de estar en un ambiente distinto.

 

Desafio de diseño: objetos inteligentes (resolución)

(continuación de Desafio de diseño: objetos inteligentes)

Hay varias formas de atacar este problema de la “testeabilidad”.

La primera opción que muchas veces viene a la mente, es hacer públicos los métodos privados y testearlos unitariamente. Si desde el punto de vista práctico esta opción puede parecer viable, cuando la miramos desde el punto de vista conceptual resulta incorrecta, pues dichos métodos son conceptualmente privados y no seria correcto cambiar su visibilidad para solo probar la clase. Si estuvieramos trabajando con C# Visual Studio nos ofrece una alternativa basada en reflexion para acceder a miembros privados de la clase, pero conceptualmente esto sigue siendo incorrecto.

Si pensamos el problema un poco más, nos daremos cuenta que puede que la clase tenga algunos problemillas de responsabilidades. Para ser más explícitos, tiene demasiadas responsabilidades: decidir si moverse y en caso positivo hacerlo, decidir si disparar y en caso positivo hacerlo, etc, etc. Bueno, si asumimos este diagnostico entonces hemos dado el primero paso: identificar el problema.

Repensemos la cuestión una vez más. Una clase que toma muchas decisiones (si X, si Y, si X, etc) y hace muchas cosas (X, Y, Z, etc). Cada una de esas cuetiones las hemos encapsulado en un método privado de cara a tener un código más legible. ¿y si fueramos un paso más allá? ¿Que tal si convertimos cada uno de ese métodos privados en una clase? De esta forma tenenemos una clase con la lógica de movimiento, otra clase con la lógica de disparo y asi sucesivamente. Así nuestro objeto inteligente tiene mucho menos código y su responsabilidad está limitada a coordinar “las estrategias” de movimiento, disparo, etc, etc. Al mismo tiempo cada estrategia puede ser testeada independientemente.

Bueno, este ha sido el primer desafio, próximamente vendrán algunos más.