Páginas

lunes, 29 de diciembre de 2008

Supervivencia a la hora de escribir código

"Always code as if the person who will maintain your code is a maniac serial killer that knows where you live"

Y es que, nunca se sabe si la persona que va a mantener tu código es un programador o un asesino en serie. Pero claro, qué fue antes, ¿el huevo o la gallina?, porque ¿a quienes no os ha entrado ganas de matar a alguien tras ver algunas líneas de código? A mí sí, es algo que ya sabéis.

Por otro lado, si queréis mantener vuestro puesto de trabajo para siempre, corriendo el riesgo de ser asesinado por un asesino en serie claro está, siempre podéis usar las técnicas de escritura de código inmantenible. Si echáis un vistazo a estas prácticas seguro que os daréis cuenta que sois habituales en algunas de ella aunque de forma menos exagerada (o quizás no). Tal vez sea nuestro instinto de supervivencia lo que nos hace escribir código inmantenible pero paradójicamente esto nos pueda llevar a ser asesinados  por un asesino en serie.

viernes, 5 de diciembre de 2008

Spring - JPA - Hibernate

Estos días he tenido que montar el esqueleto para un nuevo proyecto. Para mi sorpresa la combinación de Frameworks que se requerían no estaba entre las disponibles de Appfuse Light así que tuve que montarla casi desde cero.

Son muchos los ejemplos y la documentación que se puede encontrar que hablan acerca de cómo montar JPA con Spring, pero como suele suceder casi todos proceden de un ejemplo original por lo que al final todos quedan reducidos a muy pocos que para colmo, están incompletos. Así pues, voy a hacer mi pequeña aportación y describiré el archivo de Spring al completo. No describiré cómo se realizan Test o cómo se crean claves primarias compuestas porque son temas que ya tratan bien en otros blogs.

En primer lugar, empezaré definiendo una entidad, sobre la que girará el ejemplo: User.

package es.whatabout.model; @Entity @Table(name = "USER") public class User{ @Id @Column(name = "ID") private Integer idUser; @Column(name = "FIRST_NAME") private String firstName; @Column(name = "LAST_NAME") private String lastName; ...get/set methods...


Como se puede ver, esta clase lleva anotaciones JPA que identifican a esta clase como un entidad, su clave primaria y el mapeo de sus atributos a la tabla y columnas correspondientes en la base de datos. Esta será la única clase que contenga anotaciones ya que el resto de la configuración, como la transaccionalidad, la configuraremos desde Spring.

Antes de definir la clase DAO crearemos un interfaz genérico y su implementación que proporcionará a nuestro dao particular y a todos los que generemos (y su implementaciones) de todos los métodos CRUD gracias a los tipos genéricos de Java.

import java.io.Serializable; import java.util.List; public abstract interface GenericDao <T, PK extends Serializable> { public abstract List<T> getAll(); public abstract T findByPK(PK id); public abstract void update(T object); public abstract void remove(T object); public abstract void insert(T object); }

Y su implementación.

package es.whatabout.dao.impl; import java.io.Serializable; import java.lang.reflect.ParameterizedType; import java.util.ArrayList; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.orm.jpa.support.JpaDaoSupport; import es.whatabout.dao.GenericDao; public class GenericDaoImpl extends JpaDaoSupport implements GenericDao { private static Log logger = LogFactory.getFactory().getInstance(GenericDaoImpl.class); private Class persistentClass; public GenericDaoImpl() { this.persistentClass = (Class) ((ParameterizedType) getClass() .getGenericSuperclass()).getActualTypeArguments()[0]; } public void insert(T t) { getJpaTemplate().persist(t); } public T findByPK(PK id) { return getJpaTemplate().find(persistentClass, id); } public List getAll() { List entities = new ArrayList(); try { String s = "select c from " + persistentClass.getSimpleName() + " c"; entities = getJpaTemplate().find(s); } catch (Exception e) { logger.error(e.getStackTrace()); } return entities; } public void remove(T t) { getJpaTemplate().remove(getJpaTemplate().merge(t)); } public void update(T object) { getJpaTemplate().merge(object); } }


T será la entidad que maneje nuestra clase dao mientras que PK será la clase de la clave primaria de ésta, que puede ser de tipo simple o compuesta (composed primary key)

A continuación crearemos una interfaz para un dao particular y su implementación utilizando el interfaz y la implementación de éste antes definido.

package es.whatabout.dao; import es.whatabout.model.User; public interface UserDao extends GenericDao<User, Integer> { }

Vemos que nuestro interfáz es muy simple, ya que dispone de los métodos CRUD del interfaz GenericDao. Del mismo modo, su implementación también será muy simple ya que ésta extiende de la implementación de GenericDao, GenericDaoImpl

package es.whatabout.dao.impl; import es.whatabout.dao.UserDao; import es.whatabout.model.User; public class UserDaoImpl extends GenericDaoImpl<User, Integer> implements UserDao{ }

Sólo queda definir el archivo de configuración de Spring:

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/aop http:// www.springframework.org/schema/aop/spring-aop-2.5.xsd"> <!-- archivo de configuracion para los datos de conexion --> <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="location" value="classpath:jdbc.properties" /> </bean> <!-- Transaccionalidad para todas las clases del paquete indicado --> <aop:config> <aop:advisor id="managerTx" advice-ref="txAdvice" pointcut="execution(* es.whatabout.dao.impl.*.*(..))" /> </aop:config> <!-- restringimos a solo lectura las transacciones metodos que comienzan por get --> <tx:advice id="txAdvice"> <tx:attributes> <tx:method name="get*" read-only="true" /> <tx:method name="*" /> </tx:attributes> </tx:advice> <!-- configuramos el transaction manager--> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="dataSource" ref="dataSource" /> <property name="entityManagerFactory" ref="entityManagerFactory" /> </bean> <!-- Conexion a bd con las propiedades del arhivo jdbc.properties--> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="${jdbc.driverClassName}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </bean> <!-- configuramos la Factory Manager, que trabajará con hibernate--> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> <property name="showSql" value="true" /> <property name="databasePlatform" value="${hibernate.dialect}" /> </bean> </property> <property name="jpaProperties"> <value>hibernate.show_sql=true</value> </property> </bean> <!-- configuramos LOG4J --> <bean id="log4jInitialization" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> <property name="targetClass" value="org.springframework.util.Log4jConfigurer" /> <property name="targetMethod" value="initLogging" /> <property name="arguments"> <list> <value>classpath:log4j.xml</value> </list> </property> </bean> <!-- inyeccion del entityManagerFActory a nuestro Dao particular--> <bean id="userDao" class="es.whatabout.dao.impl.UserDaoImpl"> <property name="entityManagerFactory" ref="entityManagerFactory" /> </bean> </beans>


Con este archivo de configuración ya podemos disponer de nuestro dao capaz de realizar todas las operaciones CRUD sin ningún problema.

Referencia: The Spring Framework - Reference Documentation, chapter 9, Introduction to Spring 2 and JPA
Código: descargar

jueves, 2 de octubre de 2008

Y llegó el final

Después de diez meses en el proyecto para el Grupo Antena3, que empezó cuatro meses antes de mi llegada, éste ha llegado su fin, al menos para la mayoría, yo entre ellos.

Se han cometido muchos errores, a todos los niveles y de toda clases, algunos incluso fuera de mi alcance y comprensión pero sin duda también ha habido muchas cosas positivas que merecen ser destacadas.

Entre ellas, la evolución de todos los miembros del proyecto y del equipo en conjunto que se puede ver reflejada en los cuatro portales desarrollados hasta ahora (y un quinto en camino) ya que cada portal que hemos desarrollado refleja las ganas y el esfuerzo del equipo por hacer las cosas mejor.

Sé que el propio equipo, desde los programadores hasta los gestores, e incluso el mismo cliente son conscientes de esta evolución resultado del esfuerzo personal a través de muchas horas de trabajo y las ganas de aprender y hacer las cosas bien por parte de todos los componentes.

Todos los miembros del equipo podemos y debemos, a pesar de todo, estar orgullosos de nuestro trabajo, de lo que hemos conseguido bajos unas condiciones muy duras (falta de documentación, tiempos de entrega imposibles, desplazamiento en cliente...).

Recuerdo cómo en mi primera etapa en Indra cuando al equipo nos caía un marrón decíamos entre risas: ¿y lo que vamos a aprender?. Ahora, tras tanto esfuerzo, yo le digo al equipo: ¿y lo que hemos aprendido?. Sin duda mucho. Por eso es tiempo de mirar atrás para contemplar todo aquello que hemos aprendido y reflexionar sobre qué aspectos debemos seguir mejorando. Sí sí, yo tengo que mejorar mi diplomacia y mi mano izquierda, lo sé lo sé.

Por otra parte, debido al tamaño del proyecto, son viarios los miembros del equipo que han tenido la oportunidad de dar un paso al frente y hacerse cargo de responsabilidades huérfanas cuando, como se dice comúnmente, no están pagadas. Algunos de ellos lo hicieron, dieron un paso al frente, tomaron responsabilidades y demostraron su capacidad. Qué gusto da ver a una persona aprovechar una oportunidad para demostrar su valía y salir triunfante. Otros, no lo hicieron y ha sido una lástima ya que estas oportunidades no se presentan todos los días.

Ahora, sólo queda esperar nuevo proyecto.

martes, 12 de agosto de 2008

La caducidad de lo evidente

A pesar de los años que han pasado, todavía recuerdo con exactitud aquel día de mi primer año en la facultad, hace ya 9 años, en el que estando cogiendo apuntes como un loco en la clase de Física mi fijé en cómo tomaba apuntes la compañera que tenía a mi izquierda. La chica tomaba apuntes de todo lo que decía o escribía en la pizarra el profesor como si de una mecanógrafa se tratase, cosa que me parecía absurdo e inútil, mientras que yo sólo tomaba nota de aquello que consideraba importante, no molestándome en anotar aquellas cosas que me parecían evidentes y que por tanto no se me olvidarían.

Con la llegada de los primeros exámenes, momentos en lo que tiré por primera vez de mis apuntes de forma seria, descubrí que mis apuntes eran un desastre puesto que había grandes lagunas sobre esas cosas tan evidentes que no me molesté en anotar. Pero aprendí. Aprendí que todas las cosas que en un momento dado en caliente parecen evidentes pueden dejar de serlo cuatro meses después.

Mis apuntes del segundo cuatrimestres fueron muy distintos. Eran muchos más gruesos ya que al igual que hacía la chica (que se ve que aprendió esta lección antes que yo) yo anotaba toda y cada una de las cosas que decía el profesor. Si éste decía algo evidente o que yo no consideraba importante en ese momento, lo anotaba. Que dos minutos después lo repetía, pues yo lo volvía a anotar como si fuera tonto.

Sin duda, esta decisión de considerarme tonto a la hora de coger apuntes me vino de gran ayuda el resto de años en la facultad.

Hoy en día, procuro extender esta práctica a mi profesión, tomando nota de cualquier chorrada que se diga en las reuniones o comentando los métodos que programo sabiendo con certeza que debido a las líneas que tiro a lo largo de una semana que en un mes no recordaré ni haber hecho tales métodos o clases. Y si yo no recordaré si tan si quiera haber programado esos métodos... ¿cómo voy a recordar qué hacen? Y peor aún, ¿cómo sabrá alguien que ni si quiera ha escrito esos métodos qué hace?

La respuesta es bien fácil: documentando el método. ¡Pero si es un método muy intuitivo que no necesita documentación! Se comenta. ¡Pero si está claro lo que hace! Se comenta. ¡Pero si hasta un tonto sabría lo que hace con sólo leer el nombre del método! Se comenta, que para tonto yo.

Así que para concluir: señores y señoritas, si no se consideran suficiente tontos como yo como para comentar lo evidente por favor, piensen en mí que sí lo soy y comenten todo.

domingo, 22 de junio de 2008

No reinventemos la rueda

A lo largo de mi corta carrera profesional, y sobre todo en los primeros años, me las he visto con frameworks caseros, he leído ficheros XML utilizando Dom, he subido ficheros al servidor extrayéndolos directamente de la Request y hecho muchas otras barbaridades. En algunos casos la necesidad de utilizar soluciones "caseras" era una imposición de la empresa, reacia a utilizar librerías ajenas a ella, aunque en la mayoría de los casos fue por desconocimiento.

Hoy en día es sabido por todos que Internet podemos llegar a encontrar cientos de frameworks y librerías de código abierto que pueden llegar a facilitarnos la vida de una forma asombrosa. Aun así, todavía podemos encontrar desarrolladores reacios a utilizar todas estas librerías testeadas y utilizadas en algunos casos cientos de miles de desarrolladores. De Struts, por ejemplo, he oído decir cosas como que "es un framework que está de moda y la gente lo utiliza para ser guay", "limita mucho" o "a mí me gusta hacer las cosas a mi modo, si todo te lo hace un framework no es divertido". No hace falta aclarar en estos casos las frases salieron de personas que nunca han trabajado con este framework o similar, que sólo saben desarrollar código espagueti o lo divertido que resulta trabajar con un framework casero.

¿Qué le lleva a una persona a tratar de implementar la solución a un problema que ya está resuelto? Si es desconocimiento, creo que queda excusado pero si has oído hablar de alguna herramienta que soluciona tu problema, ¿por qué no utilizarla? Puede haber algunos casos en los que alguien opte por su solución casera frente a una profesional considerando que tiene capacidad y tiempo para implementar dicha solución (insensato) pero creo que en la mayoría de los casos es debido al miedo. Este miedo al desconocimiento, que admito haber sentido alguna vez, hace buscar una y mil excusas para no utilizar estas librerías que tanto nos pueden facilitar la existencia: es un framework que nos limita mucho, sólo se utiliza porque está de moda, no se ajusta a mi problema, no tengo tiempo para documentarme, no me fio del código de otra persona, me limita mi "liberta creativa" y muchas más. ¡Ay! Cuándo daño hace tanta libertad creativa suelta.

Optar por una solución casera frente a una profesional si duda nos llevará a un error que nos hará perder tiempo y nos causará problemas hasta el fin de la existencia de nuestro código y a todo el que lo herede. Y el primer error que se comete se encuentra en la primera palabra de la frase anterior: optar.

Y es que, escoger una solución profesional frente a una casera no debe ser una opción sino un imperativo. ¿O es que alguien pretende realizar una aplicación Web 2.0 de forma casera sin las herramientas, librerías y framework de los que disponemos?. Sin duda imposible.

Cuando se nos plantea un problema no debemos preguntarnos cómo lo vamos a resolver, sino cuales de las soluciones ya implementas nos gusta más o se ajusta más a nuestra necesidad.

lunes, 5 de mayo de 2008

Roller

Hace unos meses tuve montar un sistema de blogs para el cliente para el que actualmente me encuentro trabajando. Básicamente sólo me dijeron dos cosas: échale un vistazo a WordPress y tienes dos semanas.

Qué poco me gusta eso de tener que valorar y escoger un producto en un par de días, de hecho la última vez que tuve que evaluar un producto en tan sólo dos días, como fue ConferenceRoom, lo que en un principio parecía bueno para el uso que se le iba a dar no resultó serlo tanto. Pero esa es otra historia.

Tras estudiar varias alternativas y la recomendación de Javi me decidí por Apache Roller y tengo que decir que fue todo un acierto.

Además de contar con todas la ventajas de ser un proyecto Apache ofrece todo el conjunto de características y funcionalidades necesarias en un sistema de blog: comentarios, calendario de publicaciones, nube de etiquetas, soporte para múltiples blog, usuarios y roles, etc.. Muy destacable la posibilidad que ofrece de creación de varias blogs. Por otro lado está desarrollado en Java con tecnologías que me son familiares como Velocity, Struts, Rome... lo que me hacía sentir cómodo frente a Wordpress, la otra opción fuerte, ya que mis conocimientos de PHP son prácticamente nulos.

Su puesta en marcha, en mi caso bajo Apache Tomcat y MySQL, es muy rápida y sencilla lo que permite empezar a trabajar con él en tan sólo 5 minutos (reales).

Una de las principales ventajas que encontré fue la facilidad con la que se puede personalizar un tema más allá de lo que una hoja de estilos permite gracias a su interfaz Web basado en Velocity que permite a través de plantillas y macros poder diseñar un tema de forma modular y totalmente personalizado. Ni qué decir de la documentación tan fantástica sobre todas las macros y plantillas que le acompaña y que nos abstrae de toda la implementación que hay por debajo.

Pero todo son alabanzas. Tras varios días de trabajo creando un tema personalizado me encontré con un problema: parte del código HTML que se generaba para algunas funcionalidades como el Captcha no estaba presente en ninguna plantilla o macro por lo que la maquetación resultaba muy difícil sin tener acceso a ese código. Fue una sorpresa, tras a bajarme el código fuente y montar el proyecto descubrir que este código HTML provenía de JAVA. No me parece lógico ni acorde con el resto del proyecto encontrar ese código HTML ahí.

En cualquier caso, a pesar de ese pequeño imprevisto que me obligó a modificar el código fuente y compilar algunos paquetes Roller es mi opinión es un producto muy recomendable.

jueves, 24 de abril de 2008

Google y mi persona

Recientemente el GT29 ha aprobado que los buscadores no puedan conservar nuestros datos más de seis meses, en contra de los 18 que vienen siendo actualmente. No sé qué pensaréis de ésto, si no tiene importancia que controlen nuestras búsquedas o si por el contrario estáis recelosos antes el Master Plan de Google.

Personalmente, aunque siempre he sido consciente de que Google (buscador que utilizo por defecto) podría guardar todas mis búsquedas, nunca me ha importado ya que no creo que la información que Google pueda llegar a obtener de mí a partir de mis búsquedas tenga mucha importancia. Pero a lo tonto a lo tonto, me he vuelto un usuario de Gmal, Picasa, Google Maps, Google Bloc de notas, Calendar, etc., etc. y siempre me encuentro logado a la cuenta a través de Firefox por lo que Google tiene en todo momento información sobre las búsquedas que realizo, qué paginas visito, cuáles son mis temas de interés, a qué sitios viajo, donde viven mis amigos, mis correos, cientos de fotos personales, mi teléfono, me agenda, etc., etc. ...

El otro día no sé cómo acabé viendo mi historial de Google, y fue sorprendente. Tal vez mis búsquedas una a uno no diga nada de mí, pero al verlas ahí, todas ordenadas, clasificadas... me di cuenta de que Google sabe más de mí de lo que yo creía y da un poco de miedo. Sin contar con que sabe cosas de mí que yo no sabía.

Podéis ver como además de poder permitirme publicar mi historial que los días que más búsquedas realizo son los jueves conTendencias 2 una media de 375 y que el pico se alcanza a las cuatro de la tarde. Quien lo iba a decir, después de comer. Un apartado interesante es el que Google denomina "Elementos interesantes" en el que recomienda búsquedas, páginas y videos relacionados con mis búsquedas. Para mi tranquilidad Google no anda muy fino en esta sección y me hace recomendaciones que creo que se salen bastante de mis búsquedas (tal vez sea por que mis cientos de búsquedas sobre Apache no dan mucho juego). Y respecto a los videos que me recomienda, pues no sé qué pensar... "Piratas de Silicon Valley", "Documental de código Linux" y "Steve Wozniak talks about Pirates of Silicon Valley"...

En fin, no sé qué seguiréis pensado, pero a mí me ha quedado una cosa muy clara y es que voy a tener que empezar a buscar más culos y tetas, porque ésto no puede ser.

viernes, 21 de marzo de 2008

VLA y Contact


En todas las ocasiones en la que he visto Contact (tres veces creo recordar) me he hecho muchas preguntas sobre el conjunto de antenas gracias a las que la doctora Ellie Arroway (Jodie Foster) descubre una señal extraterrestre a 4.46GHz proveniente de la estrella Vega, a 27 años luz. Desempolvando las clases de Radiocomunicación de mis años de universidad y gracias al siempre presente Google logro resolver muchas de las dudas que se me plantean y que he querido repasar a través de este post.

Contact
La pregunta principal que creo que nos hacemos todos al ver esas antenas en la película es: ¿para qué sirven?, es decir, está claro que una antena sirve para captar señales pero, ¿qué características hacen especial a ese conjunto de antenas que se ven y en qué se diferencia de una simple antena?.

Veamos algunos datos para ponernos en situación.

El nombre real de este conjunto de antenas denominado "Argus Array" en la gran pantalla es VLA (Very Large Array) y está situado en las Llanuras de San Augustin, entre las localidades de Magdalena y Datil, a unos 80 km al oeste de Socorro, New Mexico, EEUU. El VLA es un observatorio radioastronómico y como tal su función es la estudiar los objetos celestes y los fenómenos astrofísicos midiendo su emisión de radiación electromagnética permitiéndonos ver cosas imposibles de detectar por la astronomía óptica.

El observatorio consiste en 27 radio antenas independientes (la magia de Hollywood elevó este número a 131), cada una de las cuales tiene un diámetro de disco de 25 metros y un peso de 230 toneladas. Las antenas están alineadas a lo largo de tres brazos en forma de Y (cada uno mide 21 km). Usando las vías férreas que siguen cada uno de estos brazos y una locomotora especialmente diseñada, las antenas pueden ser resituadas físicamente a un número de posiciones preparadas denominadas A, B, C y D, siendo D la mayor con una separación de 36km con respecto al centro y A la menor, con una separación de 1Km.

La respuesta a la preguntas planteadas anteriormente se encuentra en la "resolución angular" ya que el objetivo del VLA es conseguir una mayor resolución angular de la que se podría obtener con una sólo de las antenas que lo forman.

La resolución angular, expresada normalmente en arcseconds, se podría definir como la habilidad de un dispositivo de imagen para medir la separación angular de dos puntos en un objeto, es decir, la separación entre dos objetos observados desde un punto distinto a éstos. Por tanto, cuanto mayor sea la resolución angular de un radiotelescopio mayor será la precisión de la imágenes que obtiene.

Matemáticamente puede ser aproximada como:
R = λ/D
donde λ es la longitud de onda de la radiación observada y D el diámetro del objetivo del telescopio.

Por tanto obtendremos mayor resolución cuanto mayor sea el diámetro de nuestra antena. Este resultado hace que la precisión de un radiotelescópio venga limitada (entre otros muchos factores) por el tamaño de la antena empleada y que para conseguir una resolución angular comparable a la que poseen los telescopios ópticos (que trabajan a una longitud de onda del orden de 100.000 veces menor) necesitaríamos un diámetro de antena de varias docenas de kilómetros, algo que se hace imposible en la práctica.

Este problema es resuelto por la interferometría, que se basa en el uso de varias antenas observando simultáneamente el mismo objeto, de manera que la resolución total del sistema es mucho mayor que la resolución de una antena por separado. De hecho, la resolución es equivalente a la que tendría una antena cuyo diámetro fuese igual a la separación máxima de las antenas.

Utilizando la interferometría la resolución angular puede ser aproximada como:
R = λ/B
donde λ es la longitud de onda de la radiación observada y B es la longitud de la máxima separación física entre dos telescopios del array, denominada baseline.
VLA

Puesto que la longitud de onda es inversamente proporcional a la frecuencia, la resolución angular dado una B variará según la frecuencia de radiación observada. El VLA trabaja en un rango de frecuencias comprendido entre los 74MHz y los 43GHz y es a los 43GHz y con tamaño del array configurado a 36km (D) cuando alcanza su resolución angular máxima: 0.04 arcseconds. Suficiente para distinguir una bola de golf sostenida por un amigo a 150 km (por supuesto, las bolas de golf contienen radiotransmisores de alta potencia...).

Dicho todo esto, creo que queda resuelta la duda de qué tiene el VLA de especial frente a una antena sola: una alta resolución evitando una única antena de tamaño descomunal.

El problema ahora es que indagar sobre este tema me ha creado una docena de dudas que antes no tenía... pero mejor cortar el post aquí.

Para los que tengan más curiosidad: NRAO - VLA

martes, 18 de marzo de 2008

Los no profesionales

Todos sabemos que el buen momento por el que pasa la Web 2.0 ha llevado a una gran demanda de los profesionales que rodean el mundo de Internet lo que a su vez ha provocado que la situación que se dio en este sector tras el estallido de la "burbuja tecnológica" o Burbuja.com, en la que los ingenieros no llegaban ni a mileuristas, cambie. Estos profesionales han pasado de acusar a las empresas de "esclavistas" a ganar un salario digno y ser acusados de "mercenarios" por éstas.

Muchas son las líneas que discuten alrededor de este tema, sin embargo, yo quería comentar algo en lo que creo que tanto los profesionales como muchas empresas estarán de acuerdo: la entrada en el sector de los no profesionales. Con 'no profesionales' no me refiero a gente sin titulación y/o no informáticos, sino a aquellas personas que no son capaces de hacer su trabajo de una forma seria. Gente sin interés en hacer las cosas bien y aprender y que tiene cabida gracias a la falta de personal cualificado en el sector. A lo largo de mi corta carrera profesional ya me he cruzado con gente de este tipo que no sólo hacen daño a la empresa y al proyecto sino a los propios compañeros ya que éstos se ven obligaos a desempeñar las labores asignadas en un principio a éstos 'no profesionales'. Y ni que decir tiene cómo la actitud de estas personas mina la moral del equipo.

Creo que la proliferación de este tipo de trabajadores va muy ligado a las consultoras, ya que en muchos casos (por no decir todos) a estas empresas sólo les interesa los benifícios sin importarles la mejor o peor cualificación de la gente que contrata y que luego manda a otras empresa. Si una persona con esta actitud entra en plantilla de una empresa dedicada al desarrollo, tiene todas las papeletas de ser despedida mientras que caso de estar en plantilla de una consultora simplemente es recolocada.

La solución a este tema es complicaca pero sin duda, se cual sea la fórmula, no debe dar cabida a este tipo de profesionales.

viernes, 4 de enero de 2008

Súper genérico

Terminé el año con un cambio de empresa y acabé en Indra (una vieja conocida), aunque he podido comprobar que hay ideas que van más allá de las empresas y me persiguen.

Hablo del caso particular de la tendencia de muchos programadores hacia lo genérico. En Cómo Produzco, mi anterior empresa, heredé el mantenimiento y desarrollo de un gestor de contenidos de mano de un Suizo que definía la aplicación como "súper súper genérica" aunque lo cierto es que aquello no tenía nada de genérico. Aquella aplicación tenía métodos con cientos de líneas de código donde abundaban los 'if' e 'if else' que hacían que los métodos fueran el anti-cristo de lo genérico. El resultado era un gestor de contenidos muy particular, nada genérico, inmantenible y hasta incompresible.

Ahora cambio de empresa y me vuelto a topar con el mismo problema. Problema que surge cuando para el programador lo prioritario es generalizar y olvida otros elementos importantes en la programación como son la modularidad, la robustez, el mantenimiento o la separación de aspectos... todo por con seguir algo 'super genérico' y que en muchos casos acaba volviendose en nuestra contra. Es lento, inmantenible, incomprensible, pero da igual, este método lo hace todo. Que necesitas una nueva funcionalidad, no pasa nada, otro parámetro de entrada, otro 'if' y ya tenemos un método aún más genérico... ves qué fácil.

Algo que gracias a Dios no estaba presente en el famoso gestor de Cómo pero que he sufrido en otros sitios es el uso indiscriminado de interfaces y clases abstractas... menuda historia también. Y es que hay personas que han escuchado campanas y no saben donde.

Por favor señores, no es pecado duplicar una línea de código. Hagan las vida más fácil al resto de programadores y olvídense de los métodos 'súper súper genéricos'.

"Un buen programador siempre piensa en lo que viene, pero no se vuelve loco por generalizarlo todo, sabe generalizar lo que realmente vale la pena generalizar." Brian W. Kernighan, Rob Pike