Mostrando las entradas con la etiqueta framework. Mostrar todas las entradas
Mostrando las entradas con la etiqueta framework. Mostrar todas las entradas

2017/01/13

La falacia de "hacerlo sin frameworks"

Hay una idea difundida entre muchos desarrolladores acerca de que es mejor no usar un framework en lo posible.

El Framework F tiene las deventajas a, b y c; por lo tanto, si no lo usan, evitarán esas desventajas, concluyen.

Veamos por qué esto es una falacia (un razonamiento errado que parece correcto). Las falacias son peligrosas porque parecen correctas.


Un framework es, en esencia, un conjunto de convenciones sobre cómo usar un conjunto de librerías.

Cuando usas un framework, vas notando cómo sus convenciones condicionan el modo en que abordas las tareas y resuelves los problemas. Poco a poco, empiezas a visualizar las soluciones en términos del framework.

Esa pauta que establece el framework puede ser de gran ayuda para mantener orden y estabilidad en un proyecto. Y también para darle continuidad.

Pero también puede ser que las convenciones sean demasiado reguladoras, restrictivas o limitantes. O que haya problemas que sean de solución muy dificil o imposible en términos del framework.

Entonces tenemos:

Framework F
Pros Contras
m a
n b
p c


Para analizar qué framework elegir, sería:

Framework F Framework G Framework H
Pros m
n
p
Contras a no no
b no no
c no no

Así que si esos frameworks tienen esas desventajas, no los usemos y así las evitaremos.


Suena lógico. Sin embargo, es un error.


Lo que realmente están proponiendo es esto:

Framework F Framework G Framework H Framework X
Pros m ?
n ?
p ?
Contras a no no ?
b no no ?
c no no ?

¿Qué es el Framework X?

Es el framework (propio aunque negado) que se irá definiendo (sobre la marcha).

Las preferencias de uso, las posibilidades y limitaciones, y el contexto de trabajo del equipo de desarrollo, determinarán un conjunto de librerías y cómo se deben usar.

Es decir, un framework.


Por eso, lo que realmente están proponiendo los desarrolladores que "evitan frameworks" es:

"No uses un framework conocido (con todas sus ventajas, horas de prueba, comunidad y documentación) y usa mi framework (que aún no existe pero va a ser mejor que todos ellos)"


Si aceptas esa propuesta, automáticamente estás asumiendo un proyecto extra que deberá correr en paralelo al que quieres realizar. Porque hacer un buen framework consumirá tiempo y recursos en codificación, documentación y capacitación.

No es que te estés ahorrando el costo de usar un framework; estás asumiendo el costo de hacer uno.

"No hemos usado ningún framework, así que no tienes que aprender nada nuevo para empezar".

No es verdad. Verás que tendrás que familiarizarte con el conjunto de funciones y librerías que están usando, la forma en que las llaman y la particular (o peculiar) manera como el proyecto se ha organizado (o ha resultado ser).

Si usas un framework conocido, puedes tener más apoyo de la comunidad, documentación, casos de ejemplo, etc. Habrán más personas que ya lo conocen y están disponibles para colaborar contigo.

Es cuestión también de saber ver el vaso medio lleno y valorar las virtudes del modelo open source.

El efecto Dunning-Kruger

Es un efecto psicológico que se observa en todas las personas, de pensar que son más competentes en aquellas cosas en que realmente tienen más limitaciones:

Why Do Incompetent People Think They're So Great?


¿Estamos siendo afectados por el efecto Dunning-Kruger?

Usando las buenas partes

Creo que es importante ser claro en lo que se hace, y tratar de mostrar claramente lo que sucede cuando nos damos cuenta que está sucediendo.

Porque solamente podemos construir castillos de verdad usando ladrillos de verdad.

Reinventar la rueda es muy util para desarrollar las habilidades de invención.

Poder hacer un propio framework que sea comparable con los frameworks conocidos es algo admirable.

Pero no es el mejor camino minimizar lo que esos frameworks conocidos son para que así la tarea de competir con ellos resulte más fácil o nuestro trabajo parezca más meritorio.


Siempre es posible encontrar algo desfavorable en un framework, algo que no puede hacer tan bien y que quizás nosotros podamos hacer mejor (en un contexto más simple, aisladamente).

Me parece más interesante juzgar los frameworks en función de las cosas favorables. De lo que nos permiten hacer. De los problemas que nos pueden ayudar a resolver.

Porque tampoco podemos construir castillos con ladrillos que no tenemos. Hay que usar lo que sí tenemos.


Hay una cita de Addy Osmani como recomendación acerca de los frameworks:

“First do it, then do it right, then do it better.”

Primero usa lo que hay, conócelo realmente. Si encuentras algo que mejorar, corrígelo. Luego intenta hacerlo mejor.

2016/11/19

Saber usar lo que hay

Una idea común:

  • No es necesario usar ningún framework complicado. Puedo implementarlo yo mismo.

Ok, siempre y cuando:

  • Estará bien documentado este nuevo framework (así es, vas a crear un framework que sólo tú conoces), y preparado para evolucionar (así es, eventualmente le encontrarán cosas que mejorar)
  • Puedes costear ese desarrollo extra.
    Ese montón de esfuerzo y tiempo puede ser interesante para el desarrollador, por amor al arte, pero podría también ser enfocado mejor a la idea principal del producto en lugar de a la herramienta.
  • No estará documentado pero no importa porque solamente tú vas a mantener el proyecto
  • No estará documentado pero no importa porque el producto tendrá una vida corta


Es decir, no es buena idea cuando:
  • No hay tiempo ni recursos para documentar o preparar el framework para evolucionar
  • No hay documentación, no estarás disponible eternamente, y eventualmente alguien más va a mantener el proyecto
  • No hay documentación y el producto tendrá una vida mediana o larga
    Ya que aún cuando sólo tú seas quien le seguirá haciendo manteniemiento, luego de unas semanas sentirás como si lo hubiera escrito otra persona


Reinventar la rueda cuando estudias algo es instructivo. Se puede aprender muchas cosas.

Pero cuando es otro el problema principal, reinventar la rueda, estando disponible algún estandar, puede ser muy improductivo. Es apostar que se puede hacer algo tan genial que superará la gran cantidad de horas de experiencia y experimentación acumuladas en el estandar, además de la comunidad de productos derivados, guías y expertos disponibles.

Si el caballo ha ganado algunas carreras antes, puede ser. Pero si es nuevo, o se trata de puro azar, no parece muy recomendable.

Así que es importante reconocer que siempre se usará un framework. La cuestión es si usarás uno más estándar, aceptando sus pros y contras, o si usarás el tuyo propio, el que irá surgiendo sobre la marcha.

Es bonito cuando algo nuevo surge. Algo diferente y mejor que cualquier cosa que hay. Es excelente cuando uno tiene la confianza de hacer algo así. El intentarlo te puede dar un gran poder sobre el destino del proyecto. Y con un gran poder viene una gran responsabilidad. Es mejor si tienes la experiencia para distinguir si puedes asumirla, y si es oportuno.

Es importante recordar que para resolver un problema o desarrollar un proyecto, las herramientas no son lo determinante. Tampoco simplemente usar bien cierta herramienta. Puedes tener un martillo de muy buena calidad y ser excelente con el martillo, pero será complicado usarlo ara ajustar un tornillo.

Más importante es hacer buen uso de aquellas que tengas disponible y te ayuden a resolver el problema.

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.

2013/10/30

Ajedrez Mental

¿Qué tan buenas partidas de ajedrez puedes jugar mentalmente?

Imagina un grupo de personas reunido para resolver un problema. Luego de acomodarse en el lugar, comienzan a hablar. Y hablar. Y solamente hablar.

La reunión, usualmente tediosa, termina después de un tiempo, usualmente largo, donde los asistentes, usualmente cansados, han llegado a una solución, usualmente sub óptima.

En cambio, en otros lugares se usa una pizarra, o un papel mural, donde los participantes pueden expresar con libertad las ideas que van exponiendo.

Cuando el problema se puede ver escrito en un lugar, nos ahorra el esfuerzo de mantener su imagen mental, y así tenemos más energía para imaginar otras cosas. Quizás la solución. 

Es significativamente mayor el nivel de dificultad de los problemas que podemos resolver usando un diagrama o mapa de la situación en lugar de tratar de imaginar todo, todo el tiempo.

Cuando se trabaja mentalmente, probablemente la imagen mental de cada asistente sea distinta a la del otro. De modo que pronto se encuentran con malentendidos y discusiones fuera del tema. Es bastante fácil que la gente pierda la pista, desista, y finalmente se imponga la ley de la jungla de personalidades, favoreciendo a la más fuerte o carismática.

En cambio, un diagrama o mapa de conceptos está ahí mostrando de qué estamos hablando. Ayuda a mantener el foco de la reunión. Asegura los avances que se van logrando y permite construir una estructura. La sinergía se logra con más facilidad.

Y debería ser más obvio que eso habría de esperarse -si no lo es, habría que preguntarse dónde está escondido el león ;-)

Los tratos por escrito son más seguros que los realizados solo de palabra. Los comerciantes y abogados lo saben. Porque aun cuando las partes actúen honestamente, la memoria es frágil y puede recordar, o dejar de recordar, cosas que la otra persona no.

Los acuerdos escritos ayudan a que evitemos estar peleando una y otra vez las mismas batallas. Y cuando tenemos esa energía liberada, podemos emplearla para pasar al siguiente nivel de complejidad y desarrollo.

Inténtalo en tus reuniones. Escribe qué quieres lograr, escribe qué es lo que tienes y cuál es la situación. Experimenten con ideas de cómo podrían alcanzar lo que quieren. Escriban las conclusiones y acuerdos.

Podrás ver la partida que juegas. Podrás imaginar más variantes y jugadas. Será más fácil volver sobre ella y reflexionar. Será más fácil mejorar las cosas e ir mejorando.

2011/10/05

HTML + Javascript para usar cualquier framework

Todo o nada
Para hacer una aplicación web, se suele optar por alguna de las siguientes alternativas:

a) Usar completamente un framework propio.
b) Usar completamente un framework estándar.

La alternativa a) significa volver a implementar muchas de las cosas que ya se han resuelto en otros frameworks.

La alternativa b) significa depender completamente de lo que esté implementado en el framework elegido.

Pero pienso que hay otra alternativa. Una que no use la palabra completamente.

Imagine all the people
Imagine que no tiene que volver a escribir su aplicación web en otro lenguaje simplemente para usar algunas de las cosas que ofrece cierto framework escrito en ese lenguaje.

Imagine que no tiene que volver a escribir su aplicación web simplemente para usar algunas de las cosas que ofrece la siguiente versión del framework.

Imagine un framework en el que pudiera usar cualquier cosa que ya se hubiera implementado en otro framework, sin necesidad de volver a escribirlo.

Imagine que todos los frameworks pudieran trabajar juntos y usted pudiera escoger de esa feria de componentes los que mejor se adaptaran para cada cosa que necesitara. Todas las versiones y todos los lenguajes.

Cómo hacerlo
Se me ocurre al menos una manera.

Que el contenido dinámico se construya usando Javascript. Usando técnicas AJAX, se puede hacer una solicitud a cierto URL, con los parámetros que se requieran. En ese URL, un servidor procesa la solicitud, usando el framework y lenguaje de programación que sea, y devuelve una respuesta JSON. Con la respuesta, se construye la vista de la respuesta.

Pensando sobre eso, noto que en el modelo cliente-servidor del HTML, se obliga a que el navegador reemplace completamente el contenido de la página con la respuesta. Otra vez esa palabrita.

Quizás sería interesante extender la especificación HTML para admitir reemplazos parciales. AJAX es el testimonio de que eso se necesita. Flash también lo implementa (llamándolo carga dinámica).

Por el momento, la manera de hacer eso es con ayuda de Javascript (y alguna biblioteca como jQuery).

MVC
Un patrón de muy difundido en los frameworks actuales es MVC (modelo-vista-controlador).

Básicamente, se piensan las soluciones en términos de tres tipos de componentes: controladores, modelos y vistas.

Un controlador recibe la solicitud, determina qué hacer, utilizando los modelos necesarios y pasa los resultados a una vista.

Algunos dicen que la idea principal es que los diseñadores no se vean obligados a programar ni los programadores a diseñar. Pero, como nadie lo ha logrado (para hacer cualquier template se combina diseño con programación), pienso que se trata más de una cuestión de orden.

Si se usa Javascript para carga dinámica, lo que ocurre es que lo que devuelven las vistas puede ser usado no sólo para reemplazos totales, sino también para reemplazos parciales.

¿Por qué no se hace?
Eso mismo me pregunto.

He ido desarrollando estas ideas luego de observar como la comunidad Drupal está rehaciendo los módulos que funcionaban bien en Drupal 6 para que funcionen en Drupal 7. Es un riesgo. Se habla que algunos proyectos, como Perl, han perdido comunidad por hacer maniobras como esa.

Ya se ha iniciado la carrera hacia Drupal 8... llegado el momento, ¿volverán a reescribir los módulos?... ¿y así, sucesivamente?

Me parece que debe haber un camino mejor.

¿Qué le parece?

2011/07/18

Liberando la V, otra forma de usar un framework MVC

En el esquema MVC, se tienen modelos que proveen datos, y controladores que toman los datos y los procesan de algún modo antes de enviar el resultado a la vista.

En web, los framework MVC tratan de seguir este esquema para organizar el trabajo. En teoría, parte del equipo se puede enfocar en los modelos, otro en los controladores y otro en las vistas.

Al margen de si en la práctica realmente se cumple esto, es notable un problema: los modelos, vistas y controladores desarrollados determinan finalmente un API no estándar que termina "enjaulando" el producto final. Si decide actualizar el framework a la siguiente versión, encontrará que puede acarrear para el site un trabajo similar a volverlo a hacer. Aún más difícil es pasar un site de un framework a otro.

Esto genera algunos vicios. Si otro framework implementa cierta característica ventajosa, no lo podemos usar; tenemos que esperar hasta que algo similar sea implementado en el que usamos. Esa característica debe ser expresada otra vez, en los términos de nuestro framework.

En mi opinión, esto ocurre porque la página web ha sido forzada a encajar en el esquema MVC sobrescribiendo sus características estándar por otras propietarias, definidas por su sistema de templates particular.

Sí, aunque el framework sea open source, en este caso se está comportando como un ente propietario. Y eso es lo que provoca esta limitación de libertad.

Para tener más libertad, libere la vista. Puede desarrollar su sitio web de modo que las vistas sean HTML estándar y las partes dinámicas carguen con javascript (AJAX) los datos obtenidos de invocar algún framework.

Por ejemplo. Si uso Drupal como framework, puedo tener un subdirectorio drupal dentro de mi site, e invocar con javascript a algo como drupal/action.json, cuyo resultado reflejo en la página.

No hay problema con las páginas del site mientras no cambie el modo de invocar la accion. Si luego cambio la versión de drupal, no seria necesario cambiar las vistas.

Si, en lugar de usar drupal como nombre del subdirectorio, hubiera usado algo como framework, y colocara dentro acciones que se invocaran del mismo modo, entonces, podría usar cualquier framework, con tal que siguiera el protocolo esperado por las vistas.

Esta forma de trabajar puede permitir funcionar un sitio dinámico que use muchos frameworks diferentes en simultaneo. Uno para el login, otro para los listados, otro para comunicaciones, etc. El que mejor haga lo que queremos. También facilita la actualización de los frameworks a versiones superiores.

Usar javascript para esto me parece un camino relativamente asequible en este momento. Pero si alguien no desea usar javascript para eso, podría usar un framework unobstrusivo (que respete la integridad de las páginas), como uphp, para hacer el trabajo de reemplazo. uphp usa querypath para ubicar un elemento en la página (al estilo jquery, pero con php), y reemplazarlo por algún resultado; todo eso en el lado del servidor.

En este otro modo, no son las vistas las que invocan las acciones, sino los controladores que se disponen en el framework unobstrusivo (o uframework, para abreviar). El uframework podria invocar a otros frameworks para hacer los reemplazos de los resultados en las ubicaciones pertinentes en la vista. Igual, se podría usar varios frameworks a la vez.

La idea principal es que la vista salga de la jaula del framework, se respete su integridad, tal como es, y sea independiente de los motores que se usen para generar el contenido dinámico.

2011/07/08

Generación modular de HTML

Actualmente, cuando desarrolla un sitio usando cierto framework, no lo puede modificar con otro. Si está metido en esto, puede parecer obvio y hasta natural. Pero, si lo vemos en perspectiva, es algo así como una limitación por diseño. Algo que se podría mejorar.

Sites estáticos y dinámicos
Aunque el objetivo final es enviar html al navegador, en el desarrollo de sites dinamicos el paso intermedio es crear un conjunto de archivos que generen el html que se desea.

Cuando se trata de sites estáticos es más simple. Uno coloca los archivos en el directorio web y el servidor web los envía al navegador tal cual. Esos archivos son html, css, javascript, o imágenes que el desarrollador puede modificar con la libertad de elegir entre muchas herramientas para eso.

Cuando se trata de sites dinámicos las cosas se suelen complicar. En general, primero se plasma el diseño en un site estático, que luego es desmantelado para ver el modo de generarlo. Finalmente, se obtiene el site dinámico, que actúa como un generador total del html que se desea.

Ese suele se el enfoque más usado. Practicamente siempre que use C, Java, PHP, Ruby, Python, o lo que sea, lo que construye es siempre un generador total de html.

Frameworks exclusivos
El enfoque de la generación total tiene el problema de tender a soluciones monolíticas, con sus vicios asociados.

Si quiere modificar el site, tiene que modificar el generador, y tiene que entender el framework-que-todo-lo-hace.

Cuando un framework mejora, esa nueva versión no le sirve para el site que hizo con la versión antigua y tendría que reescribir el site bajo los nuevos términos.

Si otro framework implementa una característica que le gustaría, tendrá que esperar hasta que sea implementada, otra vez, en los términos del framework que usted usa.

Un montón de trabajo repetido.

Frameworks inclusivos
Una alternativa podría ser hacer generadores modulares. En lugar de generar el html de toda la página, un generador modular sólo produce el html de cierta región específica.

Para indicar dónde colocar el html dinámico, habrían algunas alternativas:

  • Que la página use javascript, obtenga el resultado y lo coloque.
  • Que la página use un tag especial que se reemplace por el contenido dinámico.
  • Que el servidor ubique los lugares dónde hacer el reemplazo y los haga.

La primera alternativa es relativamente asequible con lo que ya tenemos. Para las otras, habría que hacer un framework que se encargue de hacer los reemplazos adecuados (por ejemplo uphp).

Ya mismo podríamos empezar a desarrollar sites de ese modo. Una ventaja grande de usar generadores modulares, es que no importa en que lenguaje de programación se hacen, ni que framework usan, ni que versión del framework. Simplemente se usan. Podría usar generadores modulares escritos en C, Java, PHP, Python y Ruby... todos juntos!

2011/06/28

Liberando los sitios dinámicos

Imagine que le hicieran una página web y, un tiempo después, usted quiere modificar el documento HTML.

Imagine que puede abrirla en cualquier editor de texto, modificarla y volverla a grabar. Sin importar si se hizo en Dreamweaver, Geany, Notepad, o cualquier otro. Qué libertad.

Claro que no sólo lo podemos imaginar, de hecho podemos hacerlo.

Entonces, ¿por qué hemos permitido que esta libertad y conveniencia sea recortada por los frameworks? Porque eso es lo que ocurre.

Cuando hacemos un sitio dinámico, digamos en CakePHP, y, un tiempo después, usted quiere modificarlo, tiene que usar no sólo CakePHP, sino la misma versión de CakePHP. Del mismo modo si hubiera usado Zend, CodeIgniter o Drupal.

Es como si le dijeran que para abrir un HTML tiene que usar Notepad 4 y no otro, porque no es compatible. Que si quiere el mismo site para Notepad 5 hay que volverlo a hacer.

Sí, un site dinámico es más complejo que un documento HTML, pero la razón es similar. Es importante que el producto sea independiente de la herramienta usada para fabricarla. No sólo porque es un gran ahorro de esfuerzo y duplicidad. Sino también para que tengamos la libertad de elegir cualquier herramienta que queramos.

En el desarrollo web han aparecido islas, o silos. Al comienzo fue entre lenguajes, como ASP, JSP, PHP, Python, Ruby. Luego entre frameworks dentro de esos lenguajes. Y entre versiones de un mismo framework.

Muchos desarrolladores se amarran a cierta plataforma porque sus productos no pueden ser modificados con otra. Expresar un sitio dinámico en otro framework (o versión de framework) puede ser tanto trabajo como hacerlo de nuevo.

Después de todos los discursos que nos dan sobre la reinvención de la rueda, KISS (Keep It Simple, Stupid: Mantenlo Simple, Estúpido), DRY (Don't Repeat Yourself: No te Repitas), etc ¿no le parece poco razonable?

Hay razones por las que se prefirió que los protocolos web usaran texto simple. Para que cualquiera pudiera entrar a manejarlos. Quizás debemos recordarlo más seguido.


Imagine que le hicieran un sitio dinámico y, un tiempo después, usted quiere modificar el site.

Imagine que puede usar cualquier framework, modificarlo y guardarlo. Sin importar si se hizo en Drupal 6 o Drupal 7. O si se hizo en Zend o CodeIgniter. Incluso sin importar si se hizo en PHP, Ruby, Python o ASP. Qué libertad.

Claro que sólo lo podemos imaginar, pero podemos hacerlo.

2011/05/20

Unobstrusive wev dev

Lea el artículo original en Unobstrusive web dev.

2011/04/15

uphp


Con HTML, el contenido se mezcla con etiquetas que permiten mostrarlo en un navegador.
CSS permite separar la data del formato de la data del contenido.
Javascript permite poner código en las etiquetas para manipular el documento e interactuar con sus elementos.
Unobstrusive javascript es una forma de usar javascript que procura mantener el código aparte. jQuery ayuda mucho en esto.
JSP, PHP, etc, permiten generar HTML, abriendo la puerta a la automatización y al uso de recursos como las bases de datos.
Frameworks web permiten para manejar el desarrollo de un site relativamente extenso o complejo.
El modelo de framework MVC (Modelo-Vista-Controlador), viene del mundo Smalltalk a la web para separar el desarrollo en esas tres capas.
En mi opinión, aumenta la inercia del proceso de desarrollo. Expresar una solución web en términos MVC se convierte en un problema adicional.
Drupal usa un modelo de framework diferente, ingenioso, permitiendo agregar libremente componentes que pueden colaborar entre sí.
También requiere algo de tiempo y trabajo aprender a pensar y expresar cualquier solución en sus términos. A cambio, a mi parecer, permite ser mucho más productivo que en cualquiera de las alternativas anteriores.
En general, estos frameworks requieren que aprendamos una nueva versión de lo que ya sabemos hacer en web. A veces, incluso hay que hacer ese reaprendizaje de una versión a otra del mismo framework.
¿No le parece que algo tiene que cambiar?
¿Habrá alguna forma de hacer dinámica una página estática sin tener que reescribirla? 
Encontrando a QueryPath, algo como un puerto de jQuery para PHP, que facilita la manipulación de una página, me pareció que podría haber alternativas.
uphp es la búsqueda de una forma de desarrollar web en la que el código afecta al contenido pero se manteniene aparte.
De ese modo, se pueden respetar las páginas estáticas de un site mientras se lo vuelve dinámico.
Además, se podría usar, tal cual, soluciones HTML/CSS/Javascript que sean independientes del framework.
Quien sabe, quizás tambien se halle una forma de hacer todo eso y además separar la data del contenido de la data HTML.

2010/05/18

A través del código

Dicen que quien no conoce la historia está condenado a repetirla. Es importante registrar las cosas.
Sin embargo, tiene que haber una forma de visualizar fácilmente aquello que se ha registrado. Para comprenderla. Quizás se debería decir, en realidad, que quien no comprende la historia es quien está condenado a repetirla.

Por ejemplo, uno puede tener un log con el tráfico de un website, o los mensajes de depuración de un programa, pero si no logra visualizar fácilmente la información contenida en esos registros, no la comprenderá, y se perderá en el papeleo.

En general, no se trata sólo de la historia. Para comprender algo es importante visualizarlo fácilmente, de alguna manera. La evolución de los lenguajes de programación pueden ser una manifestación de la necesidad de los programadores de comprender más fácilmente un programa. Assembler en lugar de binario. Cobol en lugar de Assembler. O C, Pascal, Basic, Smalltalk, Java, Ruby. Y, dentro de cada uno, algún framework o manera de organizar el código. Diagramas de flujo. UML. Herramientas visuales. Generadores de código. Vamos buscando una manera simple de ver el programa.

Es tan facil introducir complejidades en la organización del código que los hackers acuñaron la frase KISS ('Keep It Simple, Stupid', 'Mantenlo simple, estúpido'), para recordárnoslo, en tono de broma, pero muy en serio.

Del mismo modo que es difícil hacer reparaciones en una casa donde las tuberías están ocultas, es difícil reparar código que no está organizado convenientemente.

Cuando un programa falla, no suele ser una tarea fácil encontrar la causa. Esta no es inmediatamente visible. Hay que bucear en el código. Por eso los buenos programadores tratan que esté limpio y claro. El código que se optimiza y compacta para que quepa en un hardware económico, es uno que ha sido muy probado, porque es demasiado costoso de depurar en esa forma. Es mejor que haya una versión más amplia y clara, donde ocurra el desarrollo, y se haga el empaque de versiones seguras sólamente.

Es la misma idea que con los programas compilados. Programamos en texto, pero se usa el compilado binario, para que quepa mejor en el hardware. Imagínese tener que depurar diréctamente en el compilado. Por eso la mayoría depura en el texto fuente.

Quizás lo ideal sería que un programa pudiera ser visualizado como una caja transparente, con el flujo ocurriendo de manera obvia, de modo que fuera fácil encontrar la causa de cierto comportamiento. Quizás lo más importante sería que, al ver con más claridad lo que hay, imaginaríamos con más facilidad lo que podría haber.

2010/04/30

La falacia de optimizar a cada paso

De buenas intenciones está empedrado el camino al infierno.-- refrán popular

La optimización prematura es la raíz de todo lo maligno.-- Donald Knuth

Primero que funcione, luego se mejora.-- refrán hacker

Hay cierta forma de pensar, cierta filosofía, que convence a las personas de que es bueno optimizar cada paso antes de dar el siguiente. Programar, limpiar, programar, limpiar lo nuevo y lo anterior, programar... y así sucesivamente. Como si dar cada paso marcado perfecto fuera garantía de un buen trabajo.

Y no es así. Uno podría empeñarse, dando lo mejor de sí, su mejor esfuerzo, para ir derechito al abismo. Es un ejemplo algo extremo, pero ilustra la idea.

Hacer algo y limpiar, hacer algo y limpiar, es una muestra de ese tipo de pensamiento del que hablo. Obsesionado en el control. Imaginando la peor de las posibilidades. Sin confiar. Arrastrándose como esclavo.

Es algo que está presente no solo en la programación, sino en muchas otras actividades humanas. Hay supervisores que necesitan convencerse de que cada persona esta enfocada en su trabajo para poder estar tranquilos. Parejas que necesitan conocer cada movimiento diario de la otra persona. Padres que no dejan respirar a sus hijos. Es un estilo de pensar desafortunado que muchos heredan y transmiten sin reflexionar mucho en eso. O hasta pensando que es la mejor de las opciones.

Alguien criado de ese modo, que haya crecido de esa forma, y que viva aún así, puede extrañarse un poco al considerar la valía de las cosas en las que siempre ha creído. Dar cada paso de la mejor manera no asegura un destino correcto; es importante que la ruta sea correcta.

No puedes estar en medio de la nube y contemplar la forma de la nube al mismo tiempo. No puedes estar adentro y afuera a la vez. Es como tratar de servir a dos amos distintos al mismo tiempo.

Para que sea posible esmerarse en la correcta ejecución de un paso mientras se contempla el panorama, se requiere de dos conciencias. Como cuando un bailarín contempla a su amada sin pensar en los pasos de baile. La parte subconciente se encarga de mover los pies y del ritmo, mientras la parte consciente lo disfruta.

Para dibujar, pintar, o esculpir mejor, la conciencia debe estar elevada, para sentir aquello que se quiere representar, mientras las manos y los sentidos entrenados se ocupan de los detalles.

Para ir bien por una ruta, hay que visualizarla, sentirla, mientras nuestros pasos la recorren.

Es necesario ambas conciencias. Pero muchas personas han descuidado esa noción y se encuentran haciendo las cosas sin sentir lo que hacen ni a donde los lleva. Pienso que es porque no han experimentado esa conciencia elevada de la que hablo. No usan sino una solo conciencia, y se afanan en alcanzar la perfección de un trazo, de una pincelada, de un golpe de cincel, sin sentir la obra que están realizando. Y lo triste, a veces, es que se encuentra con otro igual que lo premia ante el mundo, santificando el extravío.

Programar y optimizar a cada paso es actuar así. Porque, ¿qué sentido tiene la optimización en cada paso?, ¿acaso contribuye a programar mejor o hace más fácil e interesante el camino?. Al contrario, lastra el viaje, y hace que uno vaya a la velocidad de quien camina con lodo hasta las rodillas.

Digamos que tienes mucho código abierto, explícito, pero lo entiendes y eso te ayuda a avanzar, te da ideas, te inspira. ¿No es mejor eso que código cerrado, que ya no se puede analizar porque está optimizado, que es un rompecabezas depurar, y cuyo sentido se ha perdido entre técnicas para reducir el consumo de memoria o de disco?.

En un viaje lo más importante no es ahorrar comida y caminar poco. Es más importante encontrar cosas que te permitan avanzar, que te inspiren, que hagan que la comida no importe ni el camino recorrido, sino lo que vives y a dónde te permite llegar.

Si encontraras un framework que te permitiera comunicarte con la computadora de una manera en que tus ideas fluyeran con soltura, que sintieras la sinergía, la esperanza, las posibilidades surgiendo, eso sería maravilloso. Después ya se podría optimizar.

2010/04/18

Un esquema para desarrollo

Lo empírico y lo convencional

He observado que, cuando hay una solicitud para hacer un sistema, mucha gente se esmera por seguir lo mejor posible cierto modelo de desarrollo. Pero se suele perder en el bosque, porque caminar con ahinco no garantiza que la dirección sea la correcta.

Cuando algo va mal, casi siempre es posible culpar a la gente. Que no se aplicó el modelo como debía ser. Cómo rebatir eso. Sin embargo, algo hay que hacer. Consideremos que el modelo de desarrollo pueda no ser tan bueno como pensamos. Y probemos.

En la forma empírica, uno empezaba directamente programando, y adaptando el código poco a poco. Se siente bien recibir el feedback de la computadora con cada paso.

Cuando uno estudia, le enseñan que es mejor determinar cuál es el problema y modelar cuál es la solución, antes de empezar a programar.

Si le preguntan a un desarrollador profesional típico, dirá que es mejor la segunda forma, la forma convencional. Yo no estoy completamente de acuerdo. Ni tampoco completamente en desacuerdo.

La forma convencional está bastante influenciada por la necesidad académica de poder evaluar a los estudiantes. Es más fácil hacerlo cuando explicas de antemano qué es lo que pretendes hacer antes de hacerlo. La solución se puede documentar, evaluar, optimizar, etc.

Esto también le es util al mundo. Cuando una empresa solicita un sistema, la forma convencional permite estimar el costo de antemano. Con esta venia, la forma convencional queda santificada en la currícula. Después de algunos años de ser condicionados haciéndolo de ese modo, también acabamos santificándolo nosotros.

Es un poco difícil cambiar las cosas santificadas, pero a veces hay que considerar los hechos.

En el mundo real, la conocida frase 'el cliente no sabe lo que quiere' refleja el hecho de que a menudo es muy difícil precisar el problema de antemano. Y, debido a eso, aún cuando el modelado fuera perfecto, nada garantiza que el producto final sea satisfactorio.

La mayoría de proyectos de desarrollo de software fallan. Se exceden en el tiempo, no satisfacen al cliente, o ambas cosas. Si la forma convencional estuviera en lo cierto, eso significaría que la mayoría de la gente no lo aplica bien, y no creo que ese sea el caso.

Pienso que no es culpa del cliente, ni de quien reune sus requerimientos. Sino que la causa es que no tenemos aún un método que permita precisar de antemano problemas que excedan cierta complejidad.

Cuando los problemas son relativamente sencillos, o han sido ampliamente recorridos, puede funcionar la forma convencional, pero no cuando los requerimientos son imprecisos y deban descubrirse sobre la marcha. Lo cual ocurre en prácticamente todos los desarrollos (quizás deberíamos reflexionar en el desfase académico sobre esta cuestión).

La prueba que guía

Cuando uno programa, hace pruebas para estar seguro que lo que se acaba de hacer hace lo que se espera. Es relativamente sencillo probar una función o módulo y más complicado probar un caso y aún toda la aplicación. Sin embargo, es necesario, si se quiere minimizar el número de errores que puedan llegar a la versión que probará el usuario.

Las pruebas unitarias permiten usar la computadora para probar una función. Diseñando y agrupando convenientemente las pruebas se pueden probar módulos, casos y hasta la aplicación completa. Esto hace más llevadero el proceso, hasta el punto en que se pueden usar como guía para el desarrollo.

Usar las pruebas como guía para el desarrollo, o Test Driven Development (TDD), es desarrollar primero la prueba que debe pasar el producto, y recién después el producto.

Las pruebas se van implementando según se van determinando los casos de uso.

La primera vez que se corra la prueba, sin ningún producto desarrollado, aparecerá una señal roja. Entonces el desarrollo se convierte en el juego de descubrir el camino más corto, lo mínimo necesario, para que la señal se vuelva verde. Así, el producto reflejará lo que la prueba requiera. La prueba sirve como guía para el desarrollo.

Modelar es optimizar

Con TDD, la optimización se posterga todo lo que sea posible, ya que la optimización prematura fácilmente conduce a compromisos y enredos innecesarios.

Cuando un producto pasa las pruebas, se puede refactorizar con seguridad. Es decir, se puede intentar ya sea cambiar el nombre de una función, extraer un fragmento de código para formar una función, reagrupar funciones en nuevas clases, etc. Si todo va bien, las pruebas continuarán mostrando la señal verde. Y si la señal es roja, no hay problema, podemos usar un sistema de control de versiones para deshacer los cambios y volver al último punto donde todo era verde.

Así, es más natural que el modelado vaya apareciendo en este punto. Si el modelado está bien, las pruebas lo dirán. En TDD, la principal guía del modelado es evitar las repeticiones y los acoples de código. Las repeticiones son código que se nota se puede factorizar (una idea similar al del álgebra, que extrae aparte los términos comunes), usando funciones, clases, o herencia. Los acoples ocurren cuando hay una dependencia innecesaria entre dos fragmentos de código. Es mejor cuando cada fragmento de código se pueda reemplazar sin peligro de efectos inesperados en otra parte.

Un esquema para desarrollo

En la forma de desarrollo empírica se sentía bien el feedback que daba la computadora en cada paso. TDD tiene algo de eso.

El modelado previo de la solución, aunque quizás correcto académicamente, no funciona demasiado bien en el mundo real. Y tiene, además, el efecto de contenernos las ganas. No soltamos el corcel hasta que tenemos listo el arado. Pero, entonces, ya no es divertido salir a correr si hay que arrastrar un arado al mismo tiempo. Es mejor ir ligeros desde el principio, aceptar los hechos, ser prácticos, y actuar en consecuencia.

Parece que desarrollar un sistema con requerimientos imprecisos es algo que necesariamente debe resolverse sobre la marcha, en un proceso de prueba y ajuste.

El siguiente es un esquema que toma varias ideas de Scrum y otras metodologías:

  • El proceso es de prueba y ajuste. El equipo de desarrollo y el cliente deben estar abiertos al cambio, a  probar, equivocarse y corregir. El ambiente debe aceptar los errores como parte del proceso.
  • El punto de vista del cliente debe estar presente en el desarrollo. Como a menudo es difícil que pueda participar, se designa un intermediario. Puede ser una persona o un conjunto de personas, pero con una sola cabeza para la comunicación y la asignación de responsabilidades.
  • Se elije cuanto tiempo debe durar la etapa. Es más o menos al azar la primera vez. Entre 2 y 4 semanas.
  • Basado en el punto de vista del cliente, se obtiene un conjunto de requerimientos que podría esperarse estuvieran listos en esa etapa. Es más o menos al azar en la primera etapa. Los requerimientos parten de deseos del cliente. Finalmente cada uno se expresa como algo que cierto rol usa para realizar cierta tarea.
    Cada requerimiento tiene un por qué, que a su vez tiene una justificación, y así sucesivamente. La cadena se puede seguir hasta un conjunto de principios más o menos estables que constituyen la necesidad que justifica el desarrollo.
    Conforme avance el desarrollo estos principios y la jerarquía de justificaciones se irá haciendo más clara.
    Luego, habrán requerimientos que no se admitirán porque no encajan en ese orden y, del mismo modo, podrán descubrirse requerimientos que inicialmente no se consideraron pero que son necesarios.
  • Basado en los requerimientos, el equipo hace una lista general de las tareas que estos requerimientos implicaría. Es una lista libre, donde cada uno puede anotar sin censura. Es además una lista abierta, que admitirá nuevos ingresos en cualquier lugar de la etapa. La lista debe ser visible, de libre acceso y fácil de mantener.
  • Antes de procesar la lista, el equipo reunido hace una lectura rápida de todas las tareas, simplemente para informarse de cuales son, y las agrupa en páginas de cierto tamaño. Esto es más o menos arbitrario. Puede ser un número entre 10 y 30 items por página.
  • Para procesar la lista, se hace un repaso tarea por tarea. Cuando uno o más miembros del equipo sienten que pueden atender una tarea, se pone a trabajar en ella durante el tiempo que consideren conveniente.
    Si la tarea se completa, se tacha de la lista y se continúa el repaso hasta interesarse en alguna tarea. Si la tarea no se completa, se la vuelve a anotar al final de la última página, luego se tacha la anotación original y se continúa el repaso de tareas a partir de esa posición.
    Al llegar al final de la página, se vuelve al comienzo.
    Si se hace un repaso y ninguna tarea pendiente parece interesante de atender, todas ellas se resaltan y se coloca una X en una esquina de la página, antes de pasar a la siguiente página.
    Al llegar al final de todas las páginas, se vuelve a la primera.
    Puede ser ninguna de las tareas pendientes, que ahora estan resaltadas, sea interesante, porque no son realmente necesarias en ese momento. Si es así, la X se encierra en un círculo, para facilitar saltearse esas páginas la siguiente vez.
    Las tareas urgentes se anotan al final de la lista y se procesan en dirección inversa, empezando desde el final.
  • La optimización se retrasa todo lo que sea posible. El código optimizado frecuentemente se hace más difícil de entender y reutilizar. Es conveniente que las abstracciones, simplificaciones, y generalizaciones se hagan lo más tarde posible. Y es en la optimización del modelo donde recién entraría a participar el arquitecto. Viendolo bien, un modelado apriori, como en la forma convencional, en realidad "contamina" la lista de requerimientos del cliente con la lista de requerimientos del arquitecto. En cambio, al hacerlo durante la refactorización del código, se hace sobre cosas que realmente se necesitan.
  • Para saber quién atiende cada tarea, y cuál es el estado actual del proceso, se pueden colocar marcadores removibles sobre los items de la lista.
  • Al inicio de cada semana, el responsable del equipo de desarrollo se reune en privado con cada persona para tener una visión de cómo está cada una y qué está haciendo. Hay cosas que se expresan mejor sin la presión del grupo.
  • Al inicio de cada día, el equipo dedida unos minutos en contar a todos que hicieron ayer, que harán hoy, y si tienen alguna dificultad. Hay cosas que es necesario que todos conozcan.
  • Al final de cada etapa se hace una evaluación de ese periodo. Ver qué cosas funcionaron bien y qué cosas podrían mejorarse.
  • En cada nueva etapa, se ajusta la duración del periodo y el tamaño de las páginas de la lista de tareas. También se borran todas X de las páginas con tareas pendientes, para incorporarlas nuevamente al proceso.

Cómo funciona

La forma de procesar la lista de tareas está basada en el sistema Autofocus, de Mark Foster.

La idea de dejar que el equipo atienda las tareas que les resultan interesantes es permitir que se desarrolle un inconsciente colectivo que ayude a determinar cuáles son realmente necesarias.

El sistema funciona como un ambiente que sólo deja sobrevivir aquellas tareas realmente necesarias para determinar el sistema. Es decir, el sistema se determina de modo evolutivo. Por eso, se da la libertad de anotar en la lista lo que sea, porque si no vale la pena hacerlo nadie lo hará, y si es necesario, tarde o temprano sucederá.

No es necesario gastar tiempo discutiendo cuales son las tareas, en qué orden hacerlas y quién las atenderá. El sistema facilita que estas cosas se resuelvan espontáneamente.

Ahora, a probar.

Enlaces:

2010/01/09

Kohana101


Aprendiendo Kohana estoy desarrollando el tutorial Kohana101, publicado por Oscar Bajner.

Viendo que no hay mucho material sobre Kohana disponible en español, se me ocurrió que sería buena idea ir traduciéndolo mientras doy estos primeros pasos.

Ojalá sea de ayuda a quienes estén interesados en probar este interesante framework pero, por alguna razón, necesitan más material en español.

Pueden encontrar la traducción bajo mi colección sobre Kohana, en Knol.

2009/11/08

Hello World en Kohana

Kohana es un framework PHP derivado de CodeIgniter. Los desarrolladores de Kohana decidieron que participara más la comunidad, que se adoptara PHP5, y que hubiera un ORM para acceder a la base de datos, entre otras mejoras que venían reclamándose hacía tiempo en los foros de CodeIgniter.

He usado CodeIgniter para un proyecto. Pude aprender a usuarlo mucho más rápidamente que CakePHP (de hecho, fueron varios disgustos sucesivos al reaprender varias de las bibliotecas principales de Cake lo que me animó a buscar afuera y probar CI).

Usar CI es simple, claro, directo. Permite incorporar fácilmente muchas de las cosas que ya sepamos de PHP, en lugar de forzarnos a reaprenderlas, como me sucedió con Cake.
Además me gusta mucho la forma en que permite organizar los controladores y, principalmente, las vistas.
Sin embargo, extraño algunas cosas de Cake, como la forma de acceder a la base de datos y la forma de mantener disponibles los datos del formulario una vez enviado.

Leí que Kohana es interesante como alternativa a CI (mis siguientes pasos serían probar también Yii y Adventure PHP Framework), y he decidido probarla.

2009/08/19

Construyendo código

Al desarrollar una aplicación web me voy dando cuenta que el proceso es similar a cuando se dibuja, o se pinta algo. Pero también es útil pensar que es similar a cuando se construye algo.

De mismo modo que se ponen cimientos y una estructura base, uso un framework.

Uno podría hacer un framework aceptable. Afortunadamente hay frameworks estandar que puedo reutilizar y me ahorran mucho trabajo.

Pero quienes han hecho alguna vez un framework (quizás como yo, sin saber que así se llamaba), saben que es simplemente una forma de organización que va surgiendo conforme resuelves el problema. Es como un patrón de lugares comunes que van apareciendo en tu modo de resolver las cosas. Incluso aunque no hagas nada a propósito, el sólo hecho de intentar resolver el problema produce un framework.

Pienso que los framework estandar surgieron del mismo modo, pero por alguna razón (su simplicidad, elegancia, robustez, lo que sea), les pareció tan bueno a otros desarrolladores como para dedicarse a la tarea de mantenerlo y mejorarlo como un proyecto en común, un estandar.

Aún usando un framework estandar, para hacer algo nuevo se sigue la secuencia del bosquejo, funcionamiento, optimización. Es similar a levantar estructuras auxiliares, luego la estructura en sí, y después ir puliendo el trabajo.

Esa secuencia es como algo natural. Es demasiado complicado y propenso a errores tratar de desarrollar directamente 'en limpio'. Es como tratar de construir sin andamios, ni estructuras auxiliares, ni bosquejos, ni líneas guía.

El código va creciendo, simplificándose, creciendo, simplificándose. Pero entonces uno nota un problema. Si ya se tiene código funcional optimizado, las mejoras que se le puede hacer son relativamente pequeñas, del mismo modo que las correcciones que se pueden hacer sobre un edificio habitado, o sobre un dibujo ya terminado.

Sería interesante que se pudiera trabajar sobre el código original, con sus estructuras auxiliares y código aún sin optimizar, donde el espíritu de la solución es más palpable, y luego, de algún modo, iniciar un proceso de optimización estándar, una especie de compilación, que produzca el código optimizado para producción.