Aprendiendo continuamente

Aprendiendo continuamente
Autor: Clint Shank

Vivimos en tiempos interesantes. Conforme el desarrollo se distribuye en todo el mundo, se aprende que hay muchas personas capaces de hacer tu trabajo. Necesitas seguir aprendiendo para seguir siendo comercializable. De lo contrario, te convertirás en dinosaurio, atrapado en el mismo trabajo hasta que, un día, no serás necesario o tu trabajo será subcontratado con algún recurso más barato

Entonces, ¿qué hacer al respecto? Algunos empleadores son lo suficientemente generosos para proveer formación para ampliar tus habilidades. Otros pueden no ser capaces de ahorrar el tiempo o el dinero para entrenarte. Para jugar a la segura, necesitas tomar responsabilidad de tu propia educación.

Aquí hay una lista de las ideas para mantenerte en aprendizaje. Muchas de se pueden encontrar en Internet de forma gratuita:

  • Lee libros, revistas, blogs, feeds de twitter y sitios web. Si quieres profundizar en un tema, considera unirte a una lista de correo o grupos de noticias
  • Si realmente quieres estar inmerso en una tecnología, pon las manos en ello y escribe algún código.
  • Trata siempre de trabajar con un mentor, sentirse el mejor puede dificultar tu educación. Aunque puedes aprender algo de cualquiera, puedes aprender mucho más de alguien más inteligente o más experimentado que tú. Si no puedes encontrar un mentor, considera seguir adelante.
  • Utiliza mentores virtuales. Encuentra autores y desarrolladores en la web que realmente te gusten y lee todo lo que han escrito. Inscríbete en sus blogs.
  • Conoce sobre los frameworks y bibliotecas que usan. Saber cómo funciona algo te hace saber cómo usarlo mejor. Si son de software libre, estás de suerte. Usa el depurador para ir paso a paso por el código para ver qué hay tras el telón. Podrás ver el código escrito y revisado por personas realmente inteligentes.
  • Cada vez que cometas un error, arregles un error o estés en un problema trata de entender qué pasó. Es probable que alguien más haya tenido el mismo problema y haya escrito sobre él en algún lugar de la web. Google es útil en este caso.
  • Una buena manera de aprender algo es enseñando o hablando sobre eso. Como la gente está para escucharte y te hará preguntas, estarás motivado a aprender. Intenta un “almuerza y aprende” en el trabajo, un grupo de usuarios o con conferencias locales.
  • Inicia o únete a un grupo de estudio (a la comunidad de patrones) o a un grupo local de usuarios del lenguaje, tecnología o disciplina en la que estés interesado.
  • Asiste a conferencias. Y si no puedes ir, muchas conferencias ponen sus charlas en línea gratuitamente.
  • ¿Tienes un largo trayecto de la casa al trabajo? Escucha podcasts.
  • ¿Alguna vez has ejecutado las herramientas de análisis estático sobre tu código base o has mirado en las advertencias de tu IDE? Comprende qué están reportando y por qué.
  • Sigue la recomendación de The Pragmatic Programmer y aprende un nuevo lenguaje cada año. Al menos aprenderás una nueva tecnología o herramienta. El diversificar te dará ideas que puedes usar en tu pila tecnológica actual.
  • No todo lo que aprendas tiene que ser sobre tecnología. Aprende el dominio de lo que estás trabajando, así puedes comprender mejor los requerimientos y ayudar a resolver el problema del negocio. Aprender a ser más productivo – cómo trabajar mejor – es otra buena opción.
  • Vuelve a la escuela.

Sería bueno tener la capacidad que Neo tenía en The Matrix y simplemente descargar en tu cerebro la información que necesitas. Pero no podemos, por lo que requerirá un compromiso de tiempo. No tienes que gastar cada hora de vigilia aprendiendo. Un poco de tiempo, por ejemplo semanalmente, es mejor que nada. Existe (o debería haber) una vida fuera del trabajo.

La tecnología cambia rápidamente. No te quedes atrás.

Leer contribución original

Automatiza el estándar de codificación

Automatiza el estándar de codificación
Autor: Filip van Laenen

Probablemente a ti también te sucedió. Al comenzar un proyecto todo el mundo tiene buenas intenciones; las llamaremos “resoluciones de proyecto nuevo”. A menudo, muchas de estas resoluciones se documentan, y las que tienen que ver con el código terminan en el estándar de codificación del proyecto. Durante la primera reunión, el jefe de desarrollo revisa la documentación y, en el mejor de los casos, todos aceptan que intentarán respetarla. Sin embargo, una vez que el proyecto se pone en marcha, las buenas intenciones se van dejando de lado, una a una. Para cuando se entrega el proyecto, el código es un desastre y nadie parece saber por qué.

¿En qué momento salieron mal las cosas? Probablemente desde la reunión inicial. Algunos miembros no estaban prestando atención; otros no lo consideraron importante. Para peor, algunos no estuvieron de acuerdo y ya estaban planeando rebelarse en contra del estándar. Por último, algunos sí lo comprendieron y estuvieron de acuerdo pero, cuando la presión del proyecto fue demasiada, tuvieron que dejar de lado algunas convenciones. Aplicar un buen formato al código no te hará ganar puntos con un cliente que desea más funcionalidad. De hecho, respetar un estándar de codificación puede ser bastante aburrido si la función no está automatizada: intenta indentar una clase a mano para comprobarlo por tu cuenta.

Pero si es tan problemático, ¿para qué queremos un estándar de codificación? Una de las razones para darle un formato uniforme al código es que, de este modo, nadie se “adueñará” del código que escriba utilizando un formato propio. Probablemente queremos evitar que los programadores utilicen ciertos antipatrones, para así ahorrarnos algunos errores comunes. En general, un estándar de codificación debería hacer más fácil el trabajo grupal de un proyecto y mantener la velocidad de desarrollo desde el principio hasta el final. Se deduce entonces que todos deberían estar de acuerdo con el estándar; no ayuda que un programador utilice tres espacios para indentar y otro utilice cuatro.

Hay una gran cantidad de herramientas que se pueden usar para producir reportes de calidad de código, y para documentar y mantener el estándar de codificación, pero ésa no es la solución completa. El estándar debería automatizarse e imponerse siempre que sea posible. Por ejemplo, de las siguientes maneras:

  • Asegúrate de que parte del proceso de compilación sea darle formato al código, de modo que todo el mundo lo realice cada vez que se compile la aplicación.
  • Utiliza herramientas de análisis de código estático para encontrar antipatrones. Si se encuentra alguno, detén la compilación.
  • Aprende a configurar estas herramientas para que detecten antipatrones definidos por ti mismo y para tus proyectos específicos.
  • Mide la cobertura del código, pero también evalúa automáticamente los resultados. Nuevamente, detén la compilación si los resultados son muy bajos.

Intenta aplicar esto en todo lo que consideres de importancia, aunque no te será posible automatizarlo todo. Las cosas que no puedas marcar o corregir automáticamente podrían agruparse en un conjunto de directrices suplementarias al estándar automatizado, pero ten en cuenta que probablemente tú y tus colegas no lo respeten con la misma diligencia.

Por último, el estándar de codificación debería ser dinámico y no estático. A medida que el proyecto evolucione, sus necesidades también irán cambiando, y lo que quizás pareció inteligente en un principio, no será necesariamente inteligente algunos meses después.

Leer contribución original

Averigua qué haría el usuario (tú no eres el usuario)

Averigua qué haría el usuario (tú no eres el usuario)
Autor: Giles Colborne

Todos tendemos a asumir que los demás piensan como nosotros, pero no es así. Los psicólogos lo llaman efecto del falso consenso. Cuando la gente piensa o actúa de un modo diferente a nosotros es muy probable que (subconscientemente) los consideremos defectuosos en cierto modo.

Este prejuicio explica por qué a los programadores les cuesta tanto ponerse en el lugar de los usuarios. Los usuarios no piensan como programadores. Para empezar, pasan mucho menos tiempo usando computadoras y no saben, ni les interesa, cómo funcionan. Esto significa que no pueden recurrir a ninguna de las pilas de técnicas para resolver problemas que son tan comunes entre programadores. Los usuarios no saben reconocer los patrones ni indicaciones que los programadores manejan para trabajar y lidiar con las interfaces.

La mejor manera de entender cómo piensan los usuarios es observándolos. Pídele a un usuario que realice una tarea utilizando una aplicación similar a la que estás desarrollando. Asegúrate de que sea una tarea en serio: “agrega una columna de números” está bien; “calcula tus gastos del mes pasado” es mejor. Evita tareas muy específicas, como “¿puedes seleccionar estas celdas y agregar una fórmula SUMA debajo?”; es una pregunta algo obvia. Haz que el usuario te explique en detalle el proceso que realiza. No lo interrumpas. No intentes ayudarlo. Pregúntate todo el tiempo por qué está haciendo eso.

Lo primero que notarás es que los usuarios realizan una serie de cosas de manera similar. Intentan completar las tareas en el mismo orden y cometen los mismos errores en los mismos lugares. Deberías diseñar tu aplicación en torno a esta conducta base. Esto es algo que difiere de las reuniones de diseño, en las cuales se suelen hacer preguntas como: “¿y si el usuario quisiera…?”. Estos planteamientos conducen al desarrollo de funciones demasiado complejas y generan confusión sobre lo que los usuarios realmente desean. Observarlos eliminará esta confusión.

Verás que los usuarios suelen atascarse. Cuando tú te atascas, buscas una solución. Cuando los usuarios se atascan, reducen su foco de atención; se les vuelve más complicado ver una solución al problema en otro lugar de la pantalla. Ésta es una de las razones por las que los textos de ayuda son una mala solución al mal diseño de interfaces de usuario. Si debes agregar instrucciones o textos de ayuda, asegúrate de hacerlo justo al lado de las áreas problemáticas. Esta limitación de los usuarios es el motivo por el que los tooltips son más útiles que los menús de ayuda.

Los usuarios tienden a salir del paso de alguna manera. Encontrarán algo que funcione y se aferrarán a ello sin importar lo complejo que sea, pero es mejor proveer un modo obvio de hacer las cosas que dos o tres atajos.

También te encontrarás con que hay una marcada diferencia entre lo que los usuarios dicen que quieren y lo que realmente quieren. Lo cual es preocupante, ya que para averiguar los requerimientos lo normal es preguntarles. Es por esto que el mejor modo de relevar los requerimientos es observando a los usuarios. Pasar una hora con ellos es mucho más informativo que pasar un día suponiendo qué quieren.

Leer contribución original

La belleza está en la simplicidad

La belleza está en la simplicidad
Autor: Jørn Ølmheim

Hay una gran cita de Platón que es particularmente importante que los programadores sepamos y recordemos siempre: “La belleza en el estilo, la armonía, la gracia y el buen ritmo dependen de la simplicidad”. Creo que esta cita resume en una sola oración todos los valores a los que deberíamos aspirar los desarrolladores de software.

En nuestro código, nos esforzamos por lograr una serie de cosas:

  • Legibilidad
  • Mantenibilidad
  • Velocidad de desarrollo
  • La esquiva cualidad de la belleza

Platón nos está diciendo que el factor que nos permitirá alcanzar todas estas cualidades es la simplicidad.

¿Pero qué hace bello al código? Ésta puede ser una pregunta muy subjetiva. La percepción de la belleza depende mucho de nuestro trasfondo individual, tal como sucede con cualquier otra cosa. La gente formada en las artes tiene una percepción (o enfoque) sobre la belleza que es distinta a la de la gente formada en las ciencias. En el ámbito del arte se tiende a analizar la belleza del software comparándola con obras de arte, mientras que en el de las ciencias se habla de la simetría y la proporción áurea; se intenta reducir las cosas a fórmulas. En mi experiencia, la simplicidad es la base de los argumentos en ambos lados de la moneda.

Piensa en el código que has estudiado. Si no has pasado un buen tiempo leyendo el código de alguien más, deja de leer esto ahora mismo y ve a buscar algo de software libre para estudiar. ¡En serio, no es broma! Busca en Internet algo de código en tu lenguaje preferido, escrito por algún experto reconocido.

¿Ya has regresado? Bien. ¿Dónde estábamos? Ah, sí… Me he encontrado con que el código que me llama la atención y que considero hermoso siempre posee una misma serie de características. La más importante es la simplicidad. Me encuentro con que, sin importar qué tan complicada sea la aplicación o sistema en su totalidad, las partes individuales deben mantenerse simples: los objetos deben ser sencillos, poseer una única responsabilidad y contener métodos similarmente simples, con una tarea bien definida y nombres descriptivos. Algunos piensan que la idea de escribir métodos breves, de entre cinco y diez líneas de código cada uno, es bastante extrema, y algunos lenguajes hacen que sea muy difícil lograr esto, pero yo creo que esta brevedad es un objetivo deseable.

En resumen, para que el código sea bello debe ser simple. Cada pieza individual debe ser sencilla, y poseer responsabilidades y relaciones simples con otras partes del sistema. De este modo se logra que nuestros proyectos puedan mantenerse en el tiempo, con código limpio, sencillo y verificable, lo cual permite mantener una alta velocidad de desarrollo durante el tiempo de vida del proyecto.

La belleza nace y se encuentra en la simplicidad.

Leer contribución original

El camino al mejor rendimiento está lleno de sucias bombas de código

El camino al mejor rendimiento está lleno de sucias bombas de código
Autor: Kirk Pepperdine

Más frecuentemente que nunca, la optimización de rendimiento en un sistema requiere que alteres código. Cuando tenemos que alterar código, cada porción intrincadamente compleja o altamente acoplada es una sucia bomba de código, en espera de descarrilar el esfuerzo. La primera víctima de código sucio será tu agenda. Si el camino a seguir es suave, será fácil predecir cuando acabará. Los encuentros inesperados con el código sucio harán que sea muy difícil hacer una predicción cuerda.

Considera la situación en la que encuentras un punto de ejecución complicado. El curso normal de acción es reducir la fortaleza del algoritmo en cuestión. Digamos que respondes con “3-4 horas” a un estimado que te pide el gerente. Si aplicas el fix te darás cuenta rápidamente que has descompuesto una parte dependiente. Debido a que las cosas están relacionadas, a menudo están necesariamente acopladas, estas descomposturas son esperadas y se cuenta con ellas. Pero, ¿qué pasa si un arreglo en esa dependencia termina rompiéndose en otra parte dependiente? Por otro lado, entre más lejos está la dependencia de su origen, menos probable es reconocerla como tal y tomarla en cuenta en tu estimado. De repente tu estimado de 3-4 horas pueden elevarse fácilmente a 3-4 semanas. Con frecuencia esta inflación inesperada en la agenda sucede 1 o 2 días, todas al mismo tiempo. No es raro el ver refactorizaciones “rápidas” que eventualmente toman varios meses en ser completadas. En esos casos, el daño en la credibilidad y capital político del equipo responsable variará de severo a terminal. Si tan sólo tuviéramos una herramienta para ayudarnos a identificar y medir estos riesgos.

De hecho, tenemos varias maneras de medir y controlar el grado y profundidad de acoplamiento y complejidad de nuestro código. Las métricas de software puede ser usadas para contar las apariciones de característica específicas en nuestro código. Los valores de estos conteos se correlacionan con la calidad del código. Dos de estas métricas que miden el acoplamiento son las llamadas fan-in y fan- out. El fan-outestá definido como el número de clases referenciadas, ya sea directa o indirectamente, para una clase en particular. Puedes pensar en esto como un recuento de todas las clases que deben ser compiladas antes de que tu clase pueda ser compilada. El fan-in un conteo de todas las clases que depende de una clase en específico. Conociendo el fan-out y fan-in podemos calcular un factor de inestabilidad usando I = fo / (fi + fo). Conforme se aproxima a 0, el paquete se vuelve más estable. En cuanto se aproxime a 1, el paquete se convierte en inestable. Los paquetes que son estables son objetivos de bajo riesgo, mientras que los paquetes inestables son más propensos a estar llenos de sucias bombas de códigos. La meta de la refactorización es mover I lo más cercano a 0.

Cuando usamos métricas debemos recordar que sólo son reglas empíricas. Basándose puramente en las matemáticas puedes ver que el incremento de fi sin cambiar fo moverá I mas cerca a 0. Sin embargo hay una desventaja en tener el valor fan-in alto, pues estas clases serán más difíciles de modificar sin romper dependencias. Al no tener en cuenta el fan-out no estás reduciendo realmente el riesgo, por lo que debe aplicarse algún balance.

Una desventaja de las métricas de software es que la gran cantidad que números que producen las herramientas pueden ser intimidantes para los no iniciados. Dicho esto, las métricas de software pueden ser una poderosa herramienta en nuestra lucha por un código limpio. Pueden ayudar a identificar y eliminar las sucias bombas de código antes de que sean un serio riesgo al ejercicio de optimización del rendimiento.

Leer contribución original

Codificando con la razón

Codificando con la razón
Autor: Yechiel Kimchi

Trata de averiguar manualmente la correctitud de software resulta en una prueba formal más larga y propensa a errores que el código mismo. Las herramientas automatizadas son preferibles, pero no siempre posibles. Lo siguiente describe una ruta intermedia: razonamiento semi-formal sobre la dicha correctitud.

El planteamiento de fondo es dividir todo el código en cuestión de secciones cortas –desde una sola línea, como invocar a una función, hasta bloques de menos de 10 líneas– y discutir acerca de su exactitud. Los argumentos sólo necesitan ser suficientemente fuertes para convencer al compañero del diablo como tu pareja de programación.

Una sección debería ser elegida de modo que en cada terminal el estado del programa (léase: el conteo del programa y los valores de todos los objetos “vivos”) satisface una propiedad fácilmente descrita y que la funcionalidad de esa sección (transformación de estado) sea fácil de describir como una sola tarea –estos harán el razonamiento más sencillo–. Tales propiedades terminales generalizan conceptos como precondinción y poscondición de funciones, e invariantes para ciclos y clases (con respecto a sus instancias). La lucha para que las secciones sean independientes de las otras tanto como sea posible simplifica el razonamiento y es indispensable cuando estas secciones son modificadas.

Muchas de las prácticas de codificación que son bien conocidas (aunque quizás menos seguidas) y consideradas “buenas” hacen el razonamiento más fácil. Por lo tanto, sólo con la intención de razonar sobre tu código ya estás comenzando a pensar acerca de un mejor estilo y estructura. Como era de esperarse, la mayoría de estas prácticas pueden ser revisadas por analizadores de código estático:

  1. Evita usar sentencias goto, ya que hacen las secciones remotas altamente interdependientes
  2. Evita usar variables globales modificables, debido a que hacen dependientes a todas las secciones que las usan.
  3. Cada variable debería tener el mínimo alcance posible. Por ejemplo, un objeto local puede ser declarado justo antes de su primer uso.
  4. Haz los objetos inmutables cuando sea relevante.
  5. Haz al código leíble usando espacios, tanto horizontales como verticales. Por ejemplo, alineando estructuras relacionadas y usando una línea vacía para separar dos secciones.
  6. Haz al código semi-documentable escogiendo nombres descriptivos (pero relativamente cortos) para los objetos, tipos, funciones, etc.
  7. Si necesitas una sección anidada, crea una función.
  8. Crea tus funciones cortas y enfocadas en una sola tarea. El viejo límite de 24 líneas aún aplica. A pesar que los tamaños de las pantallas han cambiado, nada ha cambiado en la cognición humana desde la década de los sesenta.
  9. Las funciones deben tener pocos parámetros (cuatro es buen límite superior). Esto no restringe los datos comunicados a las funciones: agrupando parámetros relacionados en un objeto beneficia desde sus invariantes y ahorra razonamiento, tales como su coherencia y consistencia.
  10. En general, cada unidad de código, desde un bloque hasta una biblioteca, debería tener una interface rala. Menos comunicación reduce el razonamiento requerido. Esto significa que los getters que regresan estados internos son una liabilidad –no pidas a un objeto la información que ya tiene–. En otras palabras, la encapsulación es todo sobre interfaces limitadas.
  11. Para poder preservar las clases invariantes, el uso de setters no debería ser recomendada, debido a que los setters tienden a permitir invariantes que gobiernan el estado de un objeto hacia su ruptura.

Conforme se razone sobre la correctitud, argumentar sobre tu código te ofrece entendimiento sobre él. Comunica sus descubrimientos para el beneficio de todos.

Leer contribución original

Codifica en el lenguaje del dominio

Codifica en el lenguaje del dominio
Autor: Dan North

Imagínate dos códigos bases. En uno te encuentras esto:

if (portfolioIdsByTraderId.get(trader.getId())
  .containsKey(portfolio.getId())) {...}

Te rascas la cabeza imaginándote para que podría servir este código. Parece que está obteniendo un ID desde un objeto comerciante (“trader”), usándolo para obtener aparentemente un mapa de mapas y, entonces, está viendo si otro ID desde un objeto portafolio (“portfolio”) existe en el mapa interior. Te rascas la cabeza un poco más. Ves la declaración del método portfolioIdsByTraderId y descubres esto:

Map<int, Map<int, int>> portfolioIdsByTraderId;

Poco a poco te das cuenta que podría tener algo que ver con que un comerciante tenga acceso a un portafolio en particular. Y, por supuesto, encontrarás el mismo fragmento de búsqueda –o un similar-pero- ligeramente-diferente fragmento de código– en el momento en que a alguien le importa si un comerciante tiene acceso a un portafolio en particular.

En el otro código base te encuentras con esto:

if (trader.canView(portfolio)) {...}

No hay rascado de cabeza. No necesitas saber cómo lo sabe un comerciante. Quizás es uno de esos mapas de mapas escondidos dentro. Pero es un asunto del comerciante, no tuyo.

Ahora, ¿en cuál de estos códigos te gustaría estar trabajando?

Hubo un tiempo en que sólo teníamos unas muy básicas estructuras de datos: bit, bytes y caracteres (realmente sólo bytes que pretendíamos que fueran letras y puntuaciones). Tener decimales eran un poco truculento porque nuestros números de base 10 no trabajan muy bien en binario, así que teníamos varios tamaños de tipos de punto flotante. Entonces vinieron las matrices y las cadenas (realmente sólo matrices distintas). Teníamos pilas, colas, hashes, listas ligadas y listas salteadas y muchas otras excitantes estructuras de datos que no existían en el mundo real. La “Ciencia Computacional” se trataba de gastar mucho esfuerzo mapeando el mundo real en nuestras estructuras de datos restrictivas. Los verdaderos gurús podrían incluso recordar cómo lo habían logrado.

¡Entonces tuvimos los tipos definidos por el usuario! Está bien, esto no es noticia, pero fue un cambio en el juego, de alguna manera. Si tu dominio contiene conceptos como negociantes y portafolios, podías modelarlos con tipos llamados, digamos, Comerciantes y Portafolio. Pero, más importante que esto, también puedes modelar relaciones entre ellos usando términos de dominio.

Si no codificas usando términos del dominio estás creando un entendimiento tácito (léase: secreto) de que este valor de tipo entero que está por ahí significa la manera de identificar a un comerciante, donde ese valor de tipo entero por allá es la manera de identificar un portafolio. (¡Mejor no confundirlos!) Y si representas un concepto de negocio (“a algunos comerciantes no les está permitido ver algunos portafolios –es ilegal–”) con un algoritmo, digamos la existencia de relaciones en un mapa de claves, no le estás haciendo ningún favor a los chicos de auditoría y quejas.

El programador de junto quizás no sepa el secreto, así que ¿porqué no hacerlo explícito? Usar una llave como el término de búsqueda de otra llave que realiza la revisión de una llave existente no es terriblemente obvio. ¿Cómo se supone que alguien intuya que ahí están implementadas las reglas de negocio que previenen conflictos de interés?

Realizar conceptos explícitos del dominio en tu código significa que otros programadores pueden adquirir la intención del código mucho más fácilmente que intentar meter un algoritmo en lo que entienden sobre el dominio. Esto también significa que cuando el modelo del dominio evoluciona –es decir, que tu entendimiento se incrementa– estés en una buena posición para evolucionar el código. En conjunto con una buena encapsulación, aumenta la oportunidad de que la regla exista sólo en un lugar y que puedes cambiarla sin que el código dependiente se dé cuenta.

El programador que venga unos cuantos meses después a trabajar con el código te lo agradecerá y quizás ese programador seas tú.

Leer contribución original

Codificación Ubuntu para tus amigos

Codificación Ubuntu para tus amigos
Autor: Aslam Khan

A menudo escribimos código en el aislamiento y refleja nuestra interpretación personal de un problema, así como una solución personalizada. Podemos ser parte de un equipo y aun así estar aislados. Olvidamos todo tan fácilmente que este código creado en el aislamiento será ejecutado, usado, extendido y ha confiado a otros. Es fácil pasar por alto el aspecto social de la creación de software. Crear software es un ejercicio técnico mezclado con un ejercicio social. Sólo necesitamos levantar nuestra cabeza para darnos cuenta de que no estamos trabajado aisladamente y tenemos responsabilidades compartidas con respecto a incrementar la probabilidad de éxito de todos, no sólo del equipo de desarrollo.

Podemos escribir código de buena calidad en el aislamiento, mientras nos perdemos en nosotros mismos. Desde alguna perspectiva, eso es un enfoque egocéntrico (no ego como en arrogante, sino ego como en lo personal). También es una visión Zen y es sobre ti, en ese momento de la creación de código. Siempre intento vivir en el momento porque ayuda a estar más cerca de la calidad, pero entonces vivo en mi momento. ¿Qué pasa con el momento de mi equipo? ¿Es mi momento el mismo que el del equipo?

En Zulu, la filosofía de Ubuntu se resume en “Umuntu ngumuntu ngabantu”, que se podría traducir como “una persona es una persona a través de (otras) personas”. Me siento mejor porque tú me haces mejor a través de tus buenas acciones. La otra cara es que eres peor en lo que haces cuando soy malo en lo que hago. Entre desarrolladores, podemos reducirlo a “un desarrollador es un desarrollador a través de (otros) desarrolladores”. Si lo llevamos hasta el metal, entonces “el código es código a través de código (de los otros)”.

La calidad del código que escribo afecta la calidad del código que tu escribes. ¿Qué pasa si mi código es de baja calidad? Incluso si escribes un código muy limpio, los puntos donde usas mi código es donde la calidad de tu código se degrada. Puedes aplicar muchos patrones y técnicas para limitar el daño, pero el daño ya está hecho. He causado que tú hagas más de lo que necesitas hacer simplemente porque no pensé en ti cuando estaba viviendo mi momento.

Puede que considere mi código como limpio, pero puedo aún hacerlo mejor sólo codificando Ubuntu. ¿A que se parece el código Ubuntu? Se ve como un buen código limpio. No se trata del código, el artefacto. Se trata del acto de crear ese artefacto. Codificar para tus amigos con Ubuntu ayudará a que tu equipo viva tus valores y refuerce sus principios. La siguiente persona que toque tu código, en cualquier forma, será una mejor persona y un mejor desarrollador.

El Zen se trata de lo individual. Ubuntu es acerca del Zen para un grupo de personas. Muy, muy raramente creamos código para nosotros mismos.

Leer contribución original

El código es diseño

El código es diseño
Autor: Ryan Brush

Imagínate despertar mañana y saber que la industria de la construcción ha hecho el avance del siglo. Millones de robots baratos e increíblemente rápidos pueden fabricar materiales de la nada, tener gasto energético cercano a cero y se pueden reparar a sí mismos. Y se pone mejor: al darle un no-ambiguo plano para un proyecto de construcción, el robot puede construirlo sin la intervención humana, todo ello a un costo insignificante.

Uno puede imaginar el impacto en la industria de la construcción, pero ¿qué pasaría más adelante? ¿Cómo cambiaría el comportamiento de los arquitectos y diseñadores si los costos de construcción fueran insignificantes? Hoy en día modelos físicos y computacionales son creados y rigorosamente probados antes de invertir en la construcción. ¿Nos preocuparíamos si la construcción fuera esencialmente gratis? Si un diseño se colapsa, no hay problema, sólo encuentra qué estuvo mal y pon a nuestros robots mágicos a construir otro. Hay otras implicaciones. Con modelos obsoletos, los diseños sin terminar evolucionan mediante la construcción y mejoran en repetidas ocasiones hacia una aproximación de la meta final. Un observador casual podría tener problemas distinguiendo un diseño inacabado y un producto terminado.

Nuestra capacidad para predecir líneas de tiempo se esfumaría. Los costos de construcción son calculados más fácilmente que los costos de diseño –sabemos el costo aproximado de instalar una viga y cuántas vigas necesitamos–. Como las tareas predecibles se reducen a cero, la época del diseño menos predecible empieza a dominar. Los resultados se producen con mayor rapidez, pero los plazos fiables escapan.

Por supuesto, se sigue aplicando la presión de una economía competitiva. Con los costos de construcción eliminados, una empresa puede completar rápidamente un diseño ganando una esquina en el mercado. El tener pronto los diseños terminados se convierte en el empuje central de las firmas de ingeniería. Inevitablemente, alguien no familiarizado con el diseño verá una versión invalidada, ve una ventaja del mercado al liberar temprano y dice “esto parece lo suficientemente bien”.

Algunos proyectos de vida o muerte serán más diligentes, pero en muchos casos los consumidores aprende a sufrir el diseño incompleto. Las empresas siempre puede mandar robots mágicos a “parchar” los edificios y vehículos rotos que venden. Todo esto apunta a una conclusión intuitiva: nuestra única premisa era una dramática reducción en los costos de construcción, con el resultado de que la calidad ha empeorado.

No debería sorprendernos que la historia de arriba fuera ejecutada por el software. Si aceptamos que el código es diseño –un proceso creativo en vez de uno mecánico– la crisis del software se explica. Ahora tenemos una crisis de diseño: la demanda de diseños validados y de calidad excede nuestra capacidad de crearlos. La presión por usar diseños incompletos es fuerte.

Afortunadamente, este modelo también ofrece pistas de cómo mejorar. Las simulaciones físicas equivalen a pruebas automatizadas; el diseño de software no está completo hasta que es validado con una batería de pruebas brutal. Para hacer tales pruebas más efectivas estamos encontrando maneras de frenar en el gran espacio de estados de los grandes sistemas. Los lenguajes mejorados y las prácticas de diseño nos dan esperanza. Finalmente, hay un hecho ineludible: los grandes diseños son producidos por grandes diseñadores dedicados a la maestría de su oficio. El código no es diferente.

Leer contribución original

Comenta sólo lo que el código no dice

Comenta sólo lo que el código no dice
Autor: Kevlin Henney

La diferencia entre teoría y práctica es más grande en la práctica que en la teoría –una observación que aplica a los comentarios–. En teoría, la idea general de comentar código suena como algo útil: ofrece al lector detalles, una explicación de lo que está pasando. ¿Qué podría ser más útil que ser útil? En la práctica, sin embargo, los comentarios frecuentemente se convierten en una plaga. Así como otras formas de escritura, existen habilidades para escribir buenos comentarios. Mucho de esa habilidad es saber cuándo no escribirlos.

Cuando el código está mal formado, los compiladores, intérpretes y otras herramientas se aseguran de objetar. Si el código es, de algún modo, funcionalmente incorrecto, las revisiones, los análisis estáticos, las pruebas y el uso diario en un ambiente de producción eliminará muchos de los errores. ¿Qué me dices de los comentarios? En The Elements of Programming Style, Kernighan y Plauger notaron que “un comentario tiene valor de cero (o negativo) si es erróneo”. Y, sin embargo, tales comentarios ofrecen poco y sobreviven en un código base de una manera que los errores de codificación nunca pueden. Proporcionan una fuente constante de distracción y desinformación, un lastre sutil pero constante en el pensamiento de un programador.

¿Qué hay con los comentarios que no están técnicamente mal, pero no agregan valor al código? Son ruido. Los comentarios que parlotean el código no ofrecen algo extra al lector –decir algo una vez en código y otra vez en lenguaje natural no lo hace más verdadero o más real–. El código comentado no es código ejecutable, por lo que no tiene un efecto útil para el lector, ni en tiempo de ejecución. También se vuelve rancio fácilmente. Los comentarios relacionados a la versión y el código comentado tratan de abordar preguntas sobre las versiones y la historia. Estas preguntan ya han sido respondidas, de forma más eficiente, por las herramientas de control de versiones.

Una prevalencia de comentarios ruidosos e inconsistentes en el código base anima a los programadores a ignorar todos los comentarios, ya sea saltándolos o tomando medidas activas para ocultarlos. Los programadores tienen muchos recursos y le darán vuelta a cualquier cosa que se perciba como dañino: plegando los comentarios; cambiando el esquema de color, así los comentarios y el color de fondo se igualan; creando scripts para filtrar comentarios. Para salvar el código base de las malas aplicaciones de la ingenuidad del programador, y reducir el riesgo de pasar por alto cualquier comentario de valor genuino, los comentarios deberían ser tratados como si fueran código. Cada comentario debería agregar algo de valor al lector, de otro modo es un desperdicio que debería ser removido o reescrito.

¿Qué lo califica como valioso? Los comentarios deberían decir algo que ¿el código no hace y no puede decir. Un comentario que explica lo que ¿una pieza de código ya debería decir es una invitación para cambiar la ¿estructura del código o las convenciones de codificación para que hable ¿por sí mismo. En vez de compensar la pobreza en el nombre de los ¿métodos o de las clases, renómbralos. En vez de comentar secciones en ¿funciones largas, extrae las funciones pequeñas cuyos nombres capturen ¿las intenciones de las anteriores partes. Intenta expresar tanto como ¿sea posible a través del código. Cualquier déficit entre lo que puedes ¿expresar en código y lo que deseas expresar en su totalidad se ¿convierte en un candidato plausible para un comentario útil. Comenta lo ¿que el código no puede decir, no lo que el código no dice.

Leer contribución original