tag:blogger.com,1999:blog-30118681102970971162024-03-12T22:23:16.014-05:00certifiedApuntes sobre Ingeniería de Softwarecertified-eshttp://www.blogger.com/profile/05251475836524665876noreply@blogger.comBlogger279125tag:blogger.com,1999:blog-3011868110297097116.post-51483127069501742012013-10-13T02:32:00.001-05:002013-10-17T11:58:19.855-05:00Carta abierta a un Profesor de mi Universidad<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhr1WxPzoX8EOjJJvzYJZteETYch8OsmGBMfOcqnuzJd0sX6a07wVKpjPn5_m-VbznIlI3coBntBbaCpNQKsyuONJNl53KL8Zm3NxiD8aGT3EA790uQhHypCnSP7zOSkuFLi8QmJkbAn0CT/s1600/letter-writing.gif" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="211" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhr1WxPzoX8EOjJJvzYJZteETYch8OsmGBMfOcqnuzJd0sX6a07wVKpjPn5_m-VbznIlI3coBntBbaCpNQKsyuONJNl53KL8Zm3NxiD8aGT3EA790uQhHypCnSP7zOSkuFLi8QmJkbAn0CT/s320/letter-writing.gif" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Necesitaba poner un dibujo, y sólo encontré este. Créditos: <a href="http://jc-schools.net/">http://jc-schools.net</a></td></tr>
</tbody></table>
<h3>
Introducción</h3>
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:<br />
<br />
<blockquote class="tr_bq">
¿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?</blockquote>
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:<br />
<br />
<h3>
La Carta</h3>
Buenas noches Profesor, yo me considero un <i>practioner</i> 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.<br />
<br />
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 <b>se produce software altamente complejo aquí en Perú</b>, 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.<br />
<br />
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 <b>no es una disciplina de Ingeniería</b>- 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. <b>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 </b>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.<br />
<br />
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 <b>muchos egresados de la UNI ya están desempeñándose en ese rubro</b>: Los conozco y sé que son muchos.<br />
<br />
<br />
<div style="margin-bottom: 0in;">
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 <b>ese Programa es Ingeniería de Software</b>. 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 <b>nuestra tradición como Escuela de Ingenieros</b>.</div>
certified-eshttp://www.blogger.com/profile/05251475836524665876noreply@blogger.com6tag:blogger.com,1999:blog-3011868110297097116.post-70884703120756875052013-10-06T20:59:00.002-05:002013-10-09T07:51:06.364-05:00Quiero hacer Computación y no sé qué estudiar<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSI4RWm9pztl7o54FdWYdMIuzPmI03Sebsyh324InWk6NtCyRlduLcmWbvgB5W67z6Q6g_54issARJkkbTPZADIAHknhwjbJ4HlHJ_S5i7WzlPb5cLlhoOuLtSbLpDiCXaGvriu5UWmnel/s1600/CS+Ed+Week+Dec+2010+photo.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="185" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSI4RWm9pztl7o54FdWYdMIuzPmI03Sebsyh324InWk6NtCyRlduLcmWbvgB5W67z6Q6g_54issARJkkbTPZADIAHknhwjbJ4HlHJ_S5i7WzlPb5cLlhoOuLtSbLpDiCXaGvriu5UWmnel/s320/CS+Ed+Week+Dec+2010+photo.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Ellos estudian Computación. Créditos: <a href="http://web.cs.toronto.edu/news/current/National_Computer_Science_Education_Week.htm">University of Toronto</a></td></tr>
</tbody></table>
<br />
Cómo he contado en <a href="http://certified-es.blogspot.com/2013/09/la-uni-la-ingenieria-de-sistemas-y-yo.html">otro post</a>, 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:<br />
<ul>
<li>Informática, en la Universidad Nacional de Trujillo.</li>
<li>Ingeniería de Sistemas, en la Universidad de Trujillo o en la Universidad César Vallejo.</li>
<li>Ingeniería de Computación y Sistemas, en la Universidad Privada Antenor Orrego.</li>
<li>Ingeniería de Sistemas Computacionales, en la Universidad Privada del Norte.</li>
</ul>
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:<br />
<ul>
<li>Ingeniería de Sistemas, en la Universidad Nacional de Ingeniería o en la Universidad Nacional Mayor de San Marcos.</li>
<li>Ingeniería Informática en la Pontificia Universidad Católica del Perú.</li>
</ul>
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:<br />
<ul>
<li>Las empresas necesitaban Ingenieros de Sistemas para desempeñarse como Analistas de Negocios, determinando las necesidades tecnológicas de las empresas.</li>
<li>Las empresas necesitaban Ingenieros de Sistemas para administrar Servidores de Bases de Datos, Servidores Web e incluso infraestructura de redes.</li>
<li>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.</li>
</ul>
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.<br />
<br />
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.<br />
<br />
Primero, empecemos por quien pone las reglas en lo referente a Computación: las sociedades profesionales más importantes son las <a href="http://www.computer.org/">IEEE Computer Society </a>y la <a href="http://www.acm.org/">Association for Computing Machinery</a>. Estas dos junto a sociedades adicionales se reúnen periódicamente y emiten un documento denominado <a href="http://www.acm.org/education/curricula-recommendations">Computing Curricula</a>, que contiene los programas de Computación actualmente disponibles y con estándares curriculares definidos (que no les sorprenda<a href="http://certified-es.blogspot.com/2013/09/ingenieria-de-sistemas-cosa-tan-rara.html"> no encontrar a la Ingeniería de Sistemas</a>). En la versión 2005 de este documento, comienzan lógicamente definiendo Computación:<br />
<blockquote class="tr_bq">
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)</blockquote>
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:<br />
<br />
<h3>
Ingeniería de Computación</h3>
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.<br />
<br />
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.<br />
<h3>
Ciencia de la Computación</h3>
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).<br />
<br />
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 <a href="http://fc.uni.edu.pe/portal/index.php/ciencias-de-la-computacion.html">UNI</a> y la <a href="http://www.upc.edu.pe/facultad-de-ingenieria/ciencias-de-la-computacion">UPC</a> en Lima y la <a href="http://www.unsa.edu.pe/index.php/areaacademica/pregrado/ingenierias/172-esc-ciencias-de-la-computacion">UNSA</a> y la <a href="http://www.ucsp.edu.pe/index.php/pre-grado/fac-de-ingenieria-y-computacion/ciencia-de-la-computacion">UCSP</a> en Arequipa.<br />
<h3>
Sistemas de Información</h3>
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.<br />
<br />
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 <a href="http://www.upc.edu.pe/facultad-de-ingenieria/ingenieria-de-sistemas-de-informacion">UPC</a> y la <a href="http://www.usmp.edu.pe/ffia/sistemas/">USMP</a>.<br />
<h3>
Tecnologías de Información</h3>
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.<br />
<br />
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.<br />
<h3>
Ingeniería de Software</h3>
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.<br />
<br />
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 <a href="http://www.upc.edu.pe/facultad-de-ingenieria/ingenieria-de-software">UPC</a> y la <a href="http://www.urp.edu.pe/ingenieria.informatica/index.php?urp=personal">URP</a>- y están apareciendo nuevos programas en el País.<br />
<br />
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.<br />
<div>
<br /></div>
certified-eshttp://www.blogger.com/profile/05251475836524665876noreply@blogger.com2tag:blogger.com,1999:blog-3011868110297097116.post-67978935026218725702013-10-02T00:06:00.001-05:002013-10-06T22:39:39.243-05:00Programar es fácil<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVLPKw5wUVat_5scwbS9Dit-sVaFLqkEusmFsRhmAu8XerJ2w2flubaeE6yLAILC35pfcCvOOTNI5IfcvMHUg3a6sYA15BMCTMFzu0YOFCHmtY2H15NC1yHgGA_hAh2AFbD7WdwomGG7sU/s1600/1430x561.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVLPKw5wUVat_5scwbS9Dit-sVaFLqkEusmFsRhmAu8XerJ2w2flubaeE6yLAILC35pfcCvOOTNI5IfcvMHUg3a6sYA15BMCTMFzu0YOFCHmtY2H15NC1yHgGA_hAh2AFbD7WdwomGG7sU/s320/1430x561.jpg" width="245" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Programar en Java es tan sencillo que puedes aprenderlo en sólo un día. Puedes comprar el libro <a href="http://www.amazon.com/Yourself-Covering-Android-Edition-Yourself/dp/0672335751/ref=sr_1_2?ie=UTF8&qid=1380690119&sr=8-2&keywords=programming+java+24+hours">aquí</a>.</td></tr>
</tbody></table>
<span id="docs-internal-guid-47a27ef4-778b-b39b-93ae-e2808ac1db5e"></span><br />
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 <a href="http://certified-es.blogspot.com/2013/09/ingenieria-de-sistemas-cosa-tan-rara.html">me opongo rotundamente a esa decisión </a>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:<br />
<blockquote class="tr_bq">
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. </blockquote>
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:<br />
<blockquote class="tr_bq">
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.</blockquote>
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:<br />
<ul>
<li>Programar es fácil, cualquier persona con nociones básicas puede producir aplicaciones de clase mundial como Facebook o Twitter. </li>
<li>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. </li>
</ul>
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, <a href="http://certified-es.blogspot.com/2013/09/la-uni-la-ingenieria-de-sistemas-y-yo.html">existe cierta aversión de ciertos docentes para la Ingeniería de Software en mi facultad</a> y esta opinión puede haber llegado al estudiantado. Es por esto, que en este post quiero defender dos ideas: <br />
<h3>
La construcción de Software es compleja</h3>
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, <a href="http://norvig.com/21-days.html">Peter Norvig estima que te puede tomar 10 años el dominar el arte de construir software</a>, como se demuestra experimentalmente con una amplia cantidad de disciplinas. <br />
<br />
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:<br />
<ul>
<li>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. </li>
<li>Ir a la Universidad (opcional) </li>
<li>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. </li>
<li>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. </li>
<li>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. </li>
</ul>
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. <br />
<h3>
Contar con talento técnico es clave para toda Startup</h3>
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ú, <a href="http://elcomercio.pe/actualidad/1635820/noticia-gerente-peruana-amazon-explica-que-le-falta-al-peru-innovacion?ft=grid">dió esta lapidaria respuesta</a>: <br />
<blockquote class="tr_bq">
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. </blockquote>
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. <br />
<br />
Vengo de leer <a href="http://www.forbes.com/sites/stellafayman/2013/02/22/how-to-find-a-technical-cofounder/">un artículo en Forbes de Stella Fayman</a>, del que quiero rescatar algunos puntos: <br />
<ul>
<li>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. </li>
<li>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. </li>
<li>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. </li>
</ul>
Y para terminar, una cita que está en el mismo artículo: <br />
<blockquote class="tr_bq">
El desarrollo de software es un arte, no es un commodity. Trátalo como tal, y tendrás éxito. (Traducción libre)</blockquote>
certified-eshttp://www.blogger.com/profile/05251475836524665876noreply@blogger.com4tag:blogger.com,1999:blog-3011868110297097116.post-34218768228366565402013-09-24T21:35:00.000-05:002013-10-06T22:31:00.903-05:00Ingeniería de Sistemas, cosa tan rara<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgo6LUjTFslISPEQbXikk5a6cex8cyzV-t6RtAvj8LAVMIIWoT6QUClt3sfRY-1glKAu-89aDX-e-UnYPb3EsyV8z_Z1cFZtKA8VTyRRSK4zV6YxZiYgz8EMwHUC7qXOm0bWiMXuQMlgL3M/s1600/ing_en_sistemas.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="265" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgo6LUjTFslISPEQbXikk5a6cex8cyzV-t6RtAvj8LAVMIIWoT6QUClt3sfRY-1glKAu-89aDX-e-UnYPb3EsyV8z_Z1cFZtKA8VTyRRSK4zV6YxZiYgz8EMwHUC7qXOm0bWiMXuQMlgL3M/s320/ing_en_sistemas.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Un meme, algo feo pero muy cierto. (Créditos: <a href="http://aynomanches.blogspot.com/">http://aynomanches.blogspot.com</a>)</td></tr>
</tbody></table>
<br /><br />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.<br /><br />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).<br /><br />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.<br /><br />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, <a href="http://www.incose.org/educationcareers/faqsforstudents.aspx">un ingeniero de Sistemas se encarga de lo siguiente</a>:<br /><br /><blockquote class="tr_bq">
“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)</blockquote>
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 <a href="http://www.acq.osd.mil/se/">Departamento de Defensa de los Estados Unidos</a> o la <a href="http://books.google.com.pe/books/about/NASA_Systems_Engineering_Handbook.html?id=2CDrawe5AvEC&redir_esc=y">NASA</a>- 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 <a href="http://news.cnet.com/8301-17852_3-10468165-71.html">más reconocidos y mejor pagados a nivel mundial.</a><br /><br />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 <a href="http://www.incose.org/about/organization/bios/displayBio.aspx?bio_id=199953">Ralf Hartmann</a>, 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. <br /><br />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 <a href="http://www.computer.org/portal/web/pressroom/Graduate-Reference-Curriculum-for-Systems-Engineering-Version-1.0-Released">ya publicada una para ofertas de posgrado</a>.<br /><br />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.<br /><br />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. <a href="http://certified-es.blogspot.com/2013/09/la-uni-la-ingenieria-de-sistemas-y-yo.html">Como he contado anteriormente</a>, 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.<br /><br />En el <a href="http://www.blogfiisuni.com/2009/09/09/informe-de-evaluacion-curricular-especialidad-de-ingenieria-de-sistemas-uni/">Informe de Evaluación Curricular</a>, 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.<br /><br />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.<br /><br />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.<br /><br />Actualmente la UNI y mi facultad están<a href="http://www.blogfiisuni.com/2013/08/16/encuentro-de-estudiantes-docentes-y-egresados-de-ingenieria-de-sistemas-para-tratar-el-tema-de-la-acreditacion/"> en pleno proceso de acreditación</a>, 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. <br /><br />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.certified-eshttp://www.blogger.com/profile/05251475836524665876noreply@blogger.com0tag:blogger.com,1999:blog-3011868110297097116.post-44868851142932948052013-09-14T07:21:00.001-05:002013-10-06T22:27:30.875-05:00La UNI, la Ingenieria de Sistemas y yo<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiRMnqpWFcy9ylHI5uudkpaeRGi30g5f_sbrwkA9DjmAxOTCZkS0n0EPV4fOcoBOKoEKpAJWaar7Hawm123RT-kbCY6axDZeUr3pX3yOEPeFxGAVwCQUtnaaDbg_ompoCaXQeqgaz-5uGS/s1600/34053_405579408995_4361127_n.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiRMnqpWFcy9ylHI5uudkpaeRGi30g5f_sbrwkA9DjmAxOTCZkS0n0EPV4fOcoBOKoEKpAJWaar7Hawm123RT-kbCY6axDZeUr3pX3yOEPeFxGAVwCQUtnaaDbg_ompoCaXQeqgaz-5uGS/s320/34053_405579408995_4361127_n.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Chicos UNI. Entre ellos, estoy yo (Créditos: Ray Mendoza)</td></tr>
</tbody></table>
<br /><br />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.<br /><br />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.<br /><br />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. <br /><br />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.<br /><br />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. <br /><br />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.<br /><br />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. <br /><br />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.<br /><br />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.<br /><br />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.<br /><br />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.<br /><br />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.certified-eshttp://www.blogger.com/profile/05251475836524665876noreply@blogger.com0tag:blogger.com,1999:blog-3011868110297097116.post-2071722158638726522012-03-09T18:23:00.001-05:002012-03-09T18:27:18.254-05:00Estructuras de Datos: Lista EnlazadaSi han revisado los posts anteriores, para realizar un ordenamiento de elementos nos valíamos de un arreglo para contener los elementos a ordenar. Los arreglos en Java tienen un tamaño fijo en memoria asignado al momento ser instanciado: Si nuestro arreglo fue instanciado con una longitud de 100 y sólo colocamos en él 30 elementos hay 70 espacios en memoria que están siendo desperdiciados. Por otro lado, si requerimos ordenar ahora 101 elementos el arreglo anterior no nos sirve y necesitamos instanciar uno más grande. Ahora, si queremos insertar un elemento en medio de un arreglo ya poblado tenemos que desplazar todos los elementos hasta encontrar el lugar apropiado para nuestro nuevo elemento. Si nuestro arreglo es demasiado grande tantos desplazamientos pueden hacer sufrir al CPU de la máquina donde estamos ejecutando el algoritmo.<br />
<br />
Para evitarnos estos inconvenientes, podríamos dejar de usar los arreglos y usar una estructura de datos que no tenga un tamaño fijo y cuyo coste de inserción sea significativamente menor, como las Listas Enlazadas. De acuerdo a <a href="http://www.amazon.com/Data-Structures-Algorithms-Java-2nd/dp/0672324539">Data Structures and Algorithms in Java</a>, las Listas Enlazadas se ven así:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkSLuZ8Atkag9sPuGCe9YJ6kyo8WAJhYNjqOFpm4N9Eos68MU8has4WYD2x1feYgcCQpPJTfdCV-Oic_clCl0OZ124gJoMbJVkSGjV3IEJm4og4zrsYsGr2-tH3kvQLoKfVk7VuwacBV1y/s1600/linked_list.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="294" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkSLuZ8Atkag9sPuGCe9YJ6kyo8WAJhYNjqOFpm4N9Eos68MU8has4WYD2x1feYgcCQpPJTfdCV-Oic_clCl0OZ124gJoMbJVkSGjV3IEJm4og4zrsYsGr2-tH3kvQLoKfVk7VuwacBV1y/s320/linked_list.png" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
Una Lista Enlazada está compuesta por una serie de Nodos (o <i>Links</i>), donde cada Nodo contiene la data almacenada y una referencia al siguiente Nodo de Lista; de este modo la Lista sólo necesita una referencia al primer Nodo para poder tener acceso a todos sus elementos. En la imagen se ve que para insertar un elemento en la primera posición de la Lista, sólo es necesario cambiar la referencia a este primer elemento para que apunte hacia el nuevo elemento; y el elemento nuevo debe apuntar hacia el ex-primer elemento como su elemento posterior.<br />
<br />
Pero tanto palabrerío se comprende mejor en Java:<br />
<br />
<br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpLDiFE8VmR3xJtgtt4qqB3hEUesvRJnzx_JQRlS_15oEWKGHHxjriITFh1ao1oaW9ExVFyV9H-VTQkEDRyWJtQK_q_5yGCMiHMLRTlsVBnOXsb7-p29eISeoQFB9tPwtnk5zUpK40Wmy5/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> package test;
public class SortedList {
private Link first;
public SortedList() {
first = null;
}
public boolean isEmpty() {
return (first == null);
}
public void insert(long key) {
Link newLink = new Link(key);
Link previous = null;
Link current = first;
while (current != null && key > current.dData) {
previous = current;
current = current.next;
}
if (previous == null) {
first = newLink;
} else {
previous.next = newLink;
}
newLink.next = current;
}
public Link remove() {
Link temp = first;
first = first.next;
return temp;
}
public void displayList() {
System.out.print("List (first-->last): ");
Link current = first;
while (current != null) {
current.displayLink();
current = current.next;
}
System.out.println("");
}
}
class Link {
public long dData;
public Link next;
public Link(long dd) {
dData = dd;
}
public void displayLink() {
System.out.print(dData + " ");
}
}
</code></pre>
<br />
Esta no es una Lista Enlazada cualquiera, tiene la peculiaridad que ingresa los nodos en orden. La clase <i>Link </i>representa cada Nodo de la Lista, y cómo mencionaba tiene sólo dos atributos: la data que contiene y la referencia al siguiente Nodo de la Lista. Por otro lado, nuestra Lista Enlazada -representada en la clase <i>SortedList</i>- sólo tiene el atributo <i>first</i>, que hace referencia al primer elemento de la Lista.<br />
<br />
En nuestra Lista los elementos son ingresados en orden mediente el método <i>insert</i>. Para eso hacemos lo siguiente:<br />
<ol>
<li>Creamos una nueva instancia de <i>Link </i>(o sea, un nuevo Nodo) con el valor a insertar.</li>
<li>Declaramos dos variables locales: La variable <i>current </i>nos servirá para almacenar el Nodo sobre el que nos encontramos al recorrer la Lista mientras que <i>previous </i>será utilizada para almacenar el Nodo anterior al Nodo en el que nos encontramos.</li>
<li>Empezamos el recorrido de la lista desde el primer elemento, haciendo que <i>current </i>haga referencia a <i>first</i>.</li>
<li>Recorreremos el arreglo mientras tenga elementos (<i>current != null</i>) hasta que encontremos los nodos entre los que debemos insertar el nuevo elemento.</li>
<li>Cuando hemos salido del bucle ya tenemos la ubicación del elemento a insertar, sólo nos queda reasignar los atributos <i>next </i>del Nodo <i>previous </i>(para que apunte al nuevo Nodo) y del Nodo <i>newLink </i>(para que referencie al Nodo <i>current</i>)</li>
</ol>
Podríamos utilizar esta Lista para ordenar elementos y no tener que utilizar los algoritmos de posts pasados. Analizando la eficiencia de esta estructura, vemos que es costoso agregar elementos a la lista dado que -en el peor escenario- tendríamos que comparar al nuevo elemento con todos los elementos de la Lista. Por otro lado, el tiempo que nos toma extraer el menor elemento es mínimo, constante y no depende del tamaño de la Lista dado que este elemento siempre se encontrará en el atributo <i>first</i> de nuestra Lista (y lo podemos obtener mediante el método <i>remove</i>). <br />
<br /><i>Código fuente e imágenes tomadas de <a href="http://www.amazon.com/Data-Structures-Algorithms-Java-2nd/dp/0672324539">Data Structures and Algorithms in Java</a>. </i>certified-eshttp://www.blogger.com/profile/05251475836524665876noreply@blogger.com2tag:blogger.com,1999:blog-3011868110297097116.post-48794616405713455952012-03-04T17:00:00.000-05:002012-03-05T17:10:27.814-05:00Estructuras de Datos: Cola de prioridadesUna Cola -en el contexto de las Ciencias de la Computación- es una estructura de datos FIFO. Esto significa que los primeros elementos que fueron ingresados en la cola serán primeros en ser removidos. Además, los nuevos elementos a ingresar a lo cola serán colocados en la parte posterior de la misma, como los clientes en las colas de los Bancos.<br />
<br />
Eso lo sé desde la Universidad.<br />
<br />
Sin embargo, en <a href="http://www.amazon.com/Data-Structures-Algorithms-Java-2nd/dp/0672324539">Data Structures and Algorithms in Java </a> descubrí un tipo de Cola llamada Colas de Prioridades; donde los elementos la posición de los elementos en la Cola está en función a un criterio predefinido; como en las colas de las discotecas en las que las jovencitas agraciadas siempre ingresan primero, sin importar la hora en la que hallan llegado.<br />
<br />
Les presento el código que incluye el libro, para una Cola de Prioridades donde se procura que los elementos de menor valor numérico -nuestro criterio-sean removidos primero de la cola:<br />
<br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpLDiFE8VmR3xJtgtt4qqB3hEUesvRJnzx_JQRlS_15oEWKGHHxjriITFh1ao1oaW9ExVFyV9H-VTQkEDRyWJtQK_q_5yGCMiHMLRTlsVBnOXsb7-p29eISeoQFB9tPwtnk5zUpK40Wmy5/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> package cgc.learning;
public class PriorityQ {
private int maxSize;
private long[] queArray;
private int nItems;
public PriorityQ(int s) {
maxSize = s;
queArray = new long[maxSize];
nItems = 0;
}
public void insert(long item) {
int j;
if (nItems == 0) {
queArray[nItems++] = item;
} else {
for (j = nItems - 1; j >= 0; j--) {
if (item > queArray[j]) {
queArray[j + 1] = queArray[j];
} else {
break;
}
}
queArray[j + 1] = item;
nItems++;
}
}
public long remove() {
return queArray[--nItems];
}
public long peekMin() {
return queArray[nItems - 1];
}
public boolean isEmpty() {
return (nItems == 0);
}
public boolean isFull() {
return (nItems == maxSize);
}
}
</code></pre>
<br />
Nuestra Cola de prioridades está implementada en la clase <i>PriorityQ</i>, que para inicializarse requiere como parámetro el máximo número de elementos que puede soportar la cola. Usaremos este número para instanciar el arreglo de <i>longs </i>que contendrá la data.<br />
<br />
Iremos agregando data en el arreglo mediante el método <i>insert</i>, que es también el encargado de que los elementos sean insertados en orden. Se debe procurar que al registrar elementos en el arreglo, los elementos mayores se encuentren a la izquierda -de modo que el mayor elemento insertado tenga índice 0 en el arreglo- mientras que los menores sean almacenados a la derecha, lo que implica que el menor elemento insertado se encuentre en la posición <i>nItems -1</i> del arreglo. En la siguiente imagen:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJTxRq7IsXV8nYDGelhyphenhyphenGGOF5tu1WTZ8lDU-1Q-L6MXQTUDMcyajfigF4eNqNUsFNt_YTasMJD1flo34Tbhth3-2M_Lp4XOboYiEFDaDaDZRvVJkxejNPhnpxBABeirJKFm-A7VuNOgwwd/s1600/priority_queue.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="216" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJTxRq7IsXV8nYDGelhyphenhyphenGGOF5tu1WTZ8lDU-1Q-L6MXQTUDMcyajfigF4eNqNUsFNt_YTasMJD1flo34Tbhth3-2M_Lp4XOboYiEFDaDaDZRvVJkxejNPhnpxBABeirJKFm-A7VuNOgwwd/s320/priority_queue.jpg" width="320" /></a></div>
La flecha <i>Rear </i>apunta hacia el elemento de mayor valor, que tiene el índice 0 en el arreglo; mientras que la flecha <i>Front </i>apunta hacia el elemento de menor valor con índice <i>nItems -1</i> en el arreglo de <i>PriorityQ</i>. Al ingresar un elemento mediante el método <i>insert</i>, debemos procurar que este criterio se mantenga; por lo que realizamos lo siguiente:<br />
<br />
<ul>
<li>En caso el arreglo no tenga elementos, el nuevo elemento ingresado ocupará la posición 0 del arreglo. Al realizar un registro, siempre se incrementa el valor de
<i>nItems </i>de modo que este atributo siempre contenga el número de elementos de la Cola.</li>
<li>En caso el arreglo no esté vacío, compararemos el elemento a ingresar con cada uno de los elementos del arreglo empezando por el menor-el de índice <i>(nItems -1 )</i>- desplazando los elementos existentes hacia la derecha hasta encontrar el lugar apropiado para el nuevo elemento de modo que el arreglo se mantenga ordenado. </li>
</ul>
<div>
<br />
Con esa lógica de inserción aseguramos que al invocar a <i>remove </i>siempre obtendremos el menor elemento de la lista, que es el primero de la Cola. Dado que realizamos comparaciones a lo largo del arreglo al momento de insertar, el tiempo de inserción es directamente proporcional al número de elementos de la Cola; sin embargo, el método <i>remove </i>tiene un tiempo de ejecución constante y no depende del número de elementos de la cola.</div>
<div>
<br /></div>
<div>
Para finalizar, las colas de prioridades se aplican -por ejemplo- en los sistemas operativos multi-tarea. Los procesos se colocan en una Cola de Prioridades y es un función a la prioridad/importancia relativa que les da el sistema operativo que pueden acceder a recursos como el CPU.</div>
<br />
<i>Código fuente e imágenes tomadas de <a href="http://www.amazon.com/Data-Structures-Algorithms-Java-2nd/dp/0672324539">Data Structures and Algorithms in Java</a>.</i><br />
<br />
<br />
<br />certified-eshttp://www.blogger.com/profile/05251475836524665876noreply@blogger.com0tag:blogger.com,1999:blog-3011868110297097116.post-43696205231677012782012-02-20T22:57:00.001-05:002012-02-20T22:57:17.733-05:00Algoritmos: Ordenamiento por inserciónSi hay algún algoritmo que recuerdo de mi época universitaria es el <a href="http://en.wikipedia.org/wiki/Bubble_sort">Ordenamiento de Burbuja</a>: lo recuerdo porque en todos los exámenes te solicitaban ordenar y era el algoritmo más fácil de memorizar. Ayer encontré a mi querido algoritmo de la Burbuja en el capítulo de ordenamiento simple de <a href="http://www.amazon.com/Data-Structures-Algorithms-Java-2nd/dp/0672324539">Data Structures and Algorithms in Java</a>, dedicado a los algoritmos más sencillos - y lentos - de ordenamiento. De los tres algoritmos del capítulo, el de la Burbuja es el más lento e ineficiente de todos; por lo que a pesar de mi nostalgia decidí dedicarle el post al Ordenamiento por Inserción: el más rápido de todos los algoritmos fáciles.<br />
<br />
La idea del algoritmo es que a través de las iteraciones construyamos dos partes diferenciadas con los elementos que tenemos que ordenar: una parte ordenada y una parte desordenada. Conforme pasan las iteraciones, iremos agregando elementos a la parte ordenada con elementos de la parte desordenada, hasta que la parte desordenada se quede sin elementos y nuestra parte ordenada sea el resultado del algoritmo. Imaginemos que estamos aplicando el Ordenamiento por Inserción para alinear un filar de personas por orden de talla. En una iteración intermedia, tendríamos este escenario:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHMjFCpcaEB-BmjlhZuhkTzPZBIpE8paQZsOD9RmFMHT2Bfcoh5MNc_8IRfawby4WUNFeXPrXpvko4S3NWuQkF7LJHNnKFxlYE7kEQ9O4uRgcE9xKWzWtfgpqGPHy2GnBk9wlvdrpvbKcS/s1600/insercion_1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="147" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHMjFCpcaEB-BmjlhZuhkTzPZBIpE8paQZsOD9RmFMHT2Bfcoh5MNc_8IRfawby4WUNFeXPrXpvko4S3NWuQkF7LJHNnKFxlYE7kEQ9O4uRgcE9xKWzWtfgpqGPHy2GnBk9wlvdrpvbKcS/s320/insercion_1.jpg" width="320" /></a></div>
El algoritmo ya ha hecho su trabajo y nos ha dividido al grupo de personas en dos partes: una ordenada y una que tenemos que ordenar. Lo que se hace en cada iteración es tomar al primer elemento de la izquierda de la parte desordenada (en el gráfico <i>"Marked player"</i>) para colocarlo en lista ordenada en el lugar que le corresponda. Entonces, sacamos a <i>"Marked player"</i> de la fila para ver donde lo colocamos.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJ0LGMcjOu-FX-5y4Hh6zV7PzmGX-QDKh3YUqlBPmdYwe8kjaqCSsOluMl9UP-YyeucAZAG2kdSyGSkh-XsMzCmCaXtctqzjInfsH4a9r7FO8YpwG-f7fPKVO7spZRIC5wqx-5BSXae_pU/s1600/insercion_1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="157" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJ0LGMcjOu-FX-5y4Hh6zV7PzmGX-QDKh3YUqlBPmdYwe8kjaqCSsOluMl9UP-YyeucAZAG2kdSyGSkh-XsMzCmCaXtctqzjInfsH4a9r7FO8YpwG-f7fPKVO7spZRIC5wqx-5BSXae_pU/s320/insercion_1.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
Hemos retirado a <i>"Marked player"</i> y esto ha dejado un espacio libre en la lista de personas. Lo que vamos a hacer ahora es desplazar a las personas de la lista ordenada hacia la derecha (aprovechando el nuevo espacio libre) hasta que encontremos el lugar que le corresponde a <i>"Marked player". </i>Después de mover a la derecha a tres grandulones, encontramos el espacio que le corresponde a <i>"Marked player".</i> Lo colocamos en su sitio y nuestra fila india quedaría así:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQxBHkx5FZoSdbjJkh6fcKY8QTK_T49nurwuYuFVB_FsSjeVzEVV9zkIXUglawzM6hoCLYrnTO7w5pb4b9kHPBWY2f0yT9IimB5I_1m_zhUmkK-isLBNoN8h6sSrygBKgU2AsMFOexNVEz/s1600/insercion_1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="167" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQxBHkx5FZoSdbjJkh6fcKY8QTK_T49nurwuYuFVB_FsSjeVzEVV9zkIXUglawzM6hoCLYrnTO7w5pb4b9kHPBWY2f0yT9IimB5I_1m_zhUmkK-isLBNoN8h6sSrygBKgU2AsMFOexNVEz/s320/insercion_1.jpg" width="320" /></a></div>
Ahora la parte de la izquierda-que estaba ordenada- ha crecido en una persona y la parte desordenada de la derecha es una persona menor. Es momento de escoger un nuevo <i>"Marked player"</i> tomando a la primera persona de la izquierda de la lista desordenada. Repetimos el proceso tres veces más y hemos terminado.<br />
<br />
Si en vez de un grupo de personas utilizamos un arreglo de enteros, el programa Java para ordenarlos mediante ordenamiento por inserción sería más o menos así:<br />
<br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpLDiFE8VmR3xJtgtt4qqB3hEUesvRJnzx_JQRlS_15oEWKGHHxjriITFh1ao1oaW9ExVFyV9H-VTQkEDRyWJtQK_q_5yGCMiHMLRTlsVBnOXsb7-p29eISeoQFB9tPwtnk5zUpK40Wmy5/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> public void insertionSort() {
int in, out;
for (out = 1; out < nElems; out++) {
long temp = a[out];
in = out;
while (in > 0 && a[in - 1] >= temp) {
a[in] = a[in - 1];
--in;
}
a[in] = temp;
}
}
</code></pre>
<br />
Cuyo proceso es más o menos el que sigue:<br />
<br />
<ol>
<li>La variable <i>nElems </i>contiene la longitud del arreglo <i>a[]</i> que vamos a ordenar. La variable <i>out </i>la utilizamos para marcar el inicio de la porción no ordenada del arreglo. Nuestra parte ordenada al incio del algoritmo será el primer elemento de <i>a[]</i> (o sea <i>a[0]</i>) y la parte desordenada comenzará en <i>a[1]</i>; es por eso que la variable <i>out </i>se inicializa en 1: esta variable nos marcará siempre el inicio de la parte desordenada del arreglo.</li>
<li>Colocamos el valor de <i>a[out]</i> (nuestro <i>"Marked player"</i>) en la variable <i>temp</i>, dado que al desplazar los elementos de la parte ordenada hacia la derecha podríamos perder su valor.</li>
<li>Inicializamos la variable <i>in </i>con el valor de <i>out</i>, y utilizaremos esta variable para desplazarnos a lo largo de la parte ordenada con el fin de encontrar el lugar que le corresponde a <i>a[out]</i> en la parte ordenada del arreglo. Para esto, comparamos si <i>a[i-1]</i> es mayor que el valor de <i>a[out]</i> almacenado en <i>temp</i>. Si es así, desplazamos <i>a[i-1]</i> a la derecha, y disminuimos<i> i</i> en una unidad para seguir recorriendo la parte ordenada del arreglo.</li>
<li>Cuando<i> a[i-1]</i> sea menor que <i>temp </i>-que contiene <i>a[out]</i>- es que hemos encontrado al fin el lugar que le correspode a nuestro <i>"Marked Player"</i>. El valor de<i> a[out] </i>ahora estará almacenado en <i>a[i]</i>, y estamos listos para tomar el siguiente elemento de la parte desordenada del arreglo.</li>
</ol>
<div>
Como en el post anterior, nos toca determinar cúantos pasos le toma a nuestro algoritmo ordenar un arreglo arbitrario de longitud N, en el peor escenario posible (la gente de algoritmos siempre es pesimista). En la primera iteración, la parte ordenada tiene sólo un elemento, así que a lo más realizaríamos una comparación al ordenar. En la segunda iteración, como ya tendríamos dos elementos en la parte ordenada el algoritmo realizaría como máximo dos comparaciones; y en la última iteración, sólo nos quedaría realizar N-1 comparaciones en el peor escenario posible. Si sumamos todas las comparaciones, tendríamos:</div>
<div>
<br /></div>
<div style="text-align: center;">
1 + 2 + 3 + ... + N - 1 = N*(N-1)/2 </div>
<div style="text-align: right;">
<i><br /></i></div>
<div style="text-align: right;">
<i>*De acuerdo a la fórmula que enseñan en secundaria</i></div>
<div style="text-align: right;">
<i><br /></i></div>
<div style="text-align: left;">
El tiempo de ejecución del algoritmo es proporcional al número de pasos; por lo que el tiempo de ejecución del algoritmo de ordenamiento por inserción para un arreglo de longitud N es proporcional a N al cuadrado.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<i>Código fuente e imágenes tomadas de <a href="http://www.amazon.com/Data-Structures-Algorithms-Java-2nd/dp/0672324539">Data Structures and Algorithms in Java</a>.</i></div>
<br />
<br />certified-eshttp://www.blogger.com/profile/05251475836524665876noreply@blogger.com1tag:blogger.com,1999:blog-3011868110297097116.post-91608440630735142742012-02-19T22:17:00.001-05:002012-02-19T22:25:56.496-05:00Orgullo de artesano (de Software)<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVc7Jnh7fT1qhYSkCU6KaudcGiyxXfaJW63y3HkeuJlLk4ymJkkTUWwTvdkpvxMzNBY5HuFoclxLfZAtF3pIzwmPPSllPVWj4Aij50tv3tOu7H8PgxBVLXKnEH2BhEW-xN6aFifWL4LGgE/s1600/calvin-and-hobbes-snow-sharks-500x312.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="199" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVc7Jnh7fT1qhYSkCU6KaudcGiyxXfaJW63y3HkeuJlLk4ymJkkTUWwTvdkpvxMzNBY5HuFoclxLfZAtF3pIzwmPPSllPVWj4Aij50tv3tOu7H8PgxBVLXKnEH2BhEW-xN6aFifWL4LGgE/s320/calvin-and-hobbes-snow-sharks-500x312.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<i>"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!" - <a href="http://cdn.svcs.c2.uclick.com/c2/a154fb9018ad012f2fc600163e41dd5b?width=900.0">Calvin & Hobbes de Watterson</a>.</i></div>
<br />
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.<br />
<br />
¿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.<br />
<br />
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.<br />
<br />
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.<br />
<br />
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.<br />
<br />
Hace poco me enteré del movimiento de <a href="http://en.wikipedia.org/wiki/Software_craftsmanship">Artesanía de Software</a>, que propone entre otras cosas considerar al proceso de desarrollo de software como un arte en sí mismo. El movimiento tiene un <a href="http://en.wikipedia.org/wiki/Software_craftsmanship">manifiesto </a>con unos valores que a mi parecer todos los programadores deberíamos adoptar:<br />
<br />
<br />
<ul>
<li>No sólo hacemos software que funciona, sino software bien hecho</li>
<li>No sólo respondemos al cambio, sino agregamos valor constantemente.</li>
<li>No sólo somos individuos e interactuamos, sino somos una comunidad de profesionales.</li>
<li>No sólo colaboramos con nuestros clientes, sino establecemos una sociedad productiva con ellos.</li>
</ul>
<div>
<div style="text-align: right;">
<i>*Traducción libre</i></div>
</div>
<div>
<br /></div>
<div>
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:</div>
<div>
<br /></div>
<div style="text-align: center;">
<i>"Artists always suffer" (Los artistas siempre sufren)</i></div>certified-eshttp://www.blogger.com/profile/05251475836524665876noreply@blogger.com0tag:blogger.com,1999:blog-3011868110297097116.post-54828972717267225412012-02-16T16:43:00.002-05:002012-02-16T16:59:44.627-05:00Algoritmos: Búsqueda dicotómica<i><a href="http://www.stoimen.com/">Stoimen's Web Log</a> desde hace un tiempo publica cada semana un post sobre Algoritmos. Habiendo llevado el curso de Algoritmos y Estructuras de Datos en la universidad -y habiéndolo aprobado con una nota decorosa- pensé en seguir los posts como una manera de refrescar mis algo oxidados conocimientos de algoritmia.</i><br />
<i><br /></i><br />
<i>Ya van cinco algoritmos publicados y no he visto ninguno en la Universidad, así que parece que el profesor nos engañó al hacernos creer que sabíamos algoritmos. Me he propuesto remediar ese error, y he comenzado a leer <a href="http://www.amazon.com/Data-Structures-Algorithms-Java-2nd/dp/0672324539">Data Structures and Algorithms in Java</a> para aprender lo que debí haber aprendido en la universidad. Esta serie de posts son una recopilación de conceptos producto de mi lectura.</i><br />
<i><br /></i><br />
<i>Dicho esto, comenzamos:</i><br />
<br />
¿Cómo localizarías un elemento en un arreglo ordenado? Una aproximación ingenua sería recorrer el arreglo desde la posición inicial (En Java, el índice 0) e ir recorriendo el arreglo elemento por elemento hasta localizar el elemento que estábamos buscando. Si asumimos el peor escenario posible -es decir, el elemento que buscábamos se encuentra al final del arreglo- este tipo de búsqueda requeriría N "pasos" par un arreglo de longitud N.<br />
<br />
El enfoque anterior podría funcionar también para un arreglo desordenado, pero tratándose de un arreglo ordenado es ineficiente dado que no aprovechamos el hecho de tener el arreglo ordenado para reducir el número de pasos que le toma al algoritmo encontrar el elemento buscado. La búsqueda dicotómica nos permite aprovechar este atributo de nuestro arreglo para que -en el peor de los casos- la búsqueda tome sólamente lb (N) pasos (esto es el logaritmo en base 2 de N). Pongamos el algoritmo a prueba buscando un número X en un arreglo A de longitud 100 (N=100):<br />
<br />
<ol>
<li>Tomemos el elemento que se encuentra exactamente al medio del arreglo (A[50]) y verificamos si es el elemento que buscábamos. </li>
<li>Imaginemos que no lo es y que X es mayor que A[50]. Cómo se trata de un arreglo ordenado, ahora podemos afirmar con seguridad que X no se encuentre en A[49] ni en ninguno de los elementos que le preceden, por lo que sólo deberíamos buscar en los elementos entre A[51] y A[100]</li>
<li>Tenemos ahora un nuevo arreglo en el que buscar, y según nuestro algoritmo debemos verificar si el elemento ubicado en la mitad del arreglo -o sea A[75] -es el elemento que buscábamos.</li>
<li>Volvamos a pretender que no lo es, pero que ahora X es menor que A[75]. Como este arreglo también se encuentra ordenado, concluimos que todos los elementos desde A[76] hasta A[100] son mayores que X, por lo que sólo deberíamos buscar entre A[51] hasta A[74]</li>
<li>Y así hasta que encontremos el número que buscábamos. </li>
</ol>
<br />
Si tanta palabrería la pasamos a Java, obtenemos algo como esto:<br />
<br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpLDiFE8VmR3xJtgtt4qqB3hEUesvRJnzx_JQRlS_15oEWKGHHxjriITFh1ao1oaW9ExVFyV9H-VTQkEDRyWJtQK_q_5yGCMiHMLRTlsVBnOXsb7-p29eISeoQFB9tPwtnk5zUpK40Wmy5/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> public int find(long searchKey) {
int lowerBound = 0;
int upperBound = nElems - 1;
int curIn;
while (true) {
curIn = (lowerBound + upperBound) / 2;
if (a[curIn] == searchKey) {
return curIn;
} else if (lowerBound > upperBound) {
return nElems;
} else {
if (a[curIn] < searchKey) {
lowerBound = curIn + 1;
} else {
upperBound = curIn - 1;
}
}
}
}
</code></pre>
Ese método pertenece a una clase donde <i>a[]</i> es un atributo que representa el arreglo ordenado sobre el que buscamos y <i>nElems </i>es un atributo que contiene la longitud del arreglo. El método devuelve la posición en <i>a[]</i> en la que se encuentra <i>searchKey, </i>y en caso no la encuentre devuelve <i>nElems</i> que es la longitud del arreglo. La variable <i>curIn </i>representa el índice del elemento que se encuentra en el medio del arreglo que estamos evaluando, siendo <i>lowerBound </i>el índice del menor elemento del arreglo y <i>upperBound </i>el índice del mayor elemento del arreglo. En cada iteración del bucle <i>while </i>se compara si <i>a[curIn]</i> es mayor o menor que el elemento buscado <i>searchKey</i> y en base al resultado de esta comparación se recalculan los valores de <i>upperBound </i>y <i>lowerBound</i>. Con dibujitos, sería algo así:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjezMlS8CcUmpTtOuFFqo6S8Vlg0SeGWx2TmTY7RR0dAe3xZz2zd_eJxInc8wXE4hHL6T9xPL29KGAYS0bOHbvSyuWPGJjqbGiwoO60LuyNyAPf4t7KrTmS8zW-NUIf4_fHSm8Vd8SY00Pw/s1600/binary.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="175" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjezMlS8CcUmpTtOuFFqo6S8Vlg0SeGWx2TmTY7RR0dAe3xZz2zd_eJxInc8wXE4hHL6T9xPL29KGAYS0bOHbvSyuWPGJjqbGiwoO60LuyNyAPf4t7KrTmS8zW-NUIf4_fHSm8Vd8SY00Pw/s320/binary.png" width="320" /></a></div>
<br />
El número de "pasos" que necesasitamos para encontrar un elemento en un arreglo de longitud N viene a estar dado por la cantidad de veces que podemos dividir N sobre 2 (antes que el producto de esta división sea menor que 1). Este número en matemáticas es igual a lb(N), que es considerablemente menor que N de nuestro enfoque ingenuo del primer párrafo: si buscamos secuencialmente un arreglo de 100 elementos nos tomaría 100 pasos, mientras que si usamos la búsqueda dicotómica nos tomaría sólo 7 (aproximadamente el valor de lb(100)).<br />
<br />
<i>Código fuente e imágenes tomadas de </i><i> <a href="http://www.amazon.com/Data-Structures-Algorithms-Java-2nd/dp/0672324539">Data Structures and Algorithms in Java.</a></i>certified-eshttp://www.blogger.com/profile/05251475836524665876noreply@blogger.com6tag:blogger.com,1999:blog-3011868110297097116.post-75054296981782994662010-12-27T13:13:00.005-05:002010-12-27T14:50:09.282-05:00Arquitectura Java EE y Spring FrameworkHace unos meses -en mi anterior trabajo- realizé una presentación al equipo sobre fundamentos de arquitectura y su relación con Spring Framework. La presentación es fundamentalmente teórica así que van a encontrar poco código; y consideré compartirla dado que estamos en campaña de resucitar el blog xD.<br />
<br />
Saludos, y hasta otra!<br />
<div id="__ss_4591339" style="width: 425px;"><strong style="display: block; margin: 12px 0 4px;"><a href="http://www.slideshare.net/cptanalatriste/arquitectura-y-diseo-de-aplicaciones-java-ee" title="Arquitectura y diseño de aplicaciones Java EE">Arquitectura y diseño de aplicaciones Java EE</a></strong><object height="355" id="__sse4591339" width="425"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=arquitecturaydiseodeaplicacionesj2ee-100623151516-phpapp02&stripped_title=arquitectura-y-diseo-de-aplicaciones-java-ee&userName=cptanalatriste" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed name="__sse4591339" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=arquitecturaydiseodeaplicacionesj2ee-100623151516-phpapp02&stripped_title=arquitectura-y-diseo-de-aplicaciones-java-ee&userName=cptanalatriste" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object><br />
<div style="padding: 5px 0 12px;">View more <a href="http://www.slideshare.net/">presentations</a> from <a href="http://www.slideshare.net/cptanalatriste">Carlos Gavidia</a>.</div></div>certified-eshttp://www.blogger.com/profile/05251475836524665876noreply@blogger.com7tag:blogger.com,1999:blog-3011868110297097116.post-15796499636320370232010-12-23T17:46:00.002-05:002010-12-23T17:52:04.442-05:00GWT para novatos<div id="__ss_6307164" style="width: 425px;"><strong style="display: block; margin: 12px 0 4px;"><a href="http://www.slideshare.net/cptanalatriste/gwt-u" title="GWT - Una introducción">GWT - Una introducción</a></strong><object height="355" id="__sse6307164" width="425"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=gwt-101222155552-phpapp01&stripped_title=gwt-u&userName=cptanalatriste" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed name="__sse6307164" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=gwt-101222155552-phpapp01&stripped_title=gwt-u&userName=cptanalatriste" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object><br />
<div style="padding: 5px 0 12px;">View more <a href="http://www.slideshare.net/">presentations</a> from <a href="http://www.slideshare.net/cptanalatriste">Carlos Gavidia</a>.<br />
<br />
Me encargaron en el trabajo realizar una charla introductoria sobre GWT para el equipo. Después de leer durante algunos días -dado que soy un novato en la materia- preparé la presentación que adorna este post. La pongo a disposición de los interesados.<br />
<br />
Saludos, y hasta otra!</div></div>certified-eshttp://www.blogger.com/profile/05251475836524665876noreply@blogger.com0tag:blogger.com,1999:blog-3011868110297097116.post-157604174635385872010-11-24T11:06:00.001-05:002010-11-24T11:07:37.243-05:00Spring Community Day 2010<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4RbtqOnph2BlY8bDVHW6Cl22Qk_aTvN5cAXcE7ZgNRuHBtKzUCgA5YYjV7Xbn_COqQaWjrwmOHG7XwQeWA6vNhHq1C1d4JsgLtU9v8p3vu4aql7KS2XJ3L9jBwwt90-apEaFP2p7-m48S/s1600/5203166042_de83d10ab3_z.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4RbtqOnph2BlY8bDVHW6Cl22Qk_aTvN5cAXcE7ZgNRuHBtKzUCgA5YYjV7Xbn_COqQaWjrwmOHG7XwQeWA6vNhHq1C1d4JsgLtU9v8p3vu4aql7KS2XJ3L9jBwwt90-apEaFP2p7-m48S/s320/5203166042_de83d10ab3_z.jpg" width="226" /></a></div><br />
Creo que debo empezar esto post disculpándome por la ausencia prolongada: He andado tan ocupado últimamente que hasta se han reducido mis horas de sueño. Sin embargo, prometo encontrar espacio para actualizar el blog y evitar que se llene de telarañas. Palabra.<br />
<br />
Luego, quería invitar a los lectores peruanos al Spring Community Day 2010 que organiza la comunidad Spring Perú. Habrá ponencias técnicas, presentación de casos prácticos, espacios de discusión y el infaltable coffee break (además, este blogger tendrá a su cargo una charla sobre Spring Web Services xD).<br />
<br />
El evento se realizará el 27 de Noviembre (este sábado) en el Campus de la UPC. Para ingresar es necesario colaborar con 10 soles que serán destinados íntegramente a financiar una Misión de Navidad para los niños del Asentamiento Humano San Alvino.<br />
<br />
Están todos cordialmente invitados.<br />
<div><br />
</div>certified-eshttp://www.blogger.com/profile/05251475836524665876noreply@blogger.com0tag:blogger.com,1999:blog-3011868110297097116.post-15123289165848405992010-10-01T15:09:00.001-05:002010-10-01T15:44:41.785-05:00Cohesión y el principio de responsabilidad únicaImaginemos 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:<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1Iz4MNj4vKiTBRHEHJxqdWlcjHJ5eD7FbD-CqPJ8PH3yP3-jDd1SHnA_67D5tVP5FjkOOSRp8VqYkLtSoopgXGIOLHTgvZ1WTC4eu7fzIzRQFTcG7dSwXPmA2Z6xM4z1ftAH3Xp9Icrus/s1600/post.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="148" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1Iz4MNj4vKiTBRHEHJxqdWlcjHJ5eD7FbD-CqPJ8PH3yP3-jDd1SHnA_67D5tVP5FjkOOSRp8VqYkLtSoopgXGIOLHTgvZ1WTC4eu7fzIzRQFTcG7dSwXPmA2Z6xM4z1ftAH3Xp9Icrus/s320/post.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Diseño improvisado</td></tr>
</tbody></table><div><div>Terminamos, el usuario lo prueba, mira que es bueno y nos felicita. </div><div><br />
</div><div>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.</div><div><br />
</div><div>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:</div></div><div><br />
</div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoHBUfrAEQtrc14jqlqIGGHGHig0UjV3A8pZ3rnIVZndo8IKNj8O8JWMXfUUquiZKlo8f2gSyRmfIVo2H2YltDQg4hLuF8w5nHYiwF6bL0-zE2ZzIGjr-HZiigQOPWAQ88stgWfBl-vbVy/s1600/post2.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="201" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoHBUfrAEQtrc14jqlqIGGHGHig0UjV3A8pZ3rnIVZndo8IKNj8O8JWMXfUUquiZKlo8f2gSyRmfIVo2H2YltDQg4hLuF8w5nHYiwF6bL0-zE2ZzIGjr-HZiigQOPWAQ88stgWfBl-vbVy/s320/post2.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Después de recapacitar, planteamos esto</td></tr>
</tbody></table>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 <a href="http://www.butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod">Robert C. Martin</a> con su <a href="http://en.wikipedia.org/wiki/Single_responsibility_principle">Principio de Responsabilidad Única</a>:<br />
<br />
<div style="text-align: center;"><i>“Nunca debe de haber más de una razón para que una clase sea modificada”</i></div><div style="text-align: center;"><i><br />
</i></div>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.certified-eshttp://www.blogger.com/profile/05251475836524665876noreply@blogger.com5tag:blogger.com,1999:blog-3011868110297097116.post-88527923929159317782010-09-16T19:01:00.004-05:002010-09-17T00:31:23.932-05:00Casos de uso y descomposición funcionalImaginemos que estamos capturando requerimientos para una página web que tiene que incluir un foro. Hablamos con el usuario líder, y nos cuenta que es necesario que el administrador del sistema esté en capacidad de bloquear el acceso a los usuarios que repetidamente muestren un comportamiento inadecuado en el foro (escriban en mayúsculas, resuciten <i>threads </i>antiguos, utilicen palabras malsonantes y otras exquisiteces de los foristas). Después de la entrevista vamos a nuestra oficina, iniciamos nuestra herramienta CASE y aplicamos la técnica de casos de uso según lo que nos enseñaron en la universidad para producir este diagrama:<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvR9XqBASldtXq9AdK6lJd8S0G8iaKKjrPsTCuBlR1SmOZUlLGshwYvQIyD8EOagsznaoaS-PCIxsrkhQoK8BJg9Rb3WT1lszCQQjW-LY0xQOar3I8j2Eti3faCjMxbI8nyU5viEYP2a_k/s1600/post.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvR9XqBASldtXq9AdK6lJd8S0G8iaKKjrPsTCuBlR1SmOZUlLGshwYvQIyD8EOagsznaoaS-PCIxsrkhQoK8BJg9Rb3WT1lszCQQjW-LY0xQOar3I8j2Eti3faCjMxbI8nyU5viEYP2a_k/s320/post.jpg" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Diagrama construido con StarUML</td></tr>
</tbody></table><br />
Esta primera versión tiene algunos inconvenientes. Por definición,<b> un caso de uso debe producir valor para los actores con los que interactúa </b>(según<a href="http://www.amazon.com/Use-Case-Modeling-Kurt-Bittner/dp/0201709139"> Kurt Bittner</a>) y no creo que el Administrador encuentre mucho valor a la tarea de "Buscar Usuarios" o de "Mostrar Información de Usuario". A menos que se trate de reportes -y no es el caso- el Administrador del Foro no va a entrar a nuestra aplicación sólamente a realizar una búsqueda o a consultar información de un usuario, sino lo que desea es estar en capacidad de bloquear a los usuarios rebeldes. Por ahí ya tenemos problemas.<br />
<br />
Ahora, tal vez nuestra intención inicial de agregar tantos casos era para poner en evidencia que para bloquear a un usuario es necesario primero buscarlo, luego mostrar un formulario con su información básica, después ingresar los motivos por los que se le va a bloquear para finalmente realizar el bloqueo. Si ese fue el caso caimos en otro error, dado que los casos de uso no "invocan" a otros casos de uso y mucho menos se comunican entre ellos. Realizar esto es intentar convertir los casos de uso en funciones, lo que nos lleva al problema de la <b>descomposición funcional:</b> Descomponer un problema en partes pequeñas y aisladas entre sí, que trabajando juntas nos proveen de una funcionalidad del sistema.<br />
<div><br />
</div><div>La descomposición funcional de casos de uso hace que estos <b>pierdan contexto</b>, como el caso de uso "Asignar motivos de bloqueo" que no tiene sentido sin el resto de casos de uso del diagrama. También está el tema del v<b>alor para los actores</b> que mencionábamos al inicio, el mismo caso de uso "Asignar motivos de bloqueo" no le va a servir al Administrador si es que el usuario al final no termina bloqueado.</div><div><br />
</div><div><div>Ahora ¿qué hacemos para no caer en esto?. Navegando me topé con <a href="http://www.ibm.com/developerworks/rational/library/content/RationalEdge/jan03/UseCaseFAQS_TheRationalEdge_Jan2003.pdf">un documento de Kurt Bittner</a> en el que nos sugiere tres cosas:</div><div><br />
</div><div><ol><li><b>Centrarse en casos de uso que provean valor real a los stakeholders</b>. En el caso de nuestra administrador, buscando usuarios no gana mucho.</li>
<li><b>Limitar el uso de "<i>includes</i>"</b> sólamente para representar descripciones comunes entre caso de uso. Y usarlas con muchísimo cuidado.</li>
<li><b>Limitar el uso de "<i>extends</i>"</b> sólamente para agregar comportamientos opcionales a casos de uso existentes que por si mismos generen valor. Personalmente, no me gusta mucho utilizar esta relación.</li>
</ol><div><br />
Entonces, sabiendo esto borramos nuestro primer borrador defectuoso y lo cambiamos por este mucho más simple y elegante:</div></div></div><div><br />
</div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKMevz-aEOwLLO6jeLJzrjt3jUoQecZnApGPy27ICTdZdjX_Iekp6BEw9fHJzTWZ_6HmlLsePWTepmGlWsSKHkV_SDfqlhyphenhyphenjypImPe4NPOg3Ju4K6wRT9xolrqeBzMyFND9gVdCEdCfVAf/s1600/post.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKMevz-aEOwLLO6jeLJzrjt3jUoQecZnApGPy27ICTdZdjX_Iekp6BEw9fHJzTWZ_6HmlLsePWTepmGlWsSKHkV_SDfqlhyphenhyphenjypImPe4NPOg3Ju4K6wRT9xolrqeBzMyFND9gVdCEdCfVAf/s320/post.jpg" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Este diagrama también lo hice con StarUML</td></tr>
</tbody></table><div><br />
</div><div><div><br />
</div><div>En la especificación de caso de uso ya podemos explayarnos describiendo el flujo deseado. Recuerden que un modelo de casos de uso es principal y mayoritariamente texto. Eso sería todo en esta entrega, hasta otra!</div></div>certified-eshttp://www.blogger.com/profile/05251475836524665876noreply@blogger.com4tag:blogger.com,1999:blog-3011868110297097116.post-65451523890893769352010-08-10T19:25:00.000-05:002010-08-10T19:25:10.712-05:00No hables con extraños, o la Ley de Deméter<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjofbpLXI7hDIBvSr56pc1E_wqavu8xoLb_Hq-YGbEWSqFZWxX2aqIsSbhFMPL_CIJaUcZR4gowL912sLJCxMIlcXmub6OojHSWMxLQcHVGT7r8GCOIPhYFV_HswclKZtHuZ_oa6V2cXFdo/s1600/484px-Paul_Gauguin_111.jpg" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjofbpLXI7hDIBvSr56pc1E_wqavu8xoLb_Hq-YGbEWSqFZWxX2aqIsSbhFMPL_CIJaUcZR4gowL912sLJCxMIlcXmub6OojHSWMxLQcHVGT7r8GCOIPhYFV_HswclKZtHuZ_oa6V2cXFdo/s320/484px-Paul_Gauguin_111.jpg" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Imagen: Autorretrato con Sombrero de Paul Gauguin</td></tr>
</tbody></table><br />
Desde los primeros cursos de orientación a objetos de la universidad he escuchado que al programar se debe procurar siempre <i>"niveles bajos de acoplamiento y altos de cohesión"</i>. Recién ahora que estoy ojeando <a href="http://www.amazon.com/Pragmatic-Programmer-Journeyman-Master/dp/020161622X">The Pragmatic Programmer de Andrew Hunt y David Thomas</a> el tema del acoplamiento me ha quedado claro y quería compartir con ustedes mis hallazgos.<br />
<br />
Es más fácil entender este concepto si vemos un programa que no lo aplica. El libro propone este ejemplo:<br />
<br />
<br />
<i> public void plotDate(Date aDate, Selection aSelection) { </i><br />
<i> TimeZone tz = aSelection.getRecorder().getLocation().getTimeZone(); </i><br />
<i> ... </i><br />
<i> } </i><br />
<br />
La clase que contiene al método <i>plotDate </i>está altamente acoplada, dado que su estructura actual depende de otras tres clases: <i>Selection</i>, <i>Recorder </i>y <i>Location</i>. 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 <i>Location </i>hace que el método <i>getTimeZone </i>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í:<br />
<br />
<br />
<i> public void plotDate(Date aDate, TimeZone aTz) { </i><br />
<i> ... </i><br />
<i> } </i><br />
<br />
Ahora nuestro método espera que le llegue una instacia de <i>TimeZone </i>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 <i>TimeZone </i>), 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:<br />
<br />
<i> plotDate(someDate, someSelection.getTimeZone()); </i><br />
<br />
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.<br />
<br />
Descrito al problema, ahora toca describir la solución.<br />
<br />
La <b><a href="http://en.wikipedia.org/wiki/Law_of_Demeter">ley de Deméter</a></b> -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:<br />
<br />
<i>Cualquier método de un objeto debe invocar solamente a los siguientes métodos:</i><br />
<br />
<ul><li><i>Sus propios métodos</i></li>
<li><i>Los métodos de los objetos que ha recibido como parámetros</i></li>
<li><i>Los métodos de los objetos que posee como atributos</i></li>
<li><i>Los métodos de los objetos declarados como variables locales </i></li>
</ul><br />
<br />
Con esto aseguramos el mínimo de dependencias posibles. Los dejo con una imagen extraída del libro que ilustra el concepto:<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZWfMYPO9H3CUloj02r6boOeKUmUdvHG6Syl73MXNJhP7wg9W6M8Z7krkPmK4GvpKSbzBvKfZFsSwRCfRHZo9dOQfZMa-oeUndnsXs116cxHp_RSojDdsMq8idHICBSgBmQqhQcYym4uh0/s1600/post.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZWfMYPO9H3CUloj02r6boOeKUmUdvHG6Syl73MXNJhP7wg9W6M8Z7krkPmK4GvpKSbzBvKfZFsSwRCfRHZo9dOQfZMa-oeUndnsXs116cxHp_RSojDdsMq8idHICBSgBmQqhQcYym4uh0/s320/post.jpg" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Imagen tomada de The Pragmatic Programmer de Andrew Hunt y David Thomas</td></tr>
</tbody></table><br />
Hasta otra!<br />
<div><br />
</div>certified-eshttp://www.blogger.com/profile/05251475836524665876noreply@blogger.com3tag:blogger.com,1999:blog-3011868110297097116.post-10515117462825205662010-07-26T15:02:00.002-05:002010-07-26T15:04:16.304-05:00Código vicioso<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPOV3Vg6zFADrZSVBnALc1NA0p2C-q2XxUmNQMIcevZrCpnbbc1NnVRRc1QWqKUaDVNZhY3zF677Xnv3v33Z1n_ot63Ea4eNeTuUaGpOB_pvcDDDjCAlexv_L3oGOL4UdGLr9i6cmgikWO/s1600/The-Smoker.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPOV3Vg6zFADrZSVBnALc1NA0p2C-q2XxUmNQMIcevZrCpnbbc1NnVRRc1QWqKUaDVNZhY3zF677Xnv3v33Z1n_ot63Ea4eNeTuUaGpOB_pvcDDDjCAlexv_L3oGOL4UdGLr9i6cmgikWO/s320/The-Smoker.jpg" /></a></div><div class="separator" style="clear: both; text-align: center;"><br />
</div><br />
<b><i>(Imagen: El Fumador de Vincent Van Gogh)</i></b><br />
<br />
<br />
<div class="MsoNormal">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 <i>"code smell"</i> 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 <a href="http://en.wikipedia.org/wiki/Code_smell">Wikipedia</a>.<br />
<br />
</div><div class="MsoNormal">También en Wikipedia encontramos una pequeña lista de defectos famosos. Les listo algunos que me parecieron interesantes y frecuentes:<br />
<br />
</div><div class="MsoNormal"></div><ul><li><b>Código duplicado: </b>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.</li>
</ul><div><br />
</div><ul><li><b>Clases extensas: </b><a href="http://certified-es.blogspot.com/2010/04/etiqueta-para-programadores.html">Las convenciones de código en Java </a>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 <a href="http://en.wikipedia.org/wiki/Cohesion_(computer_science)#High_cohesion">alta cohesión</a>. Las clases deben tener responsabilidades especializadas, y si nuestro programa cuenta con <a href="http://en.wikipedia.org/wiki/God_object">Objetos-Dios</a> que hacen de todo es que tenemos un serio problema de diseño.</li>
</ul><div><br />
</div><ul><li><b>Envidia funcional:</b> Sucede cuando una clase utiliza en exceso los métodos de otra clase. Imaginémonos una clase <i>ClaseEnvidiosa </i>que tiene un método <i>calcularPromedio</i>(). En <i>calcularPromedio</i>(), invoca al método <i>obtenerNumeroDeCursos</i>() de la clase Estudiante. Luego, invoca a <i>obtenerCalificacion</i>(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 <i>setPromedio</i>(double d) de Estudiante y le asigna el valor calculado. Se observa que <i>ClaseEnvidiosa </i>invoca en exceso a los métodos de <i>Estudiante </i>desde el método <i>calcularPromedio</i>(), cuando lo más práctico es que el método <i>calcularPromedio</i>() se encuentre en la misma clase <i>Estudiante</i>.</li>
</ul><div><br />
</div><ul><li><b>Complejidad artificial:</b> Utilizar en exceso patrones de diseño cuando es suficiente con un diseño sencillo. Recuerdo una aplicación donde el controlador <i>Struts</i> invocaba a un <i>Facade</i>, que a su vez invocaba a un <i>BusinessDelegate </i>que mediante un <i>EJB </i>hacía uso de una clase <i>DAO </i>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 <i>Facade </i>y que éste invoque al <i>DAO </i>directamente?</li>
</ul><div><br />
</div><ul><li><b>Clase ociosa: </b>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.</li>
</ul><div><br />
</div><div class="MsoNormal"><o:p> Wikipedia señala más, pero esas son las que he encontrado (o he incurrido xD). Hasta otra!</o:p></div>certified-eshttp://www.blogger.com/profile/05251475836524665876noreply@blogger.com2tag:blogger.com,1999:blog-3011868110297097116.post-90830567175284708692010-06-14T11:27:00.004-05:002010-06-25T10:38:11.717-05:00Pereza, impaciencia y soberbia<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjW03Tb6Q8zEDlTE2yI-QdDRPd4pJsjRTAK1TIUa_VIyKUJ6-TXS67S-kwaw-MVSDqM1fTGQTZg8fZSO6hRCYHFWWdeaXasmkrGhQh3sMDw57VjJ2zVbzFbAJl09ywzyZSf7ZgQLb2ulspc/s1600/Manuel+Tols%C3%A1+Fe_esperanza_y_caridad.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjW03Tb6Q8zEDlTE2yI-QdDRPd4pJsjRTAK1TIUa_VIyKUJ6-TXS67S-kwaw-MVSDqM1fTGQTZg8fZSO6hRCYHFWWdeaXasmkrGhQh3sMDw57VjJ2zVbzFbAJl09ywzyZSf7ZgQLb2ulspc/s320/Manuel+Tols%C3%A1+Fe_esperanza_y_caridad.jpg" /></a></div><div class="separator" style="clear: both; text-align: center;"><br />
</div><b><i>(Imagen: Fé, esperanza y caridad. Esculturas de Manuel Tolsá en la Catedral de México)</i></b><br />
<br />
<a href="http://es.wikipedia.org/wiki/Larry_Wall">Larry Wall</a> es conocido en el medio por ser el creador de Perl y por ser el autor de <a href="http://oreilly.com/catalog/9780596000271/?CMP=OTC-KW7501011010&ATT=9780596000271">Programming Perl</a>, el libro de referencia de este lenguaje.<br />
<br />
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.<br />
<br />
El programador <b>perezoso </b>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.<br />
<br />
El programador <b>impaciente </b>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.<br />
<br />
Por último, los programadores <b>soberbios </b>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.<br />
<br />
Voy a tener que tomar esto bastante en cuenta al momento de buscar personal. Tal vez deberíamos poner un anuncio que diga <i>"Se solicitan desarrolladores perezosos, impacientes y soberbios. De no cumplir los requisitos, favor abstenerse"</i>.<br />
<br />
Hasta otra!certified-eshttp://www.blogger.com/profile/05251475836524665876noreply@blogger.com2tag:blogger.com,1999:blog-3011868110297097116.post-15914539821226397762010-06-09T16:40:00.016-05:002010-06-10T23:18:37.069-05:00Errare humanum est<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4bHWLSI5MDOY6s7S933yvGatqztzaYR-Efpwz_AN21jg71D_Z7Jm6NrWHW8NDUb_FiKyl5tAYsQCYwjdAI9Xe6v5WLFxmnI5-JGfetpv-wm9CB-h8h3RBsOv2x0lQnopLnlHMSAtGjyQX/s1600/post.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4bHWLSI5MDOY6s7S933yvGatqztzaYR-Efpwz_AN21jg71D_Z7Jm6NrWHW8NDUb_FiKyl5tAYsQCYwjdAI9Xe6v5WLFxmnI5-JGfetpv-wm9CB-h8h3RBsOv2x0lQnopLnlHMSAtGjyQX/s320/post.jpg" /></a></div><span class="Apple-style-span" style="color: #333333; font-family: Verdana, sans-serif; font-size: 13px; font-style: italic; font-weight: bold; line-height: 20px;">(Imagen: <a href="http://geekandpoke.typepad.com/" style="color: #003366; text-decoration: none;">Geek and Poke de Oliver Widder</a>)</span><br />
<br />
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 <i>bugs</i>, en argot del programador) llegan hasta el usuario final, que suele reaccionar muy mal cuando algo no funciona como quiere:<br />
<br />
<span class="Apple-style-span" style="font-style: italic;">"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."</span><br />
<br />
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.<br />
<br />
Es por eso que todo equipo de desarrollo necesita <b>una base de datos de bugs</b> 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 <a href="http://www.bugzilla.org/">Bugzilla </a>para el control de errores, y nos está yendo bien: es bastante completo y además es gratuito :D.<br />
<br />
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<a href="http://www.joelonsoftware.com/articles/fog0000000029.html"> un artículo de Joel Spolsky</a> sobre sistemas de reporte y control de incidencias. Les listo algunas ideas que me parecieron interesantes:<br />
<b></b><br />
<b></b><br />
<b><ul><li><span class="Apple-style-span" style="font-weight: normal;"><b>Un buen reporte de bugs debe tener 3 partes: Pasos para reproducir el bug, resultado esperado y resultado real.</b> 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.</span></li>
</ul><ul><li><span class="Apple-style-span" style="font-weight: normal;"><b>Los bugs deben ser responsabilidad de una persona.</b> 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.</span></li>
</ul><ul><li><span class="Apple-style-span" style="font-weight: normal;"><b>Sólo el que reporta el bug puede cerrar el bug.</b> 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.</span></li>
</ul><ul><li><span class="Apple-style-span" style="font-weight: normal;"><b>El sistema de registro de bugs debe ser masivamente usado.</b> 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.</span></li>
</ul><ol></ol></b><br />
<b></b><br />
En todos estos puntos Bugzilla nos va a ser de ayuda. Ojalá nos funcione: si le funcionó <a href="http://www.bugzilla.org/installation-list/">a Facebook y a la NASA</a> creo que a nosotros nos puede ser útil xD.<br />
<br />
Hasta otra!!certified-eshttp://www.blogger.com/profile/05251475836524665876noreply@blogger.com6tag:blogger.com,1999:blog-3011868110297097116.post-13955308550533348762010-06-04T11:17:00.005-05:002010-06-06T00:19:32.025-05:00A propósito del Pair Programming<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCaJySRGNu4SEKxAf-AtNiK1gcSBj17zZP5_kh2OSePQxlfs7-ur_vBkdvpBbaIKk1j_bsWZJpcoMdpFV1l6Rp63NLjNqLq90NlyZnHmFjUMBU0jwjJMDYomtMFAmWKjqmxWCytOJtkSA0/s1600/pair_programming.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCaJySRGNu4SEKxAf-AtNiK1gcSBj17zZP5_kh2OSePQxlfs7-ur_vBkdvpBbaIKk1j_bsWZJpcoMdpFV1l6Rp63NLjNqLq90NlyZnHmFjUMBU0jwjJMDYomtMFAmWKjqmxWCytOJtkSA0/s320/pair_programming.jpg" /></a></div><b><i><br />
</i></b><br />
<b><i>(Imagen: <a href="http://geekandpoke.typepad.com/">Geek and Poke de Oliver Widder</a>)</i></b><br />
<ul><li><i>Programador</i>: Entonces, estamos de acuerdo. En las líneas pares alineamos mediante <i>tabs</i>, y en las impares con espacios en blanco. En las sentencias "<i>if" </i>abrimos llaves en la misma línea, y en los bucles "<i>for</i>" lo hacemos en la línea siguiente. Ahora... ¿Cómo hacemos con los bucles "<i>do</i>" y "<i>while</i>"?</li>
<li><i>Nota al pie:</i> Programación en pareja</li>
</ul><div style="text-align: right;"><i>(Traducción libre)</i></div><div><br />
</div><div>Sobre cómo el<a href="http://certified-es.blogspot.com/2010/05/el-amigo-elegido.html"> pair programming</a> no siempre es una buena idea (y la necesidad de establecer <a href="http://certified-es.blogspot.com/2010/04/etiqueta-para-programadores.html">convenciones de código</a>).</div><div><br />
</div><div><br />
</div>certified-eshttp://www.blogger.com/profile/05251475836524665876noreply@blogger.com0tag:blogger.com,1999:blog-3011868110297097116.post-32639061881850162092010-05-29T23:57:00.005-05:002010-05-31T08:29:32.948-05:00El Síndrome del estudiante<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqLRxXMjNwbZlxdaVr7iw8s3JQ7o-hgte5ZFqRSAT2-qh7t3MLWrmZup5PqHX5eV3OOg1RLGAvCj_q17VGm56i3uvyWx8HlkKTGvKRbagvhriPqWtIlMMt7Hox1F9jsueTRy1RilwbFTHx/s1600/phdcomics.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqLRxXMjNwbZlxdaVr7iw8s3JQ7o-hgte5ZFqRSAT2-qh7t3MLWrmZup5PqHX5eV3OOg1RLGAvCj_q17VGm56i3uvyWx8HlkKTGvKRbagvhriPqWtIlMMt7Hox1F9jsueTRy1RilwbFTHx/s320/phdcomics.gif" /></a></div><br />
<b><i>(Imagen: </i></b><a href="http://www.phdcomics.com/"><b><i>Piled Higher and Deeper de Jorge Cham</i></b></a><b><i>)</i></b><br />
<br />
É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:<br />
<br />
<i>- Dime Perico ¿Cuánto te tomaría construir este componente?</i><br />
<br />
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ó:<br />
<br />
<i>- Jefe, este componente como mínimo me toma dos días</i><br />
<br />
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.<br />
<br />
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.<br />
<br />
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.<br />
<br />
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ó:<br />
<br />
<i>- Voy a estudiar los cursos de la universidad hasta el martes, y el miércoles comienzo a hacer este insignificante componente</i><br />
<br />
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.<br />
<br />
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.<br />
<br />
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).<br />
<br />
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.<br />
<br />
¿Les suena familiar? A mi me ha pasado un montón de veces, y es un ejemplo clásico del <a href="http://es.wikipedia.org/wiki/S%C3%ADndrome_del_estudiante">Síndrome del estudiante</a> (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 <a href="http://www.amazon.com/Critical-Chain-Eliyahu-M-Goldratt/dp/0884271536">Eliyahu M. Goldratt en su libro "Cadena crítica"</a>.<br />
<br />
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.<br />
<br />
Hasta otra!!certified-eshttp://www.blogger.com/profile/05251475836524665876noreply@blogger.com8tag:blogger.com,1999:blog-3011868110297097116.post-25541956715436414822010-05-11T20:02:00.001-05:002010-05-11T21:28:42.220-05:00El amigo elegido<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWA0I55uMbI-23CzBOmjvBO3emS5AoJJLT_p9Lx-F6AMYe88AhHlX8zGamnC5GRxm0d5fkkHwPZqeRXS3t8tD0pOGcI1xFvBdltGcAi82WEizSCBAsPKqYEsLk-X9m_1glx91frSvof4xC/s1600/batman_robin.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWA0I55uMbI-23CzBOmjvBO3emS5AoJJLT_p9Lx-F6AMYe88AhHlX8zGamnC5GRxm0d5fkkHwPZqeRXS3t8tD0pOGcI1xFvBdltGcAi82WEizSCBAsPKqYEsLk-X9m_1glx91frSvof4xC/s320/batman_robin.png" /></a></div><br />
<br />
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 <i>bug </i>no tenía ningún reparo en interrumpirte, lo que llegaba a ser molesto si es que esto sucedía muy a menudo.<br />
<br />
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<i><a href="http://en.wikipedia.org/wiki/Pair_programming"> pair programming</a></i>. 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.<br />
<br />
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 <i>voyeur </i>mencionado al inicio del post<i> </i>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 <a href="http://es.wikipedia.org/wiki/Coco_(folclore)">"El Cuco"</a>. 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.<br />
<br />
Valgan verdades, durante el desarrollo del Cuco aprendí bastante, y si algo le debo reconocer al<i> Pair Programming</i> 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ó.<br />
<br />
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 <a href="http://pastamanvibration.files.wordpress.com/2008/07/allison-stokke11.jpg">Allison Stokke</a>).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).<br />
<br />
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). <a href="http://www.codinghorror.com/blog/2009/02/whos-your-coding-buddy.html">Jeff Atwood en su blog </a>postula que todos los desarrolladores deberían tener un amigo programador (el les llama <i>coding buddy</i>), 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<i> pair programming</i> informal y de mutuo acuerdo.<br />
<br />
A la fecha no han vuelto a mencionar de nuevo lo del <i>Pair Programming</i> en mi compañía. Hasta entonces, sigo programando como el Llanero Solitario xD.<br />
<br />
Hasta otra!certified-eshttp://www.blogger.com/profile/05251475836524665876noreply@blogger.com3tag:blogger.com,1999:blog-3011868110297097116.post-63322172436142765942010-04-29T12:22:00.005-05:002010-04-30T10:06:01.487-05:00A propósito de la Ley de Brooks<div class="separator" style="clear: both; text-align: center;"><a href="http://dilbert.com/dyn/str_strip/000000000/00000000/0000000/000000/80000/8000/300/88361/88361.strip.print.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="99" src="http://dilbert.com/dyn/str_strip/000000000/00000000/0000000/000000/80000/8000/300/88361/88361.strip.print.gif" width="320" /></a></div><span class="Apple-style-span" style="font-style: italic; font-weight: bold;">(Imagen: <a href="http://dilbert.com/">Dilbert de Scott Adams</a>)</span><br />
<ul><li><i>Jefe</i>: ¿Cuánto demoraría tu proyecto si le agregamos dos personas?</li>
<li><i>Dilbert</i>: Añádele un mes de entrenamiento, un mes por la complejidad generada y uno más para controlar el drama</li>
<li><i>Jefe</i>: Pero después de todo eso...</li>
<li><i>Dilbert</i>: Ellos serán tan productivos como esta reunión.</li>
</ul><div style="text-align: right;"><i>(Traducción libre)</i></div><div><br />
</div>Definitivamente, Dilbert en tres viñetas dice mucho más que <a href="http://certified-es.blogspot.com/2010/01/una-fabula.html">mi post</a> xD.certified-eshttp://www.blogger.com/profile/05251475836524665876noreply@blogger.com0tag:blogger.com,1999:blog-3011868110297097116.post-39437635958902631972010-04-26T20:08:00.008-05:002012-01-07T02:40:06.944-05:00En busca del programador perdido<div class="separator" style="clear: both; text-align: left;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjoC1KIpG_DXiPKg3gWmR_UJ5NPCdclji07dZaReOCK-m8R4Yy2zeMcz4KyAlAVlerz0dXstgMDnIJy_jahoffn4jEfW6A3YDN0gHBHQ_JB-oEHWaPoVDndqbFOqhfDQJhA8bMVfh76N02L/s1600/post.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjoC1KIpG_DXiPKg3gWmR_UJ5NPCdclji07dZaReOCK-m8R4Yy2zeMcz4KyAlAVlerz0dXstgMDnIJy_jahoffn4jEfW6A3YDN0gHBHQ_JB-oEHWaPoVDndqbFOqhfDQJhA8bMVfh76N02L/s320/post.jpg" /></a></div>
<br />
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:<br />
<br />
<i>-Hola Carlos, mucho gusto. Necesitamos que hagas un mantenimiento a una tabla. Tienes una hora.</i><br />
<br />
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 <a href="http://www-01.ibm.com/software/awdtools/developer/application/">IBM RAD</a>, que nunca había visto antes; y tenía que conectarme a una base de datos <a href="http://www-01.ibm.com/software/data/informix/">Informix</a>, 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.<br />
<br />
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.<br />
<br />
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.<br />
<br />
<a href="http://www.codinghorror.com/blog/">Jeff Atwood</a> -en su artículo <a href="http://www.codinghorror.com/blog/2007/02/why-cant-programmers-program.html">Why can't programmers... program?</a>- 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 <a href="http://imranontech.com/2007/01/24/using-fizzbuzz-to-find-developers-who-grok-coding/">siguiente problema a los postulantes para verificar sus habilidades:</a><br />
<br />
<i>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".</i><br />
<br />
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 <a href="http://certified-es.blogspot.com/2010/03/el-test-de-joel-para-equipos-de.html">se debe exigir codificar</a>. Parece sensato, y yo creo que si le hacemos caso nos aseguramos el descartar a los que no puedan con la pregunta FizzBuzz xD.<br />
<br />
Hasta otra!<br />
<div>
<br /></div>certified-eshttp://www.blogger.com/profile/05251475836524665876noreply@blogger.com7tag:blogger.com,1999:blog-3011868110297097116.post-1131447534423404252010-04-19T15:45:00.013-05:002010-04-19T19:09:38.941-05:00Etiqueta para programadores<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvek5WwI32Zji3mwaPBHlzJz4Z-665PbNfAXJZxqikTka-AQVR4_yxg8jBzvPhmsVyKGij7zOu5Cwqi3WC__ERRj1nQaffzePygWZCTIROpdunVuOPMhq2_G23qhicq9q7LbvUDgcwY-g3/s1600/post.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvek5WwI32Zji3mwaPBHlzJz4Z-665PbNfAXJZxqikTka-AQVR4_yxg8jBzvPhmsVyKGij7zOu5Cwqi3WC__ERRj1nQaffzePygWZCTIROpdunVuOPMhq2_G23qhicq9q7LbvUDgcwY-g3/s320/post.jpg" /></a></div><br />
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 .<br />
<br />
Citando a <a href="http://www.otrastardes.com/2008/02/26/frieda-holler/">Frieda Holler</a>, 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.<br />
<br />
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.<br />
<br />
El listado a continuación es un extracto de <a href="http://java.sun.com/docs/codeconv/">Java Code Conventions</a>, 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:<br />
<ul><li> Los archivos Java con más de 2000 líneas -incluyendo líneas en blanco y comentarios- deben evitarse.</li>
<li> Las primeras líneas de un archivo Java deben contener comentarios de entrada, de preferencia en este formato:</li>
</ul><pre class="java" name="code">/*
* Nombre de clase
*
* Versión
*
* Aviso de Copyright
*/</pre><ul><li> 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.</li>
<li> Un archivo Java debe tener la siguiente estructura:</li>
</ul><ol><li>Documentación de clase/interfaz</li>
<li>Declaración de clase</li>
<li>Variables de clase</li>
<li>Variables de instancia</li>
<li>Constructores</li>
<li>Métodos</li>
</ol><ul><li>Una línea de código no debe exceder de 80 caracteres. Las líneas que excedan esta longitud pueden dividirse de esta manera:</li>
</ul><pre class="java" name="code">function(longExpression1, longExpression2, longExpression3,
longExpression4, longExpression5);
</pre><br />
En la caso de sentencias condicionales:<br />
<br />
<pre class="java" name="code">if ((condition1 && condition2)
|| (condition3 && condition4)
||!(condition5 && condition6)) {
doSomethingAboutIt();
}
</pre><br />
Y para sentencias ternarias:<br />
<br />
<pre class="java" name="code">alpha = (aLongBooleanExpression) ? beta
: gamma;</pre><ul><li>Los comentarios deben utilizarse para brindar información adicional que no está explícita en el código fuente.</li>
<li>Los comentarios no deben estar delimitados en cajas hechas de asteriscos u otros caracteres.</li>
<li>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:</li>
</ul><pre class="java" name="code">/*
* Este es un comentario en bloque
*/
</pre><ul><li>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í:</li>
</ul><pre class="java" name="code">if (condition) {
/* Acciones para la condición */
...
}</pre><ul><li>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:</li>
</ul><pre class="java" name="code">/**
* La clase Example provee...
*/
class Example { ...
</pre><ul><li>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.</li>
<li>Se recomienda utilizar una declaración por línea. Entonces, es preferible utilizar esto:</li>
</ul><pre class="java" name="code">int level; // nivel de indentación
int size; // tamaño de la mesa
</pre>que esto:<br />
<pre class="java" name="code">int level, size;</pre><ul><li>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í:</li>
</ul><pre class="java" name="code">void MyMethod() {
int int1; // inicio del bloque del método
if (condition) {
int int2; // inicio del bloque "if"
...
}
}
</pre><ul><li>Tratar siempre de inicializar las variables locales al momento de declararlas.</li>
<li>Utilizar siempre llaves para sentencias condicionales (if). Evitar este formato:</li>
</ul><pre class="java" name="code">if (condition) //EVITAR!! UTILIZAR LLAVES!
statement;
</pre><ul><li>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 */:</li>
</ul><pre class="java" name="code">switch (condition) {
case ABC:
statements;
/* falls through */
case DEF:
statements;
break;
case XYZ:
statements;
break;
default:
statements;
break;
}</pre><ul><li>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:</li>
</ul><pre class="java" name="code">class Raster;
class ImageSprite;</pre><ul><li>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:</li>
</ul><pre class="java" name="code">run();
runFast();
getBackground();
</pre><ul><li>Las variables declaradas como constantes deben tener nombres en mayúscula, y las palabras internas deben estar separadas por guiones bajos (_). Así:</li>
</ul><pre class="java" name="code">int MIN_WIDTH = 4;
int MAX_WIDTH = 999;
int GET_THE_CPU = 1;
</pre><ul><li>No hacer las variables de instacia y de clase públicas a menos que se tenga una buena razón.</li>
<li>Evitar hacer referencia a variables o métodos de clase desde objetos. Usar para esto el nombre de la clase.</li>
</ul><pre class="java" name="code">classMethod(); //OK
AClass.classMethod(); //OK
anObject.classMethod(); //EVITAR!
</pre><br />
<div></div>certified-eshttp://www.blogger.com/profile/05251475836524665876noreply@blogger.com1