2016/04/27

Reutilizar código

Hay programadores que parecen tomar la reutilización de código como un mandamiento que hay que cumplir mecánicamente para ser un buen programador.

Pero, como aprendimos con los diez mandamientos, la bondad de algo no está tanto en obedecer mecánicamente sino en comprender el por qué.

[Leer más]

2016/04/16

Sobre frameworks

Algunos desarrolladores dicen que prefieren no usar frameworks.

Empiezan desde cero y van completando el sistema con ayuda de los patrones y librerías que les parecen más adecuados.

Felicidades, eso es un framework. Cualquier desarrollador que quiera corregir o agregar algo al sistema tendrá que familiarizarse con las peculiaridades de ese nuevo esquema.

Seamos claros. Siempre se usa un framework. Si no es el de los demás, es el tuyo. Si no lo tienes hecho, irá surgiendo en el proceso.

¿Cuál es la ventaja de un framework propio? Que si el desarrollo es reciente probablemente estés muy familiarizado con él y puedas hacer cualquier cosa más rápido y mejor que alguien que no lo conoce (todos los demás).

En cierto modo, usar un framework propio, alimenta la ilusión de falsa competencia, porque eres el mejor en el juego (que nadie ha practicado tanto como tú).

Por supuesto que hay proyectos que requieren una solución a la medida, particular y específica. ¿Pero pertenece tu proyecto a ese grupo exclusivo de clientes que necesita un sastre? ¿O es como el 90% de los proyectos usuales? Quizás seas un buen costurero, quizás seas un buen sastre, pero, ¿que es lo que realmente necesita el cliente? ¿se sentirá cómodo en la playa con sus shorts de diseño? (el cual no puede forzar mucho porque no ha sido tan probado como los más baratos shorts que pudo haber elegido).

Muéstrame alguien que reniegue de usar un framework conocido y posiblemente encontremos que, aunque sea buen programador, no domina ninguno. Es natural querer usar lo que mejor manejamos, pero no es justo negar la virtudes de lo que no hemos probado o aún no conocemos a profundidad.

No existe tal cosa como un proyecto hecho sin frameworks, sólo con estándares. Lo que en realidad hay es un nuevo framework surgido en el transcurso del desarrollo, impregnado con las particulares opiniones del desarrollador sobre como se deben hacer las cosas correctamente, probablemente con escasa documentación y comunidad mínima (esas cosas requieren más horas hombre que las que pueda pagar cualquier cliente).

Existe la posibilidad de que el nuevo framework tenga alguna ventaja sobre los demás. Entonces, la manera más eficiente de que evolucione es que se vuelva open source. Si realmente es bueno, la comunidad llegará para usarlo, probarlo, documentarlo y difundirlo.

Encontrarás muchas razones por la que un proyecto open source es una mejor opción para hacer mejor software.

Cuando se hace software es importante reutilizar aquello que es bueno. Para reutilizar software, o para mantenerlo, con comodidad, es importante documentación y ejemplos. Para documentar y discutir casos y soluciones, una buena comunidad es grandiosa.

Pienso que un software es mejor cuanto más mantenible es. Algunos piensan que es mejor lo que corre más rápido, pero no se puede hacer muchas optimizaciones sobre código ilegible (y la optimización prematura es el camino a todo tipo de problemas). Otros piensan que es mejor software si usas menos líneas de código, pero no podrá evolucionar con facilidad si esa obsesión de menos líneas conduce a código menos legible que requiera numerosos hacks mentales tan sólo para aclarar la intención.

Además, el código lo va a correr una computadora, a la que le da lo mismo. Todas esas cosas de buenas prácticas, organización, frameworks, etc, no es por ellas, sino para la gente. Así que es más importante escribir buen código para la gente.

Pienso que un código es más mantenible si es más legible y si es más fácil de depurar. No importa que sea muy largo o parezca inocente, porque esa sencillez permitirá obtener versiones optimizadas también con facilidad.

Aprender un framework cuesta, pero usar un framework conocido puede hacer que tu proyecto sea más mantenible y una mejor opción para tu cliente. Si te gusta crear cosas nuevas, suele haber espacio para plugins (y mejor feedback para tu trabajo). Si quieres realmente ser autor de un framework, aprenderás mucho de la comunidad antes de intentar crear una. Puede que te ayude tener mejor perspectiva conocer a otros con muy alto nivel colaborando con entusiasmo en proyectos open source. Aprenderás a valorar la gran cantidad de tiempo y conocimientos que se puede condensar en un proyecto abierto, más allá de lo que puedas imaginar.

2016/03/12

#NoEstimates

   

https://oikosofy.safechkout.net/NoEstimates-Book  

Un desarrollador (o su representante) conversa con el cliente (o su representante):

- ¿Qué es lo que se necesita hacer?
- ABC, ¿cuánto tiempo te tomará?
- x

Luego de x tiempo:

- Ya pasó x, ¿cómo vamos?
- Aún en la tarea
- Vamos retrasados

Finalmente:

- Ya está listo ABC
- Ok, pasa la prueba. Pero se atrasaron y%
- Ok, trataremos de hacerlo mejor

Situaciones de ese tipo se presentan durante el desarrollo de un producto y nos parecen normales. Sin embargo, expresan una serie de supuestos que no son necesariamente ciertos. Ni siquiera relevantes.

¿Qué es lo se necesita hacer?
Supone que el cliente (o su representante) saben lo que se necesita hacer. Casi siempre no es así, y determinar lo que se necesita hacer es algo que habrá que resolver. ¿Qué es lo que quieres resolver? suele ser una mejor pregunta.  

¿Cuánto tiempo te tomará?
¿Cuánto tiempo toma hacer algo? Si has hecho algo similar varias veces, puedes tener una idea. Pero como programador habrás experimentado que muchas veces hacer exactamente lo mismo, con la misma gente, toma un tiempo diferente. Algunas razones:
  • La programación es una actividad creativa
  • Las actividades creativas requieren una buena conexión con el subconciente
  • La conexión con el subconciente es sensible al humor, el stress, etc
  • Los equipos de trabajo están conformados por personas
Y, si nunca has hecho algo similar, quizás sientas que debas importar la respuesta que otro desarrollador similar, de otro equipo similar, para un cliente similar. Pero eso no es correcto por algunas razones:
  • El trabajo no lo va a realizar ese desarrollador ni ese equipo para tu cliente en tu contexto. Cada equipo es distinto y el rendimiento de un equipo es sensible al contexto.
  • En realidad, no estás seguro de que lo que hay que hacer sea similar a lo que ellos hicieron.
Cuando nunca has hecho algo similar, es necesario empezar a hacer y ver qué tal lo vas haciendo, antes de poder ofrecer alguna estimación sincera.

Vamos atrasados
Supone que la estimación fue correcta. Si hubieras dicho una cifra mayor estarías a salvo. Algo como el doble más el 10% más el número que pensaste. De hecho, muchos desarroladores, o sus representantes, usan ese tipo de tácticas para estar tranquilos; pero el cliente, o su reprepresentante, saben que puede pasar y entonces se produce un regateo de tiempos estimados.

Cualquier supuesto atraso o adelanto es irreal si la estimación no es correcta. ¿Es correcta la estimación? Ya vimos que no es posible que lo sea.

Imagina que un entrenador se acerca te mira y te dice 'mmm tu debes estar saltando unos 150 cm'. 'Sí señor', respondes, mientras le ayudas a colocar la valla. Tomas tu distancia, corres y saltas, llevándote la valla de encuentro. 'Qué mal' dice el entrenador. 'Sí señor', respondes. Si hubieran puesto la vaya a 60 cm hubiera sido 'Qué bien, excelente'. Así de absurda es la situación.

Sería mejor aprender a aceptar las capacidades reales de la gente y trabajar con eso, en lugar de intentar hacer pronósticos y calificaciones arbitrarias.

Además, considerar que, tanto para el clima como para los humanos, todos los pronósticos pueden fallar.

Aprendiendo a programar

Aunque términos como ingeniería de software y ciencias de la computación dan la impresión de que hay un dominio del tema, en realidad estamos aprendiendo a programar.

Quizás no se trata tanto de algoritmos óptimos, sino de encontrar un proceso sostenible que permita desarrollar sistemas también sostenibles. Lo óptimo será alcanzado eventualmente.

Persiguiendo la ilusión del óptimo inmediato es que se suele perder el camino, del mismo modo que un artista principiante que trata de hacer un cuadro trabajando perfectamente cada centímetro cuadrado, para lograr un resultado que no cuadra porque las partes no siguen un bosquejo que nunca trazó.

Encontramos buenas prácticas en programación imperativa. Pero el retorno de la programación funcional parece indicar que son soluciones creadas para problemas generados por usar el modelo imperativo en primer lugar. 

Así, estamos en camino de aprender el oficio de programar.

Programación mental

En los años 70, cuando los ciclos computacionales eran muy caros, nadie podía imaginar usar las computadoras para diseñar software. El software era diseñado en papel, para luego ser codificado por programadores y funcionara a la primera, si era posible.

En las escuelas de programación se incentivaba a la gente hacer todo en papel antes de escribir una línea de código. Correr una línea de código en una computadora era más caro que correrlas en la cabeza, así que los programadores usaban sus cabezas, y mucho papel, como simuladores de computadoras.

En los años 80, con el ascenso de la computación personal, hacer software se volvió una actividad comercial importante. Así que la industria y las universidades impulsaron más la creación de productos de software. Como venían haciendo, tratando de usar la experiencia que tenían en desarrollar otros tipos de productos. Sin embargo, la ejecución de los proyectos de desarrollo de software empezó a mostrar que había cosas importantes que funcionaban de modo diferente.

En los años 90, cuando los ciclos computacionales ya no costaban lo que antes, los programadores se dieron cuenta que tenía más sentido usar la misma computadora para explorar con ella las cosas que quisieramos que ejecute, en lugar de seguir intentando que nuestros cerebros traten de imitar ese proceso.

Considerar los icebergs y los andamios

Lo que se quiere desarrollar se puede representar con algo como:

No es cierto que alguien pueda desarrollar una versión final directamente. Similar a un iceberg, las 9/10 partes de lo que se tiene que hacer queda debajo de las aguas.


Los andamios son necesarios para levantar y producir lo que se verá. Es la infraestructura util que sin embargo será removida y descartada luego. La construcción de andamios también es parte de la producción de software.


Aprovechar la computadora para explorar

El software de hoy es más complejo que el de los 70s, cuando era normal instar a resolver el diseño primero en papel y simulando mentalmente los procesos que realizaría la computadora.

Hoy es mejor aprovechar la potencia computacional disponible.

TDD (Test Driven Development) es una técnica que construye cajas de prueba que determinan cuando el software está cumpliendo lo que se requiere. TDD promueve un proceso de descubrimiento para diseñar software.

Hay partes del diseño que se puede realizar con más flexibilidad mentalmente, pero hay otras donde es más razonable usar la computadora. Permitirse codear, fallando y acertando, explorando, ayuda a tener una mejor estimación. 

¿Es necesario estimar?

Los manejadores de proyectos han sido entrenados a resolver problemas con contextos definidos, desempeños uniformes y destinos determinados.

Por otro lado, la mayor parte del desarrollo de sistemas consiste en adaptarse a un contexto cambiante y manejar los desempeños irregulares hacia destinos inciertos.

Y es insistir en usar buenas herramientas en un contexto equivocado lo que conduce a muchos de los problemas en el desarrollo de software.

El uso de estimaciones es un ejemplo de eso. No es muy util tratar de estimar algo en un contexto con tanta variabilidad. Se convierte en una tarea ingrata que solo produce halagos o llamadas de atención completamente arbitrarias. Sin embargo, es algo que se sigue haciendo.

#NoEstimates, de Vasco Duarte, es un libro que habla sobre eso.

En el video, Vasco explica como las estadísticas de story points muestran un comportamiento irregular sobre el que es inútil tratar de hacer estimaciones.

En cambio, el número de historias que puede resolver un equipo por periodo muestra un comportamiento más regular.

Es decir, es irrelevante tratar de asignar puntos de dificultad a las historias.

Y parece ser que las estimaciones en desarrollo de software vendrían a ser un error metodológico.





2015/12/23

Unobtrusive Template Engine para Express


El uso de los sistemas de templates típicos (como jade, handlebars, jinja, etc), involucra aprender el lenguaje del sistema de templates y procesar el html base para que se acomode a los requerimientos del sistema de template.

El proceso se llama templating. El templating para jade es diferente que el de handlebars, o jinja.

Si uno usa express con jade, los templates que obtenga no servirán para express con handlebars.

Y esa forma de trabajo está bastante extendida. Si uno usa Drupal, los templates que obtenga no servirán para Wordpress. Aún más, si uno usa Drupal 6, los templates que obtenga no servirán para Drupal 7.

Todas las horas que se invierten en un templating no se pueden reutilizar si se cambia de framework. Es algo que mucha gente ve como algo natural pero me molesta desde hace algún tiempo :-P

Hace un tiempo, ensayé la idea con php y querypath. También con Wordpress y querypath.

http://akcideas.blogspot.pe/2011/05/unobstrusive-web-dev.html

Esta vez con nodejs-express con cheerio.

https://github.com/akobashikawa/express-unobtrusive-template-engine

La visión

La idea es hacer los reemplazos necesarios usando los mecanismos de jquery. Encontrar un modo en que el código base html no se toque.

Imagina que maquetas un site en html5. Puro frontend. Tomas ese conjunto de archivos y los dejas caer en cierto directorio de un framework. Y que el framework sea capaz de usarlo tal cual, sin que tengas que procesarlo. Luego, paulatinamente, unobtrusivamente, vas haciendo los reemplazos dinámicos.

Claro que hay que hace templating de todos modos, pero ya no es en el html, sino en el backend de la vista.

Me parece que sería más productivo desarrollar de ese modo.

2015/11/29

NodeJS en DigitalOcean


Vengo aprendiendo NodeJS desde hace unos meses.

Actualmente, tengo voy creando aplicaciones sencillas con Express (un framework para Node) y Angular.

Esas aplicaciones suelen funcionar bien en mi localhost:3000, que es la dirección por default de los proyectos en Express.

Recientemente, tuve la necesidad de deployar una de esas aplicaciones en un hosting y eso me ayudó a completar esa parte del cuadro.

DigitalOcean



https://www.digitalocean.com/

Permite crear droplets donde puedes instalar el sistema operativo de tu preferencia y allí dentro lo que desees, como harías con tu propio servidor. Puedes instalar tantos droplets como desees. Hay un pago mensual, dependiendo de tu consumo de recursos, pero me parece que es uno de los más económicos en su rubro.

Linux Ubuntu

Puede ser cualquier variante de Linux. En mi caso, elegí instalar un droplet con Ubuntu 14.04.3 LTS (trusty). Una vez creado el droplet, te envían el password del root por email.

Luego seguí la guía Initial Server Setup with Ubuntu 14.04

NodeJS

Instalé node vía NVM, que permite usar varias versiones de node en simultáneo.


Por ejemplo, para instalar la versión más estable:

$ nvm install stable
$ nvm use stable

Express

Express puede ser agregado como un módulo más a una aplicación web. Hay varios módulos y que se pueden ir agregando paulatinamente para facilitar el paso de parámetros en los request, las sesiones, el debug, etc. El esquema de trabajo también se puede adaptar a las preferencias personales.

Sin embargo, Express Generator puede construir un esquema base típico para ahorrarnos algo de tiempo.

$ npm install -g express express-generator
$ express --git myexpress

La aplicación corre en el puerto 3000 por default:

$ npm start

O también:

$ node ./bin/www

http://localhost:3000

Nodemon

Durante el desarrollo puede ser práctico usar nodemon para que el servidor se reinicie cuando detecte algún cambio en los archivos de la aplicación:

$ npm install -g nodemon
$ nodemon start

Nunjucks

El sistema de templates por default es jade, pero hay alternativas como nunjucks:

PM2

PM2 permite correr la aplicación como un servicio, monitorear su estado, detenerla, reiniciarla, etc.

$ pm2 start ./bin/www

Las opciones de inicio de la aplicación se pueden colocar en un archivo processes.json:

{
  "apps" : [{
    "name"        : "myexpress",
    "script"      : "./bin/www",
    "log_date_format"  : "YYYY-MM-DD HH:mm Z"
  }]
}

$ pm2 start processes.json

Nginx

Aunque es posible hacer que una aplicación node corra en el puerto 80, hay una alternativa y es la de usar Nginx como proxy reverso para que la aplicación node siga usando el puerto 3000 pero pueda ser accedida a través del puerto 80.

/etc/nginx/sites-available/default

server {
    listen 80;

    server_name rulo.me;

    location /myexpress/ {
        proxy_pass http://rulo.me:3000/;
        proxy_redirect off;
        proxy_http_version 1.1;
        proxy_buffering off;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_set_header X-NginX-Proxy true;
    }

   location /app-two/ {
        proxy_pass http://rulo.me:3010/;
        proxy_redirect off;
        proxy_http_version 1.1;
        proxy_buffering off;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_set_header X-NginX-Proxy true;
    }

    location ~ ^/(images/|img/|javascript/|js/|css/|stylesheets/|flash/|media/|static/|robots.txt|humans.txt|favicon.ico) {
        root /home/rulo/www/expressdemo/public;
        access_log off;
        expires max;
    }

}

La idea es que se solicita al servidor web nginx algo como http://midominio.com/myexpress/, entonces él revisa en su mapeo previamente configurado que ese url le corresponde a la aplicación que se ejecuta en el puerto 3000 (que se llama myexpress, pero podría ser otro nombre también) y procede a servirla. Para el usuario parece que se estuviera accediendo a la applicación directamente a través del puerto 80.

Esta estrategia permite tener varias aplicaciones corriendo en diferentes puertos que pueden ser accedidas a través de urls adecuadas, por ejemplo cualquiernombre:3010 a través de http://midominio.com/app-two