Carta abierta a un Profesor de mi Universidad

Necesitaba poner un dibujo, y sólo encontré este. Créditos: http://jc-schools.net

Introducción

No sé si lo he mencionado, pero estoy involucrado en un movimiento en la Facultad que busca la redefinición de nuestro programa de Ingeniería de Sistemas y establecer tres programas diferenciados: Ingeniería de Sistemas, Sistemas de Información e Ingeniería de Software. Uno de nuestros colaboradores publicó el manifiesto en uno de los grupos Facebook de la facultad, y un profesor de reconocida trayectoría y prestigio acotó lo siguiente:

¿Qué es y qué ámbito de aplicación sostienen los que proponen desarrollar la Ingeniería de Software? Los que laboran haciendo software, que yo sepa, sólo hacen software aplicativo y de negocio. No software de base, ni software de desarrollo, ni software de desarrollo asistido, ni software instrumental, ni software complejo. Y el profesional de Sistemas de Información diseña, construye, dirige, supervisa y evalúa software aplicativo. ¿Para hacer software aplicativo se necesita una carrera profesional?
He hecho algunas correcciones de estilo. Publiqué la respuesta en el mismo grupo, pero dado que resulto un tanto extensa quisiera que quedara publicada en el Blog:

La Carta

Buenas noches Profesor, yo me considero un practioner de la Ingeniería de Software y con mucho gusto daré respuesta a sus inquietudes. Primero, déjeme contarle que llevo 7 años en el rubro y que a la fecha sólo he laborado en empresas con sede en el Perú, por lo que mi experiencia le a a ser útil para que se haga una idea del futuro de esta disciplina dentro de nuestro mercado.

Quisiera comentarle también que en el año 2010, mientras trabajaba para una Consultora costarricence con sede en Perú, junto a un equipo de Ingenieros peruanos le dimos mantenimiento al aplicativo CRM de una empresa líder del rubro de Buscadores de Internet: Se trataba del Software que le daba soporte a todas las operaciones de venta de esta compañía a nivel mundial, con equipos distribuidos a lo largo del planeta para darle soporte a este aplicativo vital. Mi equipo -de 7 personas- le daba soporte a el sólo Módulo de Administración, por lo que puede hacerse una idea de la complejidad de este Producto Software. Como ese caso podría darle al menos dos mas de mi experiencia personal, pero al punto que quiero llegar es que se produce software altamente complejo aquí en Perú, y la disciplina académica encargarda de lidiar con la complejidad de este tipo de sistemas -porque sí, son sistemas- es la Ingeniería de Software.

Por otro lado, creo que tiene un error conceptual respecto a lo que es Sistemas de Información, al menos desde la perspectiva de ACM-AIS. La disciplina de Sistemas de Información -que no es una disciplina de Ingeniería- tiene por objetivo ayudar a una compañía u organización a lograr sus objetivos mediante tecnologías de información. Le pongo un ejemplo con el que he estado familiarizado: Las empresas de telecomunicaciones tienen una área de Sistemas, así como tienen un área de Recursos Humanos o de Finanzas.  El área de Sistemas cuenta con profesionales de Sistemas de Información, que determinan que para abaratar costos -un objetivo organizacional- deberían tener un Portal de Autoatención, y son estos profesionales los que realizan una especificación de requisitos  inicial y un diseño con las principales funcionalidades. Asimismo, los profesionales de Sistemas de Información determinan que lo mejor para el negocio -ellos siempre piensan en la empresa- es tercerizar este desarrollo, por lo que le envían el requerimiento a una Consultora, digamos, de la India. El personal de la Consultora que diseña, construye, dirige, supervisa y evalúa la construcción de este aplicativo son profesionales en  Ingeniería de Software y no de Sistemas de Información. La disciplina de Sistemas de Información está orientada a la organización y empresa, por lo que típicamente se encuentra es Escuelas de Negocios y no es común que sean los principales responsables de la consecución de un Proyecto Software.

Finalmente, no porque sea un “software aplicativo” deja de ser complejo o de importancia. Por ejemplo, en una empresa de telecomunicaciones americana hemos visto un Software de Tickets de Atención -un dominio aparentemente sencillo- que está desplegado en dos Datacenters en distintas partes del globo, con versión Escritorio, Web y  una de Respaldo que es mantenido por equipos de desarrollo desplegados en Estados Unidos, Argentina, India y Perú. Si este aplicativo deja de funcionar, la empresa pierde millones, y la Ingeniería de Software es la que garantiza que todo funciona como debe: Temas como Gestión de Proyectos, Gestión de la Configuración, Calidad de Software y Arquitectura y Diseño son nuestro día a día. Y esto pasa acá en Perú, y muchos egresados de la UNI ya están desempeñándose en ese rubro: Los conozco y sé que son muchos.


Quisiera terminar respondiendo su última pregunta. La ACM Computing Curricula establece que sí existe un Programa de Pregrado orientado a la construcción de Software Complejo -sin importar si es aplicativo, software base u otra tipología- y ese Programa es Ingeniería de Software. En ese mismo documento se establece un profesional en Ingeniería de Software puede ser un licenciado en Ciencias de la Computación que ha tenido cursos de Ingeniería de Software en su Plan de Estudios o un Bachiller en Ingeniería de Software. Creo firmemente la facultad -y la UNI- deben optar por la segunda vía, en concordancia con nuestra tradición como Escuela de Ingenieros.

Quiero hacer Computación y no sé qué estudiar

Ellos estudian Computación. Créditos: University of Toronto

Cómo he contado en otro post, allá por el año 2001 había decidido que hacer Software era mi vocación y debía obtener un grado universitario que me permitiera hacerlo. En caso de quedarme en mi natal Trujillo, hubiera podido acceder a los siguientes programas:
  • Informática, en la Universidad Nacional de Trujillo.
  • Ingeniería de Sistemas, en la Universidad de Trujillo o en la Universidad César Vallejo.
  • Ingeniería de Computación y Sistemas, en la Universidad Privada Antenor Orrego.
  • Ingeniería de Sistemas Computacionales, en la Universidad Privada del Norte.
Como ven, bastante nombres pomposos y -según iba escuchando en las ferias vocacionales- casi todas estas carreras de nombres disímiles tenían contenidos curriculares similares. Ahora, cuando comencé a evaluar las universidades limeñas -causándole una pena a mi madre- me encontré con las siguientes opciones:
  • Ingeniería de Sistemas, en la Universidad Nacional de Ingeniería o en la Universidad Nacional Mayor de San Marcos.
  • Ingeniería Informática en la Pontificia Universidad Católica del Perú.
Para mis ojos ingenuos de postulante tenía un listado largo de nombres que a la larga eran lo mismo.  Como también he narrado en otro Post, al final opté por seguir Ingeniería de Sistemas en la UNI; seguí el programa disciplinadamente y cuando me disponía a buscar prácticas profesionales noté lo siguiente:
  • Las empresas necesitaban Ingenieros de Sistemas para desempeñarse como Analistas de Negocios, determinando las necesidades tecnológicas de las empresas.
  • Las empresas necesitaban Ingenieros de Sistemas para administrar Servidores de Bases de Datos, Servidores Web e incluso infraestructura de redes.
  • Las empresas requerían  de Ingenieros de Sistemas para construir Software, ya sea Programadores para construir el Software, Testers para probarlo o Gerentes de Proyecto para administrar el proceso.
El haberme graduado de Ingeniero de Sistemas en la UNI me ha permitido hacer carrera en el mundo del desarrollo del Software. Sin embargo, muchos de mis compañeros han optado por rumbos distintos -incluso tengo dos compañeros que han incursionado en el Marketing- por lo que aparentemente ser Ingeniero de Sistemas en el Perú te da la posibilidad de desempeñarse en cualquier rubro. Y no creo que esto sea positivo para la profesión.

Este desorden en lo referente a programas, currículas y ámbito profesional es un fenómeno eminente latinoamericano. De primera mano sé que esto también pasa en Colombia. Sin embargo naciones que están más alejadas del tercer mundo -como Brasil- tienen la formación en Computación normada, con contenidos definidos y ámbitos de ejercicio plenamente determinados. El objetivo de este Post, es mostrarles cómo es la formación en Computación de clase mundial, para reconocer nuestra problemática y empezar a trabajar en corregirla.

Primero, empecemos por quien pone las reglas en lo referente a Computación: las sociedades profesionales más importantes son las IEEE Computer Society y la Association for Computing Machinery. Estas dos junto a sociedades adicionales se reúnen periódicamente y emiten un documento denominado Computing Curricula, que contiene los programas de Computación actualmente disponibles y con estándares curriculares definidos (que no les sorprenda no encontrar a la Ingeniería de Sistemas). En la versión 2005 de este documento, comienzan lógicamente definiendo Computación:
Computación es cualquier actividad -orientada a objetivos-  que requiera de computadoras, se benefecien con el uso de computadoras o busque crear computadoras. (Traducción libre)
Aquí sería bueno dejar en claro que Computación es a efectos prácticos equivalente a Informática, y utilizaremos ese término a lo largo de este post y de todo el Blog. Como ven, es una visión bastante amplia, y por eso en el reporte se señala que es virtualmente imposible obtener maestría en todas sus disciplinas, razón por la cuál se ha dividido en cinco programas, cada uno con propósito y contenidos específicos:

Ingeniería de Computación

Este programa emergió de los programas de Ingeniería Eléctrica, y se encarga del diseño y construcción de Computadoras o sistemas basados en Computadoras. Para esto, la gente de Ingeniería de Computación utiliza prácticas de Ingeniería Eléctrica y Matemáticas, teniendo más énfasis en Hardware que en el Software.

Un Ingeniero en Computación está en capacidad de diseñar y construir teléfonos celulares, reproductores de música digitales o cámaras de video digitales. No creo que haya un programa universitario en el Perú orientado hacia este perfil.

Ciencia de la Computación

Esta es una disciplina de computación de amplio alcance. La Computing Curricula le define tres campos de acción: el diseño e implementación de software, el descubrimiento de nuevos usos para las Computadoras (por ejemplo, el desarrollo de Internet) y el desarrollo de formas efectivas de resolución de problemas de computación (como la forma más eficiente de almacenar la información en una Base de Datos).

Esta es la disciplina de Computación más difundida a nivel mundial, y es bastante común que -por ejemplo- empresas de alta tecnología como Google, Microsoft o Facebook están en demanda ese tipo de profesionales. Actualmente en el país están emergiendo programas de Ciencia de la Computación, ahora me viene a la mente la UNI y la UPC en Lima y la UNSA y la UCSP en Arequipa.

Sistemas de Información

Este es otro programa antiguo y popular, centrado en integrar tecnologías de información con los procesos de negocio de modo que los negocios y las empresas satisfagan sus necesidades de información y logren sus objetivos. Pueden inferir que esta disciplina sirve de puente entre la comunidad técnica y la comunidad de administración en una organización.

Típicamente, los programas de Sistemas de Información se ubican dentro de Escuelas de Negocios y el plan de estudios contiene cursos tanto de negocios como de Computación. Es una disciplina bastante necesaria y practicada en nuestro medio, puedo decir que varios compañeros de Universidad se desempeñan en ese rubro. Además, en el país ya tenemos dos programas acreditados, en la UPC y la USMP.

Tecnologías de Información

Es el complemento de Sistemas de Información en lo referente a Computación para negocios, y se ocupa de satisfacer las necesidades de tecnología para todo tipo de organización. Mientras que Sistemas de Información se centraba en la información, los profesionales de tecnologías de información hacen énfasis en la tecnología en sí misma por lo que entre sus responsabilidades está la administración de redes de computadores, de sistemas de correo electrónico y de servidores Web.

A pesar de ser una disciplina tan necesaria, y en la que se desempeña una gran cantidad de egresados de Ingeniería de Sistemas en el Perú, no sé de ningún programa universitario que esté tomando esa orientación. Tal vez los Institutos deberían buscar la acreditación en este rubro.

Ingeniería de Software

Este programa emergió de los programas de Ciencia de la Computación, ante la creciente complejidad e importancia del Software. La Ingeniería de Software se encarga del desarrollo y mantenimiento de software de manera confiable y eficiente, de modo que el software sea de desarrollo y mantenimiento asequibles y satisfaga todos los requerimientos definidos por sus usuarios.  La Ingeniería de Software es una de las dos disciplinas de Ingeniería dentro de la Computing Curricula, e incluso en ABET es acreditada por el comité de Ingeniería y no por el de Computación. La formación de un Ingeniero de Software incluye Matemáticas, Ciencia de la Computación y prácticas de Ingeniería.

Internacionalmente, uno puede formarse en Ingeniería de Software llevando cursos como parte de un programa de Ciencia de la Computación o llevando un programa propio de Ingeniería de Software. Muchos Ingenieros de Sistemas peruanos -especialmente los que trabajan en consultoras- se desempeñan en este rubro y están llegando empresas del extranjero buscando gente de ese perfil. A la fecha, tenemos dos programas acreditados por ABET -la UPC y la URP- y están apareciendo nuevos programas en el País.

Ahora todo está bastante más ordenado -al menos más que en el 2001- y varias universidades del país se están dando cuenta de la necesidad de alinearse a estos estándares y no trabajar de espaldas al mundo. Sólo espero que mi Facultad también lo haga.

Programar es fácil


Programar en Java es tan sencillo que puedes aprenderlo en sólo un  día. Puedes comprar el libro aquí.

Si es que siguen el Blog deben saber que soy un egresado de Ingeniería de Sistemas de la UNI, que esta facultad y este Programa han proveído de profesionales en Computación al país por más de 30 años y que como parte del proceso de acreditación han decidido adoptar a la Ingeniería de Sistemas como el programa a acreditar y dejar de lado la Computación. Y si es que siguen el Blog, sabrán también que me opongo rotundamente a esa decisión y que estoy en franca y solitaria campaña porque mi facultad adopte la identidad que ya tiene, por más contradictorio que esto suene. Como parte de esta “cruzada personal” me he visto envuelto una serie de discusiones en Facebook, y en una de esas discusiones me sorprendió el siguiente comentario:
Con respecto a la Ingeniería de Software no dudo que seguirá cambiando el mundo, pero éste no ha sido el principal motor sino saber usar la información y/o el avance de las TIC’s. Ejemplos por doquier ¿Facebook no?. La creación de Facebook va más allá de los procesos y herramientas utilizadas por esta disciplina, pero fue indispensable sin duda.
Algunas correcciones de estilo son mías. Si bien aún se presenta diplomático, percibí entre líneas cierto desdén hacia lo relativo a Programación: Incluso pone a esta disciplina en segundo plano en un producto eminentemente tecnológico como Facebook. La respuesta en verdad me pareció increíble, y le repliqué que una gran de emprendimientos tecnológicos -léase Google, Amazon, Microsoft- tienen como líderes a gente con formación en Computación y que estar educado en esta disciplina es vital si es que se quiere innovar y tener éxito en el mercado tecnológico. Y fue aquí que obtuve esta réplica más sorprendente aún:
Le preguntaría a los desarrolladores de aplicaciones que más necesitan saber de informática o computación para crear una aplicación análoga a Facebook , Twitter, LinkedIn, etc (sic). Jóvenes con poca noción en informática - con los frameworks, creados gracias a la Informática y computación, que facilitan la creación de aplicaciones - se hacen millonarios de la noche a la mañana.
Corregí algo de sintaxis para hacerlo entendible. Aquí se dejó de diplomacia y creo entender -corríjanme si no es cierto- que tiene dos ideas bastante arraigadas respecto a la programación:
  • Programar es fácil, cualquier persona con nociones básicas puede producir aplicaciones de clase mundial como Facebook o Twitter. 
  • Asimismo, con ese conocimiento tan básico le basta y le sobra para tener éxito y hacer millones en un mercado tan competitivo como Internet. 
En su defensa, mi interlocutor afirma -no sin cierto orgullo- que no se dedica a la Ingeniería de Software sino “resuelve problemas de Sistemas en organizaciones” así que esos puntos de vista tan controversiales pueden ser producto de desconocimiento. Como he dicho en ocasiones anteriores, existe cierta aversión de ciertos docentes para la Ingeniería de Software en mi facultad y esta opinión puede haber llegado al estudiantado. Es por esto, que en este post quiero defender dos ideas:

La construcción de Software es compleja

Algo que nos parece tan evidente para los que nos dedicamos a la programación no lo es tanto para el resto, incluso para gente que trabaja junto a nosotros como Jefes de Proyecto o Analistas. En un brillante artículo, Peter Norvig estima que te puede tomar 10 años el dominar el arte de construir software, como se demuestra experimentalmente con una amplia cantidad de disciplinas.

Es por eso que me sorprende ver en el mercado local ver a colegas ostentando el título de Arquitecto sin haber llegado a esta cuota mínima de experiencia: Eso no ocurre en otras latitudes. Norvig también brinda una receta para convertirse en un programador experto, de la que mencionaré algunos puntos que me parecieron importantes:
  • Se requiere primero programar, y programar mucho. No basta con leer tutoriales en la Web o libros donde dicen enseñarte a programar en 24 horas. 
  • Ir a la Universidad (opcional) 
  • Construir programas junto a otros programadores. Esto incluye ser el mejor para aprender habilidades de liderazgo o ser de los peores para aprender de los mejores. 
  • Mantener programas construidos por otros programadores, comprender código ajeno y diseñar programas de modo que sean de fácil entendimiento por otros programadores. 
  • Conocer a las computadoras, dado que es el entorno donde se ejecutan los programas. Esto no es conocer Windows, sino saber cómo es que nuestro programa será ejecutado en el Procesador, el manejo de caché y políticas de paginación a bajo nivel. 
Norvig consigna algunos ítems más, con las cuáles llegaremos a dominar nuestro oficio luego de dedicarle 10 años. Y mientras aprendemos iremos seguramente produciremos mucho software mediocre pero que se hará mejor cada día que pase: Pensar que podemos construir una solución escalable y de clase mundial con sólo algunos años de entrenamiento es bastante ingenuo.

Contar con talento técnico es clave para toda Startup

Hace unos días estuvo en Lima Antoinette del Río, que es gerente de juguetes y juegos en Amazon. Al ser consultada sobre los déficits en innovación que tiene el Perú, dió esta lapidaria respuesta:
Principalmente pasar de la creatividad a la acción. Los peruanos siempre hablamos de nuestra creatividad, de cómo siempre tenemos solución para todo. Trato de seguir de cerca la movida de los start-ups en Perú y veo algunos esfuerzos pero, honestamente, siento que la ejecución aún está débil. En tecnología, no hay cupo para fallar, si alguna vez te llama la atención una página, entras, no carga o lo que ves no es lo que esperas y listo, no vuelves, hay un solo momento de la verdad. Mi esperanza está en que las carreras técnicas cobren valor, y que pronto toda esa creatividad pueda concretarse en start-ups inteligentes y de calidad que realmente mejoren la vida de la gente.
Lamentablemente en nuestro medio esto no es evidente, mientras que en Estados Unidos el Santo Grial el emprendimiento es encontrar al “Technical Cofounder”, aquella persona que esté en capacidad de transformar una idea en un producto.

Vengo de leer un artículo en Forbes de Stella Fayman, del que quiero rescatar algunos puntos:
  • Ella coincide con Norvig es que la Programación es un arte que lleva años aprender, así que esta parte no debe ser subestimada, es decir, no creas que puedes construir un producto de valor a punta de tutoriales. 
  • Contratar programadores es difícil, y esto también se está dando aquí en Perú. Han venido varias empresas americanas y otras tantas transnacionales que están distorsionando el mercado -a beneficio de los programadores- y ahora ser programador está mejor pagado. 
  • Hay que tener cuidado con utilizar outsourcing, es decir, mandar el trabajo a la india. El construir un producto valioso requiere de interacción con tu equipo y esto se hace bastante difícil con un equipo offshore. 
Y para terminar, una cita que está en el mismo artículo:
El desarrollo de software es un arte, no es un commodity. Trátalo como tal, y tendrás éxito. (Traducción libre)

Ingeniería de Sistemas, cosa tan rara

Un meme, algo feo pero muy cierto. (Créditos: http://aynomanches.blogspot.com)


Nunca me ha sido fácil conseguir amigos, y mucho menos conseguir amigas: Soy víctima de una timidez crónica que se agudiza al estar cerca del sexo opuesto. Ahora a mis 28 años ya es menos evidente, pero cuando llegué a Lima a mis 17 años la tenía a flor de piel. El 2002 llegué a Trujillo a la casa de mi tía -y mis cinco primas- con el firme objetivo de convertirme en un estudiante de la UNI y también con unas habilidades sociales casi inexistentes. Aún el día de hoy, mis primas se burlan de aquellos días de postulante, cuando pasaba por la sala con la mochila llena de libros y las mejillas al rojo vivo cuando las encontraba junto a sus amigas y me veía forzado a saludar y por ende a socializar.

En Agosto de ese mismo año ingresé a la UNI y mi reciente estatus de estudiante de Ingeniería de Sistemas me había convertido de repente en Soporte Técnico de la casa: Esto incluía a mis tías, mis primas y por extensión a sus amigas. Muchas fueron las veces que tocaron a mi puerta alguna prima acompañada de una asustada amiga, que necesitaba con desesperación que arreglara la Computadora de la casa antes que lleguen sus papás. Fue así que mi reducido círculo de amigas -que inicialmente sólo incluía a mis cinco primas- se fue expandiendo poco a poco, y mi timidez se iba diluyendo con ello (aunque nunca del todo).

Y déjenme decirles que era bastante bueno, en gran medida a que junto a mis hermanos estropeamos la computadora de la casa de Trujillo una infinidad de veces y siempre era yo el que tenía que arreglar el estropicio para evitar la ira de papá. Fue ese entrenamiento el que me permitía reparar una Computadora y no la educación que me estaba impartiendo la Universidad. Sin embargo, para mis primas y sus amigas mis habilidades venían de que me estaba formando como Ingeniero de Sistemas, y que lo estaba haciendo en la UNI.

Pues resulta que Ingeniería de Sistemas no tiene nada que ver con darle soporte técnico a computadores, muy a pesar de lo que piensa mi familia y una cantidad importante de la población. Según INCOSE, referente mundial en Ingeniería de Sistemas, un ingeniero de Sistemas se encarga de lo siguiente:

“Un Ingeniero de Sistemas líder debe dirigir a ingenieros de las más diversas ramas, e incluso a médicos, abogados y psicólogos de modo que satisfagan los requerimientos del proyecto sin importar la naturaleza de estos. Un profesional en Ingeniería de Sistemas es el pegamento que mantiene al proyecto unido” (Tradución libre)
La labor del Ingeniero de Sistema está estrechamente vinculada al manejo de la complejidad, por lo que las principales instituciones que promueven -léase el Departamento de Defensa de los Estados Unidos o la NASA- llevan a cabo proyectos de magnitud y costo significativo que requieren de la convergencia de especialistas de las más diversas ramas. Por ejemplo, el proyecto Apollo requirió de Ingenieros Mecánicos, Ingenieros Eléctricos e Ingenieros de Software trabajando coordinadamente para lograr el objetivo de llevar al hombre a la Luna. Es ahí donde la Ingeniería de Sistemas se hace necesaria, y es por eso que los Ingenieros de Sistemas son uno de los profesionales más reconocidos y mejor pagados a nivel mundial.

Asimismo, la Ingeniería de Sistemas es rara vez practicada por Ingenieros de Sistemas. Bueno, para expresarme mejor, por gente que tenga un Bachillerato en Ingeniería de Sistemas. Los profesionales en Ingeniería de Sistemas en su gran mayoría tienen formación en alguna otra Ingeniería y han hecho un Postgrado en Ingeniería de Sistemas. Por ejemplo, les presento a Ralf Hartmann, director de estrategia de INCOSE y Vice-Presidente de Estrategia en Astrium, una fabricante de equipos y vehículos espaciales. Ralph es Ingeniero Eléctrico de la Universidad de Karlsruhe, y como él, muchos practicantes de la Ingeniería de Sistemas vienen desde otras disciplinas.

Esto se debe en parte a que existen corrientes de pensamiento que postulan que para poder tener una visión amplia de múltiples ramas de la Ingeniería primero se debe tener una visión profunda de alguna de sus disciplinas. A la fecha, los programas de Pregrado en Ingeniería de Sistemas son muy pocos habiendo por el contrario una gran oferta de programas de posgrado, cosa que no ocurre con el resto de disciplinas de la Ingeniería. Además, no existe en la actualidad una estructura curricular de referencia para programas de pregrado existiendo por el contrario ya publicada una para ofertas de posgrado.

Como ven, la Ingeniería de Sistemas tiene poca relación con formatear computadoras e instalar Windows; cosa que he venido evangelizando en mi familia y con cualquier persona que quiera escucharme. Fue esa Ingeniería de Sistemas la que se creó en la UNI el año 1974, bajo la dirección del Ingeniero Augusto Mellado, siendo el primer programa de Ingeniería de Sistemas del país. Si ustedes ven la currícula de Ingeniería de Sistemas de aquel entonces, verían que si bien tiene algunos cursos de computación explora y abarca las más diversas áreas de la Ingeniería. Un Ingeniero de Sistemas de aquellos años tenía formación en resistencia de materiales, termodinámica y mecánica del cuerpo rígido, por mencionar algunos de los nombres que más me asustaron.

Sin embargo, y tal vez debido a mi limitado círculo social, actualmente no conozco a ningún Ingeniero de Sistemas que esté ejerciendo la disciplina que pone transbordadores en el espacio o cazas de combate en los cielos. Yo actualmente hago Ingeniería de Software, como muchos de compañeros, mientras que otro buen grupo está actualmente dedicado a Sistemas de Información. Como he contado anteriormente, yo ingresé a la UNI con la intención de hacer Computación, mis padres esperaban que hiciera Computación y cuando terminé el programa descubrí que el mercado esperaba que como Ingeniero de Sistemas hiciera Computación, porque la gente la UNI es reconocida en ese campo.

En el Informe de Evaluación Curricular, elaboran una hipótesis sobre esta confusión que ya lleva más de 30 años. En el informe se señala que en los años 80, cuando estaban saliendo las primeras promociones de Ingenieros de Sistemas, los egresados incursionaron en el ámbito profesional y nunca regresaron al ámbito académico. Es decir, los especialistas en Ingeniería de Sistemas no retornaron a las aulas y los espacios académicos fueron cubiertos por gente de Computación que fueron degenerando a la profesión en lo que ahora es.

Si bien ese escenario puede ser posible, yo tengo otra hipótesis: La demanda de Ingenieros de Sistemas en el Perú es ínfima, mientras que la demanda de profesionales en computación fue siempre creciente desde los años 70. Y cómo en aquellos años no existían profesionales ni programas de Computación suficientes -tenemos a UNMSM con Computación Científica y la PUCP con Ingeniería Informática- esta demanda fue suplida por los Ingenieros de Sistemas, que bien o mal por lo holístico de su formación tenían nociones de Computación.

Y ahora la Computación florece en el Perú: tenemos programas de Ciencias de la Computación, Sistemas de Información e Ingeniería de Software en el país; las grandes casas de Software del mundo están viniendo al Perú para quedarse y en los Concursos de Programación nuestros connacionales cada vez obtienen más galardones. Todo esto gracias a generaciones y generaciones de Ingenieros de Sistemas -y hay que decirlo, también otros profesionales- que descubrieron en la Computación una pasión y una forma de vida.

Actualmente la UNI y mi facultad están en pleno proceso de acreditación, y luego de un intenso debate han optado por acreditarse como Ingeniería de Sistemas en lugar de optar por un programa de Computación. Me preocupa enormemente que esto signifique dejar de lado la Computación y tirar por la borda años de trabajo y prestigio y adoptar un programa que actualmente no tiene demanda en el mercado lo que puede afectar la empleabilidad de nuestros graduados. Se está planteando que los egresados vayan a desempeñarse en roles de gestión de proyectos o reorganización de procesos, que actualmente son dominio de profesiones más especializadas -como Ingeniería Industrial- donde habría que ver que tan mal o bien el mercado reciba a estos jóvenes profesionales.

Para mí, esta decisión es un error y espero tener éxito en mi intento de rectificación. O en su defecto, espero estar equivocado que sería muy triste que un programa con tanta historia y prestigio como el de Ingeniería de Sistemas fracase.

La UNI, la Ingenieria de Sistemas y yo

Chicos UNI. Entre ellos, estoy yo (Créditos: Ray Mendoza)


Allá por el año 2001 yo tenía 17 años y dos grandes preocupaciones en la vida: A quién llevar a la fiesta de promoción y qué hacer con mi vida luego de terminar el colegio. Ese año fue un gran año porque ambas cosas salieron mejor de lo que esperaba: el 2001 conseguí a mi primera enamorada y descubrí que mi vocación era ganarme la vida haciendo software.

Lamentablemente, estas aparentes soluciones trajeron más problemas de los que solucionaron: Mi enamorada de estreno era el interés romántico de uno de mis mejores amigos y tenía que escoger la universidad que me acogería por 5 años. Mi madre -y mi enamorada- querían que estudie en Trujillo, mientras que mi padre quería que me fuera a Lima. Además, el bolsillo de mi padre quería que fuera una universidad pública, con lo que varias de mis opciones iniciales fueron desechadas rápidamente.

Me encontraba en medio de esas tribulaciones, cuando llegó a casa el tío Miguel. El tío Miguel es un familiar muy querido, y lo recordaba siempre en su taller de mecánica, rodeado de máquinas enormes y guiando con temple a sus operarios: Siempre que mis hermanos y yo íbamos al taller nos hacía pasar a su oficina, que estaba llena de planos pegados en las paredes y revistas en inglés desparramadas en su escritorio. Las visitas eran siempre agradables porque nos permitía jugar con su regla de cálculo y además hacía trucos de magia que se tornaban en ciencia luego de su explicación.

En aquella visita, el tío Miguel me dejó dos cosas: Un libro de Diseño de Ingeniería y una cita de Theodore von Karman: “Los científicos estudian el mundo tal como es, los ingenieros crean el mundo que nunca ha sido”. El tío Miguel tenía en la pared de su oficina -en un lugar privilegiado- un título de Ingeniero Mecánico de la Universidad Nacional de Ingeniería: luego de esa visita había decidido que yo también quería uno igual y que sería un Ingeniero de Sistemas de la Universidad Nacional de Ingeniería.

Una serie de fracasos y mucha perseverancia fueron los que me llevaron a ingresar a la Universidad. Esos primeros días fueron maravillosos, donde caí en la cuenta que era un privilegio formar parte de un grupo humano con tanto talento y donde muchos compañeros compartían mi pasión por el software. Puse todas mis esperanzas en el curso de Introducción a Ingeniería de Sistemas esperando que me dijeran cómo esta disciplina me permitiría hacer software, sólo para que el profesor las diluya al hacernos ver que la Ingeniería de Sistemas no es una disciplina de Computación, sino un enfoque holístico hacia la resolución de problemas complejos.

Y en nombre de ese enfoque holístico mis compañeros y yo hemos visitado las más diversas disciplinas: tomamos un curso de algoritmos pero no somos gente de computación, estudiamos Microeconomía y Macroeconomía sin ser Economistas, y vimos contabilidad por tres ciclos sin ser contadores. Además, ciclo tras ciclo al menos un profesor nos venía con la cantaleta que la gente que se dedica a hacer software está condenada a la monotonía y a la mediocridad.

Pero yo estaba en la UNI por dos motivos principales: Quería ser Ingeniero -quería crear por medio de la ciencia- y quería hacer software, solucionar problemas mediante las computadoras. A pesar de lo descrito en el párrafo anterior, la UNI me dio dos espacios donde ese deseo podía germinar: el Capítulo Estudiantil de la IEEE Computer Society y el Programa de Ayudantía del Centro de Cómputo. Fue en esos dos grupos donde descubrí que la Ingeniería de Software es una disciplina reconocida en el mundo y que día a día lo está cambiando, que el poder programar es un talento raro y altamente valorado por el mercado y que con mi vocación podía hacer grandes cosas, por el país y por mi.

Llegado el momento de buscar trabajo, descubrí que no estaba sólo en mi vocación. La comunidad Programación-FIIS agrupa a una gran cantidad de egresados de la facultad que ven en la Programación una forma de vida. Fue gracias a ellos que pude desempeñarme como Programador, para caer luego en la cuenta que los egresados de la Universidad -y la facultad- somos altamente apreciados por el mercado y se reconoce nuestra calidad aún por encima de programas propios de Informática o Computación.

Hace ya más de 6 años que me desempeño profesionalmente como Ingeniero de Software y ha sido una ruta bastante gratificante. La profesión me ha permitido interactuar con gente de diversos lugares del planeta, y en empresas como Google he visto de primera mano los niveles de sofisticación que la Ingeniería de Software puede tener y su nivel de impacto en la vida de mucha gente. Fue por eso que me llenó de entusiasmo que la facultad haya intentado acreditarse como Ingeniería de Software y me llenó de tristeza ver la oposición generalizada a esta propuesta, con argumentos principalmente orientados hacia el desmedro de una disciplina que literalmente está transformando la forma en que vivimos.

Personalmente no creo que la Ingeniería de Sistemas sea nociva, es más, la considero necesaria. Pero cuestiono seriamente que se busque enseñar desde programas de pregrado por dos razones: Primero, los programas de pregrado en Ingeniería de Sistemas propiamente dicha son muy raros en el mundo, al nivel que no existe una currícula de referencia para este tipo de ofertas educativas; y segundo, veo muy difícil que jóvenes egresados puedan poner en práctica esta disciplina y que el mercado laboral actualmente tenga necesidad de estos profesionales. Una búsqueda rápida en computrabajo.com pondrá en evidencia que los especialistas en dinámica de sistemas o metodología de sistemas blandos son raramente requeridos.

La realidad es que los egresados de Ingeniería de Sistemas mayoritariamente irán a desempeñarse en dos disciplinas: O Sistemas de Información o Ingeniería de Software. Y lamentablemente, nuestros jóvenes egresados estarán en abierta desventaja contra los egresados de otras universidad que sí les ofrecieron a los estudiantes un cuerpo de conocimiento definido. Recuerdo que en mi primer trabajo como practicante en Ingeniería de Software, mi mentor era otro practicante egresado de otra universidad debido a que su currícula le había dado más experiencia en programación que yo.

Sí me preguntan cuál es el logro del que me siento más orgulloso, diría sin titubear que ingresar la UNI: muchos jóvenes peruanos quieren tener ese privilegio y somos muy pocos lo que lo hemos logrado. En segundo lugar, sería haber egresado de la UNI: los Ingenieros más talentosos que he conocido son de esa casa de estudios y nada se compara a la satisfacción de llamar “colega” al tío Miguel. Pero también me gustaría que la Universidad, y principalmente mi facultad, sean más receptivas con aquellos adolescentes que, cómo yo en su momento, llegan llenos de sueños sobre Software y Computadoras. Tengo fé que esta situación cambiará y pienso hacer todo lo que está en mis manos para que esto suceda.

Orgullo de artesano (de Software)


"The whole problem with modern times is that there's no pride in craftsmanship. (...) Everyone's a slave of efficiency! No time for aesthetics! No love of things for their own sake!" -  Calvin & Hobbes de Watterson.

La frase que abre el post la encontré hoy en un tira de Calvin & Hobbes, y podría ser traducida como "El problema de estos tiempos es que se ha perdido el orgullo del artesano. ¡ Todos son esclavos de la eficiencia! ¡Ya no hay tiempo para la estética! No hay amor  para las cosas en sí mismas". Mientras todos los niños hacen bolas de nieve acumulándola entre las manos, Calvin se asegura que las suyas tengan la cantidad óptima de humedad y un diseño aerodinámico.

¿No creen que la frase de Calvin aplica también al mundo del desarrollo de software? Al Jefe de proyecto sólo le importa que el software esté listo a tiempo, al usuario sólo le preocupa que el software funcione y a los ingenieros sólo les interesa cobrar puntualmente. Eficiencia y productividad son los valores máximos de la industria de software hoy.

Creo que el software y su código fuente tienen un componente estético. Sí, yo creo que los programas pueden ser "bonitos".  Revisar código fuente ordenado, indentado, con nombres de variables y métodos adecuados puede llegar a emocionarme tanto como un buen cuento o una canción. Los programas con tipos desacoplados, capas definidas, estructuras de herencia elegantes y aplicación inteligente de patrones de diseño a  mi parecer pueden llegar al estatus de obras de arte.

Pero parece que la mayoría de ingenieros han perdido esos valores. Simplemente se limitan a digitar el código que haga que el software cumpla con los requerimientos del usuario. Si el código fuente es un caos lleno de nombres de variables initeligibles, clases de cientos de líneas de código y lógica de negocio dispersa pues es una lástima, pero no es su problema. Ya los ingenieros de mantenimiento arreglarán eso después del pase a producción.

Cuando codifico, trato que lo que estoy viendo en el monitor sea agradable para mi y para el próximo ingeniero que lo tendrá cargo. Trato siempre de aplicar las pocas técnicas que conozco para que el programa que estoy construyendo sea funcional, eficiente y , si se puede, elegante. Puede llevarme un poco más de tiempo y esfuerzo, pero creo que como profesional le debo calidad a la empresa que me ha contratado y a mis colegas que tendrán que lidiar con lo que he hecho.

Hace poco me enteré del movimiento de Artesanía de Software, que propone entre otras cosas considerar al proceso de desarrollo de software como un arte en sí mismo. El movimiento tiene un manifiesto con unos valores que a mi parecer todos los programadores deberíamos adoptar:


  • No sólo hacemos software que funciona, sino software bien hecho
  • No sólo respondemos al cambio, sino agregamos valor constantemente.
  • No sólo somos individuos e interactuamos, sino somos una comunidad de profesionales.
  • No sólo colaboramos con nuestros clientes, sino establecemos una sociedad productiva con ellos.
*Traducción libre

En la historieta, las bolas de nieve aerodinámicas de Calvin toman demasiado tiempo en hacerse. Para cuando tiene una lista, Susy ya lo ha acribillado con decenes de bolas de nieve convencionales. Mientras Calvin yace acribillado sobre la nieve, Hobbes sólo atina a decir:

"Artists always suffer" (Los artistas siempre sufren)

Cohesión y el principio de responsabilidad única

Imaginemos que nuestro siempre creativo usuario nos solicita un proceso que genere cierto reporte Excel con información de base de datos y se lo coloquemos en un servidor FTP para que lo pueda descargar luego. Dado que -para variar- quiere el reporte para ayer, construimos la siguiente solución apresurada:

Diseño improvisado
Terminamos, el usuario lo prueba, mira que es bueno y nos felicita. 

Pasan unos días y el mismo usuario nos pide una aplicación para que pueda colocar algunos documentos PDF en el mismo  servidor FTP. ¿Por qué no utilizamos a nuestra clase AdministradorDeReportes junto a su método enviarArchivoFTP()? Podríamos hacerlo, pero nuestra clase para poder ser compilada depende también de POI y de JDBC lo que le daría una carga extra de 5 megas a nuestro sencilla aplicación para PDF's. Esto pone en evidencia que nuestro diseño original tiene algunos problemitas.

La cuestión es que nuestra clase AdministradorDeReportes tiene la responsabilidad de conectarse a base de datos, de generar un archivo Excel con esta data y de colocar el archivo en el servidor FTP; y si uno quiere reutilizar este componente pues no le queda otra que adquirir el paquete completo de responsabilidades que esta clase posee. ¿Y si queremos otra clase que genere el mismo reporte en HTML en un browser? Sería bastante conveniente utilizar el método obtenerInformacionBD ()de AdministradorDeReportes, pero una vez más tenemos el problema que esta clase tiene dependencias que no necesitamos (ni el API para conexión a FTP ni la generación de Excel). Dado que es obvio que nuestro diseño inicial tiene problemas, corregimos y planteamos lo siguiente:

Después de recapacitar, planteamos esto
Con esta nueva solución, la aplicación para transferir archivos PDF solamente debería utilizar la clase ClienteFTP sin la sobrecarga del resto de API's que no necesita; y si se requiere el reporte HTML que planteábamos sólo dependeríamos de la clase ExtractorDeDatos. Este diseño tiene la peculiaridad que nuestras clases están bastante especializadas y tienen una única responsabilidad específica: Por ejemplo, la clase ClienteFTP se ocupa de la conexión con el servidor FTP y nada más. Es esta especialización lo que nos da bastante flexibilidad para la reutilización, que es lo que trata de decirnos Robert C. Martin con su Principio de Responsabilidad Única:

“Nunca debe de haber más de una razón para que una clase sea modificada”

Si vemos nuestro diseño inicial, la clase AdministradorDeReportes debería modificarse si es que se requieren datos extra en el reporte. Esta clase también debería modificarse si quieren que el reporte Excel tenga otros colores. Y si quisiéramos optimizar la conexión con el servidor FTP nuestra clase AdministradorDeReportes también debería pasar por mantenimiento, por lo que tenemos un ejemplo bastante claro de como violentar este principio. Ahora, en nuestra versión mejorada del diseño hemos transferido estas responsabilidades a las clases ExtractorDeDatos, ClienteFTP y ReporteadorExcel; de modo que cada cambio que mencionábamos  ahora impacta solamente en una clase de nuestro programa.

No hables con extraños, o la Ley de Deméter

Imagen: Autorretrato con Sombrero de Paul Gauguin

Desde los primeros cursos de orientación a objetos de la universidad he escuchado que al programar se debe procurar siempre "niveles bajos de acoplamiento y altos de cohesión". Recién ahora que estoy ojeando The Pragmatic Programmer de  Andrew Hunt y David Thomas el tema del acoplamiento me ha quedado claro y quería compartir con ustedes mis hallazgos.

Es más fácil entender este concepto si vemos un programa que no lo aplica. El libro propone este ejemplo:

          
     public void plotDate(Date aDate, Selection aSelection) { 
       TimeZone tz = aSelection.getRecorder().getLocation().getTimeZone(); 
       ... 
     } 

La clase que contiene al método plotDate está altamente acoplada, dado que su estructura actual depende de otras tres clases: Selection, Recorder y Location. Esto nos pone en una situación delicada, dado que un cambio en cualquiera de esas tres clases tendría impacto en nuestro programa. Por ejemplo, si Location hace que el método getTimeZone sea privado, nuestro método tendría que redefinirse, y lo mismo pasaría con modificaciones a cualquiera de las otras clases dependientes. Es por eso que se recomienda mantener los niveles de acoplamiento mínimos (es decir, depender del mínimo número de clases) para evitar que las ocurrencias del resto deshagan nuestro trabajo. Si bajamos el nivel de acoplamiento de clase de arriba, nos quedaría algo así:

      
     public void plotDate(Date aDate, TimeZone aTz) { 
       ... 
     } 

Ahora nuestro método espera que le llegue una instacia de TimeZone como parámetro y ya no la obtiene desde un objeto Selection. De este modo hemos reducido las dependencias de tres a una clase (sólamente TimeZone ), siendo responsabilidad de la clase cliente la obtención de la instancia de TimeZone que necesitamos. Esta clase cliente nos puede invocar de esta manera:

     plotDate(someDate, someSelection.getTimeZone()); 

El libro menciona que los síntomas clásicos de un programa altamente acoplado son que los cambios más simples impactan en componentes que no deberían, y que los programadores se resisten a darle mantenimiento al sistema por miedo a echar a perder algo.

Descrito al problema, ahora toca describir la solución.

La ley de Deméter -inventada en 1987 en la  Northeastern University - tiene como objetivo el minimizar las dependencias entre las clases de un programa dado, previniendo el acceso a objetos externos para consumir sus métodos. En resumen, la ley establece lo siguiente:

Cualquier método de un objeto debe invocar solamente a los siguientes métodos:

  • Sus propios métodos
  • Los métodos de los objetos que ha recibido como parámetros
  • Los métodos de los objetos que posee como atributos
  • Los métodos de los objetos declarados como variables locales 


Con esto aseguramos el mínimo de dependencias posibles. Los dejo con una imagen extraída del libro que ilustra el concepto:

Imagen tomada de The Pragmatic Programmer de Andrew Hunt y David Thomas

Hasta otra!

Código vicioso



(Imagen: El Fumador de Vincent Van Gogh)


El que una aplicación funcione no significa siempre que esté bien construida, y es frecuente que detrás de una bonita y funcional interfaz de usuario se encuentre un pandemónium de líneas de código. Los americanos les llaman a estas joyitas de la programación "code smell"  que vendrían a ser "Cualquier síntoma en el código fuente de un programa que nos indique la presencia probable de un problema mayor" según Wikipedia.

También en Wikipedia encontramos una pequeña lista de defectos famosos. Les listo algunos que me parecieron interesantes y frecuentes:

  • Código duplicado: Es el producto de una de las más antiguas y populares técnicas de programación: el "copy-paste". A la larga representa un problema serio ya que los cambios que se realicen en una sección de código deben ser replicados en el resto de archivos donde hemos "reutilizado" esta funcionalidad. Para evitarlo podemos extender la clase, o simplemente encapsular esta funcionalidad en un método que sea invocado por los que lo requieren.

  • Clases extensas: Las convenciones de código en Java recomiendan que las clases no debe exceder las 2000 líneas. Si ese es el caso, probablemente tu clase esté haciendo más de lo que debería violentando el principio de alta cohesión. Las clases deben tener responsabilidades especializadas, y si nuestro programa cuenta con Objetos-Dios que hacen de todo es que tenemos un serio problema de diseño.

  • Envidia funcional: Sucede cuando una clase utiliza en exceso los métodos de otra clase. Imaginémonos una clase ClaseEnvidiosa que tiene un método calcularPromedio(). En calcularPromedio(), invoca al método obtenerNumeroDeCursos() de la clase Estudiante. Luego, invoca a obtenerCalificacion(int i) de Estudiante  varias veces para sumar todos los valores obtenidos y al resultado dividirlo entre el número de cursos que obtuvo anteriormente. Finalmente, invoca a setPromedio(double d) de Estudiante y le asigna el valor calculado. Se observa que ClaseEnvidiosa invoca en exceso a los métodos de Estudiante desde el método calcularPromedio(), cuando lo más práctico es que el método calcularPromedio() se encuentre en la misma clase Estudiante.

  • Complejidad artificial: Utilizar en exceso patrones de diseño cuando es suficiente con un diseño sencillo. Recuerdo una aplicación donde el controlador Struts invocaba  a un Facade, que a su vez invocaba a un BusinessDelegate que mediante un EJB hacía uso de una clase DAO que finalmente invocaba a un procedimiento almacenado. Y lo único que se hacía en cada capa de la aplicación  era pasar los parámetros a la capa inferior, hasta llegar al DAO que era el que realmente hacía el trabajo. ¿No era más sencillo contar con un Facade y que éste invoque al DAO directamente?

  • Clase ociosa: Cuando una clase hace  muy poco. Por ejemplo, una clase con un sólo método que es invocado solamente por una clase. Tampoco hay que llevar lo de alta cohesión a extremos y para estas situaciones recomendaría que la funcionalidad de la clase ociosa sea absorbida por otra clase más robusta.

 Wikipedia señala más, pero esas son las que he encontrado (o he incurrido xD). Hasta otra!

Pereza, impaciencia y soberbia


(Imagen: Fé, esperanza y caridad. Esculturas de Manuel Tolsá en la Catedral de México)

Larry Wall es conocido en el medio por ser el creador de Perl y por ser el autor de Programming Perl, el libro de referencia de este lenguaje.

En este libro, Wall le sugiere a los lectores que desarrollen las que -según el- son las tres grandes virtudes de todo gran programador: Pereza, Impaciencia y Soberbia.

El programador perezoso detesta hacer lo mismo dos veces, es por eso que procura siempre que el código que produzca sera reutilizable. Asimismo, el programador perezoso procura documentar siempre para evitar la molestia de tener que explicar sus programas al resto del equipo.

El programador impaciente no soporta estar mucho tiempo sin hacer nada. Es por eso que los programadores impacientes siempre están construyendo programas que quizás no necesiten ahora pero que con certeza necesitarán en el futuro.

Por último, los programadores soberbios no toleran ser criticados. Para evitar críticas y burlas, los programadores soberbios producen código de calidad de modo que sólamente reciban elogios por su trabajo.

Voy a tener que tomar esto bastante en cuenta al momento de buscar personal. Tal vez deberíamos poner un anuncio que diga "Se solicitan desarrolladores perezosos, impacientes y soberbios. De no cumplir los requisitos, favor abstenerse".

Hasta otra!

Errare humanum est

(Imagen: Geek and Poke de Oliver Widder)

Nadie es perfecto, ni siquiera los programadores, y mucho menos los programas que hacemos. Es por eso que son necesarios nuestros amigos de control de calidad, para decirnos - con cortesía- que nos hemos equivocado pero solicitando con insistencia que arreglemos lo que detectaron.  Sin embargo, la gente de control de calidad tampoco es perfecta y sucede con frecuencia que nuestros errores  (o bugs, en argot del programador) llegan hasta el usuario final, que suele reaccionar muy mal cuando algo no funciona como quiere:

"Estimado Perico: Nada en el sistema funciona como me dijeron que iba a funcionar y no puedo trabajar con un sistema en estas condiciones. Cuando trabajábamos con el sistema en Cobol no teníamos este tipo de problemas."

Correos de esa naturaleza llegan a la bandeja de los desarrolladores, incluyendo a Jefes de Proyecto, Gerentes y demás interesados entre los destinatarios. Ahora, si el programador es novato y la gente de calidad es despistada este tipo de correos puede crecer en número y frecuencia; dejándonos con la bandeja de entrada llena y muchos bugs sin control.

Es por eso que todo equipo de desarrollo necesita una base de datos de bugs para tener control del estado de la aplicación: saber cuánto hemos reparado, cuánto nos falta reparar y quién está haciendo ese trabajo. Puse base de datos en negrita porque dada la importancia de esta tarea no podemos confiar en hojas excel ni archivos txt (aquí donde trabajo lo hemos intentado y hemos fracasado rotundamente). Ahora en la empresa estamos empezando a  usar Bugzilla para el control de errores, y nos está yendo bien: es bastante completo y además es gratuito :D.

Quería comentarles también que gracias a la recomendación de un compañero de trabajo -asiduo lector de este modesto blog- llegué a un artículo de Joel Spolsky sobre sistemas de  reporte y control de incidencias. Les listo algunas ideas que me parecieron interesantes:


  • Un buen reporte de bugs debe tener 3 partes: Pasos para reproducir el bug, resultado esperado y resultado real. Por lo general los usuarios mandan correos poco descriptivos ( del tipo "¡nada funciona!", o con un screenshot y el asunto de "Arréglalo"). En el sistema de  reporte de errores (como nuestro Bugzilla) se debe registrar toda la información necesaria para que el programador pueda hacer su trabajo.
  • Los bugs deben ser responsabilidad de una persona. En otras palabras, en todo momento debemos saber quien se está haciendo cargo del bug. Inicialmente puede estar asignado al Jefe de Proyecto, que puede derivarlo al Desarrollador Perico que luego lo asigna al Desarrollador Paco debido a que el error era en el módulo que él desarrolló. Siempre se debe conocer al responsable del bug, de modo que podamos echarle la culpa cuando persista el error xD.
  • Sólo el que reporta el bug puede cerrar el bug. Porque sólamente el que registró el bug sabe a ciencia cierta que es lo que estaba mal. Una vez que el desarrollador termine de construir la solución, el registrador del bug (que puede ser personal de Control de Calidad o Usuarios finales) debe dar el visto bueno. Caso contrario, a continuar con las reparaciones xD.
  • El sistema de registro de bugs debe ser masivamente usado. Para esto, Spolsky nos da algunos tips: Si eres desarrollador, sólamente repara bugs que te han asignado por el sistema. Si eres personal de Control de Calidad, sólamente reporta bugs por el sistema. Si eres Jefe de Proyecto, asigna bugs a tus desarrolladores por el sistema. De esa manera dejaremos de usar excel y emails para pasar a algo más organizado.


    En todos estos puntos Bugzilla nos va a ser de ayuda. Ojalá nos funcione: si le funcionó a Facebook y a la NASA creo que a nosotros nos puede ser útil xD.

    Hasta otra!!

    A propósito del Pair Programming



    (Imagen: Geek and Poke de Oliver Widder)
    • Programador: Entonces, estamos de acuerdo. En las líneas pares alineamos mediante tabs, y en las impares con espacios en blanco. En las sentencias "if" abrimos llaves en la misma línea, y en los bucles "for" lo hacemos en la línea siguiente. Ahora... ¿Cómo hacemos con los bucles "do" y "while"?
    • Nota al pie: Programación en pareja
    (Traducción libre)

    Sobre cómo el pair programming no siempre es una buena idea (y la necesidad de establecer convenciones de código).


    El Síndrome del estudiante


    (Imagen: Piled Higher and Deeper de Jorge Cham)

    Érase una vez un proyecto de software, y érase también un jefe de proyecto que estaba elaborando su cronograma. Como era un buen jefe de proyecto, siempre consultaba a los  desarrolladores antes de realizar estimaciones:

    - Dime Perico ¿Cuánto te tomaría construir este componente?

    Perico sabía que componentes similares le habían tomado un día. Pero Perico estaba aún en la universidad y necesitaba a veces algunas horas de trabajo para avanzar ciertas tareas. Siendo consiente de esto, Perico respondió:

    - Jefe, este componente como mínimo me toma dos días

    El jefe de proyecto entonces agregó a su cronograma la actividad "Construcción de componente", la asignó a Perico y le colocó un tiempo de dos días. Sin embargo, recordó que el proyecto era para un cliente nuevo cuya plataforma no le era familiar al equipo, y mucho menos a Perico. El jefe de proyecto lo pensó mucho, y al final le asignó cuatro días al componente de Perico, dado que uno nunca sabe lo que puede pasar.

    El Jefe de Proyecto hizo esto para todas las actividades del proyecto, y le entregó el cronograma al Gerente de Desarrollo. El Gerente observó el cronograma y se sorprendió del poco tiempo del proyecto. Además, históricamente los proyectos de nuestro Jefe de Proyecto siempre se atrasaban, por lo que como medida preventiva le agregó un día a todas las actividades. Hecho esto, le hizo llegar el cronograma al cliente, junto con el costo del proyecto.

    El cliente recibió el cronograma. Le pareció un tiempo prudente, y por tratarse de un cliente importante el costo no significaba ningún problema para él. Aprobó el cronograma, firmaron lo que tenían que firmar y el proyecto empezó a caminar.

    Cuando a Perico le hicieron llegar el cronograma, lo primero que notó fue que para hacer un componente -bastante simple a su criterio- le habían asignado cinco días. Perico tomó esto con bastante alegría dado que la universidad le estaba consumiendo bastante tiempo. Siendo lunes, Perico pensó:

    - Voy a estudiar los cursos de la universidad hasta el martes, y el miércoles comienzo a hacer este insignificante componente

    Y así lo hizo, estudió mucho hasta el martes y el miercoles comenzó con el componente. Hizo lo que siempre hacía cuando se trataba de esos componentes. Al finalizar el miércoles lo tenía listo, para alegría de Perico y del Jefe de Proyecto.

    El jueves desplegaron el componente en los servidores de prueba del cliente; y como el jefe de proyecto había previsto, no el componente no funcionaba como debería.

    Se lo hicieron saber a Perico, y se pasó todo el jueves tratando de descubrir porqué el componente funcionaba en su computadora y no en los servidores del cliente (que usaban un software que ni Perico ni el Jefe de Proyecto habían visto antes).

    Perico leyó todo el jueves y también el viernes. Más o menos a las ocho de la noche ya tenía una idea de lo que tenía que hacer, y eso implicaba hacer el componente de nuevo. Con mucha verguenza, Perico le confesó a su jefe que necesitaba dos días más. Con más verguenza que Perico, el Jefe de Proyecto le informó de esto al Gerente de Proyectos, quien se enojó bastante pero se sorprendió muy poco: Los proyectos de nuestro Jefe de Proyectos siempre se atrasaban a pesar de lo holgado de su cronograma.

    ¿Les suena familiar? A mi me ha pasado un montón de veces, y es un ejemplo clásico del Síndrome del estudiante (no creo que sea necesario explicar el porqué del nombre xD) : Las personas empiezan a dedicarse al máximo a las tareas asignadas recién unos días antes de la fecha límite. Esto lleva a un desperdicio de la holgura que uno pueda considerar al momento de estimar tiempos de tareas. Fue descrito por Eliyahu M. Goldratt en su libro "Cadena crítica".

    El Síndrome ya lo conocía por experiencia propia, pero me lo presentaron formalmente hoy en el curso de Gestión de Proyectos Informáticos. Cuando el profesor nos diga el antídoto, se los hago saber.

    Hasta otra!!

    El amigo elegido



    Una vez trabajé con un programador que disfrutaba viendo programar a los demás. Podía observar por horas a su programador objetivo sin que este tenga la más mínima idea de que su código estaba siendo escrutado al milímetro. Eso sí, si no entendía alguna línea de código o detectaba algún bug no tenía ningún reparo en interrumpirte, lo que llegaba a ser molesto si es que esto sucedía muy a menudo.

    Me acuerdo de esto debido a que hace un tiempo en una reunión de la empresa mencionaron que tenían planes de implementar una política de pair programming. Esto implica que vas a ser observado mientras programas, y vas a tener observar programar a alguien: dos desarrolladores construyendo el mismo código en una sola estación de trabajo.

    Son pocas las ocasiones en las que he tenido otros ojos -aparte de los míos- sobre el código que produzco. Las que más recuerdo son la del programador voyeur  mencionado al inicio del post y una funcionalidad bastante compleja que nos encargaron a dos programadores bastante novatos (que éramos entonces). Era tan difícil y nos causó tantos problemas que le llamábamos "El Cuco". Fue necesario juntar lo poco que los dos sabíamos para sacar el requerimiento adelante, y nos pasábamos bastante tiempo conversando sobre el código que uno de los dos escribía.

    Valgan verdades, durante el desarrollo del Cuco aprendí bastante, y si algo le debo reconocer al Pair Programming es que es una manera eficiente de distribuir el conocimiento entre desarrolladores. Por otro lado, en muchas ocasiones el programador sigiloso me hizo notar errores que tuve que corregir y no llegaron a producción, por lo que la calidad de lo desarrollado aumentó.

    Ahora, si vemos el vaso medio vacío, hay gente que por su personalidad trabaja mejor sola y no va a aceptar de ninguna manera que les pongas un compañero al costado (ni aunque se trate de Allison Stokke).Además, si pones a programar a tu desarrollador Senior junto al Junior a largo plazo vas a tener otro desarrollador experto, pero a corto plazo estás perdiendo software de calidad que el desarrollador senior podría estar produciendo en vez de andar de profesor. Esos costos deben evaluarse. Y... ¿que pasaría si pones a trabajar juntos a dos desarrolladores senior? Podrían construir software maravilloso, como podrían terminar peleando y acusándose mutuamente de incompetentes (por lo general los buenos programadores son bastante orgullosos).

    Definitivamente, si dos programadores van a trabajar juntos sus personalidades deben ser compatibles para que se toleren mutuamente 8 horas al día (que en nuestro sector por lo general suelen ser muchas más).  Jeff Atwood en su blog postula que todos los desarrolladores deberían tener un amigo programador (el les llama coding buddy), con el que se tenga la confianza suficiente como para compartir código y aceptar sugerencias. También menciona que debe ser una persona con un gusto por la programación similar al tuyo, y al que respetes y sobre todo admires profesionalmente. Ahora, se espera que una persona con estas características trabaje contigo, caso contrario Atwood te recomienda renunciar. Este sistema del "amigo programador" sería algo así como un pair programming informal y de mutuo acuerdo.

    A la fecha no han vuelto a mencionar de nuevo lo del Pair Programming en mi compañía. Hasta entonces, sigo programando como el Llanero Solitario xD.

    Hasta otra!

    A propósito de la Ley de Brooks

    (Imagen: Dilbert de Scott Adams)
    • Jefe: ¿Cuánto demoraría tu proyecto si le agregamos dos personas?
    • Dilbert: Añádele un mes de entrenamiento, un mes por la complejidad generada y uno más para controlar el drama
    • Jefe: Pero después de todo eso...
    • Dilbert: Ellos serán tan productivos como esta reunión.
    (Traducción libre)

    Definitivamente, Dilbert en tres viñetas dice mucho más que mi post xD.

    En busca del programador perdido


    La entrevista de trabajo en la que me fue peor fue para la empresa en la que trabajo ahora. Las entrevistas a las que estaba acostumbrado eran con señores enternados de mediana edad, que me preguntaban sobre lo que había estudiado, lo que mejor sabía y lo que había hecho. Convérsabamos unos minutos, me contaban lo que haría en caso de ingresar y me despedían con una sonrisa. En algunas ocasiones me tomaban un examen técnico escrito, y en el peor de los casos un test psicológico (que es todo un rollo que ya contaré). Sin embargo esa vez, fue diferente:

    -Hola Carlos, mucho gusto. Necesitamos que hagas un mantenimiento a una tabla. Tienes una hora.

    Me dijo en ese entonces el que sería mi jefe, un ingeniero un poco mayor que yo vestido de forma casual. La IDE que tenía que usar era el IBM RAD, que nunca había visto antes; y tenía que conectarme a una base de datos Informix, cuya existencia me enteré el día de la entrevista. Mi futuro jefe me ofreció una clase de Conexión a Base de Datos, que cuando agregué al IDE estaba llena de errores de compilación. No tenía internet, y como me había dicho, tenía solamente una hora.

    Depuré la clase de conexión y comencé a construir el mantenimiento con mis casi inexistentes conocimientos de IBM RAD. Cuando la señorita de recursos humanos me dijo que el tiempo había terminado, sólamente tenía listo el registro y la eliminación. Salí bastante triste, dado que un amigo mío me había recomendado y había hecho un soberano papelón. Para sorpresa mía, me llamaron a los pocos días, por lo que asumí que fue el lobby de amigo lo que me había hecho ingresar. Después me vine a enterar que mi mediocre examen fue uno de los mejores (y que no entré a la empresa por tráfico de influencias) por lo que me había hecho merecedor del puesto.

    Pasó el tiempo, y de evaluado pasé a evaluador. En efecto, ningún postulante podía hacer el bendito mantenimiento, ni siquiera un solo método operativo. Relajamos un poco el asunto y dimos hora y media de tiempo. Nada, ni siquiera el EAR desplegado. Cambiamos a Oracle -un DBMS más popular por estos lares- e instalamos IDE's a gusto del postulante (Eclipse y Netbeans). Ninguno podía terrminar. Cuando habilitamos el uso de Internet ya las cosas comenzaron a mejorar; pero aún así nos topábamos frecuentemente con programadores que no pueden hacer el mantenimiento de una tabla de 5 campos.

    Jeff Atwood -en su artículo Why can't programmers... program?- señala que en USA se vive una problemática similar, y que buscar un programador competente se ha hecho una tarea difícil. Señala que emplean muchas horas entrevistando a gente que no tiene la más mínima noción de lo que es programar. En ese mismo artículo cita a Isram, que en su blog propone el siguiente problema a los postulantes para verificar sus habilidades:

    Escriba un programa que imprima los números del 1 al 100. Para los múltiplos de tres imprima "Fizz" en vez del número, y para los múltiplos de cinco escriba "Buzz". Para los números que son múltiplos de tres y cinco escriba "FizzBuzz".

    Según el autor, la mayoría de graduados de ciencias de la computación demoran más de 15 minutos en la solución o simplemente no pueden hacerlo (tal vez por eso en Estados Unidos en desarrollo de software tercericen tanto) . Por otro lado, Joel Spolsky sostiene que en toda entrevista a desarrolladores se debe exigir codificar.  Parece sensato, y yo creo que si le hacemos caso nos aseguramos el descartar a los que no puedan con la pregunta FizzBuzz xD.

    Hasta otra!

    Etiqueta para programadores


    Recuerdo que en la universidad existía un curso electivo de "Protocolo", donde te instruían en las buenas maneras en el comer y el actuar. La evaluación final era asistir a una cena de gala en una embajada y no hacer quedar mal a la profesora xD .

    Citando a Frieda Holler, la etiqueta tiene que ver bastante con el respeto,  y saber como comportarse demuestra consideración con los demás. Y así como es necesario ser educado a la hora de comer, hay que saber también ser correcto al momento de programar. Codificar de manera ordenada y clara es una muestra de respeto hacia el programador que va a dar mantenimiento a lo que has construido. No indentar, por ejemplo, puede ser considerado una malcriadez.

    Ningún profesor en la universidad me mencionó que existían convenciones de programación, así que en mis primeros años era bastante salvaje al codificar. Cuando entré a trabajar, el código desordenado -pero funcional- que en la universidad me hubiera valido un 20 era devuelto por el área de Arquitectura indicándome que indente, que comente y que siga los estándares. De rechazo en rechazo fui ordenándome de a pocos y ahora ya guardo ciertas formas con el código fuente.

    El listado a continuación es un extracto de Java Code Conventions, que siendo publicado por Sun Microsystems puede considerarse oficial. Ojalá les sea de ayuda, y les sugiero programen siempre pensando en el desarrollador que va  a dar mantenimiento a su código (de modo que no te eche maldiciones xD). Dicho esto, comenzamos:
    •  Los archivos Java con más de 2000 líneas -incluyendo líneas en blanco y comentarios- deben evitarse.
    •  Las primeras líneas de un archivo Java deben contener comentarios de entrada, de preferencia en este formato:
    /*
     * Nombre de clase
    *
     * Versión
     *
     * Aviso de Copyright
     */
    •  Dentro de una clase las primeras variables en declararse son las variables de clase (estáticas) y luego las variables de instancia. Dentro de cada categoría, primero deben colocarse las variables públicas, luego las protegidas y por último las privadas.
    •  Un archivo Java debe tener la siguiente estructura:
    1. Documentación de clase/interfaz
    2. Declaración de clase
    3. Variables de clase
    4. Variables de instancia
    5. Constructores
    6. Métodos
    • Una línea de código no debe exceder de 80 caracteres. Las líneas que excedan esta longitud pueden dividirse de esta manera:
    function(longExpression1, longExpression2, longExpression3,
             longExpression4, longExpression5);
    

    En la caso de sentencias condicionales:

    if ((condition1 && condition2)
            || (condition3 && condition4)
            ||!(condition5 && condition6)) {
        doSomethingAboutIt();
    }
    

    Y para sentencias ternarias:

    alpha = (aLongBooleanExpression) ? beta
                                     : gamma;
    • Los comentarios deben utilizarse para brindar información adicional que no está explícita en el código fuente.
    • Los comentarios no deben estar delimitados en cajas hechas de asteriscos u otros caracteres.
    • Los comentarios en bloque deben usar al inicio de cada archivo java y antes de cada método. Un comentario en bloque debe estar separado del resto del código por una línea en blanco. Todas las líneas de un comentario en bloque comienzan con un asterisco (*). Por ejemplo:
    /*
     * Este es un comentario en bloque
     */
    
    • Se pueden usar comentarios cortos de uno línea indentados al mismo nivel del código fuente. Si el comentario no puede estar contenido en una sóla línea, debe utilizarse el formato de comentarios en bloque. Un comentario de una línea debe estar precedido de una línea en blanco. Así:
    if (condition) {
        /* Acciones para la condición */
        ...
    }
    • Los comentarios de documentación describen clases Java, interfaces, constructores, métodos y atributos. Cada comentario de documentación se encuentra delimitado por /** ...*/, y debe aparecer justo antes de la declaración:
    /**
     * La clase Example provee...
     */
    class Example { ...
    
    • Los comentarios de documentación no deben colocarse dentro de un método o una definición de constructor, dado que Java asocia los comentarios de documentación a la primera documentación después del comentario.
    • Se recomienda utilizar una declaración por línea. Entonces, es preferible utilizar esto:
    int level; // nivel de indentación
    int size;  // tamaño de la mesa
    
    que esto:
    int level, size;
    • Colocar las declaraciones sólamente al inicio de los bloques (un bloque está limitado por llaves). No se debe esperar a declarar las variables justo antes de utilizarlas. Así:
    void MyMethod() {
        int int1;         // inicio del bloque del método
        if (condition) {
            int int2;     // inicio del bloque "if"
            ...
        }
    }
    
    • Tratar siempre de inicializar las variables locales al momento de declararlas.
    • Utilizar siempre llaves para sentencias condicionales (if). Evitar este formato:
    if (condition) //EVITAR!! UTILIZAR LLAVES!
    statement;
    
    • Cada sentencia switch debe incluir la condición default. Dentro de default, utilizar break es redundante pero evita errores en caso se agreguen nuevas condiciones. Cuando no se requiera incluir break en un case, agregar el comentario /* falls through */:
    switch (condition) {
    case ABC:
    statements;
        /* falls through */
    case DEF:
    statements;
        break;
    case XYZ:
    statements;
        break;
    default:
    statements;
        break;
    }
    • Los nombre de clase debe ser sustantivos, donde la primera letra de cada palabra interna comience con mayúsculas. Utilizar palabras completas y evitar acrónimos y abreviaturas:
    class Raster;
    class ImageSprite;
    • Los nombres de los métodos debe ser verbos, la primera letra del nombre del método debe estar en minúsculas. La primera letra de cada palabra interna debe estar en mayúsculas:
    run();
    runFast();
    getBackground();
    
    • Las variables declaradas como constantes deben tener nombres en mayúscula, y las palabras internas deben estar separadas por guiones bajos (_). Así:
    int MIN_WIDTH = 4;
    int MAX_WIDTH = 999;
    int GET_THE_CPU = 1;
    
    • No hacer las variables de instacia y de clase públicas a menos que se tenga una buena razón.
    • Evitar hacer referencia a variables o métodos de clase desde objetos. Usar para esto el nombre de la clase.
    classMethod();             //OK
    AClass.classMethod();      //OK
    anObject.classMethod();    //EVITAR!
    

    Recetario IBM 669


    Hace unas semanas obtuve la certificación SOA de IBM de SOA, así que ahora puedo poner en el resumé que soy IBM Certified SOA Associate. En realidad, no creo que la forma en la que me preparé sea un ejemplo a seguir -por eso la demora en el post- pero igual la comentaré para que sirva de referencia a la gente que se lo quiera tomar más en serio.

    Comenzó Marzo y con él la temporada de certificaciones gratuitas en la empresa en la que trabajo. En esos días andaba bastante ocupado con un software en producción bastante problemático, por lo que si quería certificarme tenía que ser en algo que no me demande demasiado tiempo (de preferencia, algo que ya conozca xD). Opté por la de SOA porque mis fundamentos de Web Services están bastante sólidos -modestia aparte xD- y un par de compañeros ya tenían la certificación así que podrían facilitarme orientación y material. Programé la certificación para fin de mes porque parecía un tiempo razonable.

    Como siempre, revisé lo que la gente de Javaranch recomendaba para la certificación. Muchos coincidían en que SOA for Dummies de Judith Hurwitz era un buen punto de partida, así que me conseguí el libro y lo revisaba cuando podía. Como todo libro For Dummies, era bastante didáctico, elemental y bastante bueno para un novicio como yo. Encontrándome ya por el capítulo 10 caí en la cuenta que ya faltaban dos semanas para el día D por lo que necesitaba enfocarme más en el examen y en los temas en los que me iban a evaluar (el libro de Hurwitz es bastante amplio, y no contiene exactamente lo que IBM evalúa). Recurrí nuevamente a JavaRanch donde me recomendaron SOA Fundamentals in a Nutshell, un documento IBM de 34 páginas especialmente orientado a la certificación. Lo leí completo, con lo que tuve una mejor idea de qué es lo que IBM espera que uno sepa.

    Revisé también la web del examen y me percaté que aún me quedaban muchos objetivos por cubrir. Entonces, era necesario revisar las lecturas que IBM sugería. El listado era inmenso, e incluye Redbooks, artículos de DeveloperWorks y cursos en línea. Dado que no disponía de mucho tiempo -ni ganas, que el tema de SOA no me emociona mucho- revisé solamente esto:


    Ya con esto me quedó más claro que es lo que IBM entiende por SOA. Ahora que ya tenía más confianza me puse a buscar mocks para hacerme una idea de cómo era el examen (y desistir si es que estaba muy difícil xD). Una vez más por Javaranch me topé con un grupo Yahoo de prepaparación para el examen SOA, donde estaban colgadas algunas preguntas de ejemplo. La mayoría de preguntas eran "de opinión" y a mi parecer eran bastante relativas; por ejemplo "¿Porqué la característa X es importante?" o "¿Cúales son los beneficios de utilizar Y?". En los documentos que había leído no se encontraban exactamente estas definiciones, pero tenía ya el suficiente conocimiento para hacerme una idea y responder a estas preguntas de acuerdo a mi criterio. Para sorpresa mía, parecía que mi criterio coincidía con el de IBM xD.

    El 31 de Marzo me acerqué a New Horizons a dar mi examen. Como ya me habían anticipado los mocks, las preguntas "de opinión" eran mayoría, y las respondí con lo que me dictaba el sentido común. Las preguntas técnicas fueron poquísimas, y casi en su totalidad eran sobre temas de Web Services. Terminé el examen, y en el reporte de Prometric decía que había aprobado.

    Eso sería todo. Espero les sea de utilidad.

    Hasta otra!