Monthly Archives: enero 2009

Proxy: Patrón de Diseño para Seguridad

Entre los patrones de diseño que ya comenté en otro post, quiero agregar uno que dejé pasar, y al que he retomado hace poco, tanto de forma teórica, como para implementación en algunos desarrollos. Es el patrón de diseño Proxy.

Este patrón es usado para agregar una capa de seguridad sobre un sistema ya desarrollado y que es totalmente ajeno a este aspecto. Es decir, podemos desarrollar un sistema de control de almacén en el que solo tendremos en cuenta el stock en sí del almacén y, para agregar los usuarios, permisos y demás, entonces, agregamos el la capa proxy que se encarga de asegurar el acceso solo a los usuarios que deban de poder acceder.

Ahora que mi atención se está centrando en Ruby, voy viendo artículos como este (algo antiguo), donde explican como integrar esta capa junto con ruby on rails. En Java, este patrón de diseño está presente en entornos tales como spring.

En el patrón MVC, agregando esta ideología, además del uso de rutas, tenemos que el controlador se puede diseccionar en:

  • Controlador: controla el flujo normal de ejecución del sistema.
  • Rutas: facilita las peticiones desde el navegador.
  • Proxy: comprueba cada acceso a cada controlador, teniendo en cuenta parámetros como el usuario que accede, dirección IP y/o navegador, entre otros que se puedan tener en cuenta.

Esta separación facilita el desarrollo, ya que se basa en la encapsulación y abstracción del código por similitudes funcionales, así como, por supuesto, cumplir con el principio: divide y vencerás.

Desarrollo Web

Hace tiempo, comenté acerca del desarrollo web en plataformas como Java, PHP, Erlang, Python… en ese momento, veía la maraña en la que está tejida la red de redes, el abanico de posibilidades a la hora de desarrollar una aplicación web y comenzaban a sonar términos como CRUD, SOA, MVC, ActiveRecord, Scaffolding…

Es una verdad que cada entorno, en cada lenguaje, ha ido implementando una serie de características que facilitasen y acelerasen la creación de entornos web, de toda índole, en poco tiempo y, una vez aislada la idea base, dado un nombre e incluso un acrónimo de tres letras (como el buen Jargon file manda :-) ), se convierte en un concepto de estudio e implementación en el resto de lenguajes.

A este respecto, PHP ha sufrido una desaceleración en innovación. La cantidad de estas características que pululan entre el resto de lenguajes, que la mayoría los orientan a objetos, quedan en imposibilidad de implementación, o en una implementación algo sucia, cuando se hacen en PHP, debido a su, aún, pobre implementación de orientación a objetos.

No obstante, en PHP se pueden identificar buenos entornos de trabajo que hacen, o en los que se pueden emplear y usar todos estos conceptos, como son Code Igniter o Simfony.

Algunos conceptos a tener en cuenta y que no se nos olviden, como buenas prácticas para el desarrollo de sitios web son:

  • CRUD: create, retrieve, update y delete; es usado como sistema base para gestión de la información, con las cuatro tareas básicas que se suelen hacer sobre cada entidad de base de datos típica.
  • SOA: arquitectura orientada al servicio; es una forma de diseñar nuestras aplicaciones de forma que se tenga presente siempre el nivel de aplicación, el servicio que se va a prestar.
  • MVC: modelo-vista-controlador; es una separación lógica de las aplicaciones en lógica de negocio (modelo), presentación o vista, y controlador del flujo de ejecución.
  • ActiveRecord: es una forma de aislar la sintaxis SQL del programa base. Intenta emular al sistema que se usaría con un sistema de base de datos orientado a objetos, pero a través del mapeado de las tablas con los atributos de las clases.
  • Scaffolding: realiza, automáticamente, el paso de tablas de base de datos a CRUD y/o ActiveRecord. Es un sistema que intenta automatizar, lo máximo posible, la generación de entornos simples de metodología CRUD.
  • Rutas: es la forma en que las aplicaciones web pueden hacer uso de la llamada a un método específico con unos parámetros específicos y de una forma elegante, a través de un sistema tipo ruta en la URL.
  • AJAX: el uso de AJAX para agregar dinamismo a la web es un factor del que no se debe de abusar, pero que se debe tener en cuenta, ya que hace que la carga de páginas se reduzca de forma drástica.

En poco tiempo, supongo y espero, haré esta lista algo más grande, porque sé que se me olvidan más conceptos, pero de momento, así se queda :-P

Lenguajes esotéricos

Otro viernes… las oficinas a medio gas y toca trabajar… me da por buscar información, ahora que aprendo más sobre Ruby y Erlang y, topo con un lenguaje llamado COW. Un lenguaje esotérico.

Ves cosas como la serie de fibonacci:

MoO
moO
MoO
mOo
[[ main loop ]]
MOO
[[ print first number ]]
OOM
[[ temp copy of first number ]]
MMM
moO
moO
MMM
mOo
mOo
[[ store second number off in the first position now ]]
moO
MMM
mOo
MMM
[[ move back to temp number ]]
moO
moO
[[ use temp to add to first and store in second in loop ]]
MOO
MOo
mOo
MoO
moO
moo
mOo
mOo
moo

Supongo que el autor de este lenguaje llegaría hasta el punto de decir si hasta las vacas pueden programar… y mira por donde, ahora sí :-D Ahora tenemos un sistema de accesibilidad para que las vacas, con sus gemidos, puedan trabajar por nosotros :-P

Pero realmente, este es uno de los desafíos que se ponen algunos programadores, diseñar un lenguaje Turing completo que desafíen el ingenio, la creatividad y sentido del humor de todos los programadores en general.

Aquí dejo un enlace a más lenguajes de programación esotéricos.

Ruby… esa pequeña joya

El lenguaje de programación Ruby, creado por Yukihiro Matsumoto (a.k.a. Matz), fue ideado para ser un lenguaje que simplificara las actividades diarias y necesidades de programación de su creador, al igual que Perl (la otra joya) fuera creada por Larry Wall para cubrir sus necesidades como administrador de sistemas, Matz necesitaba un lenguaje que fuese igual o más potente que Perl, y con igual o mejor implementación de orientación a objetos que Python.

En su trabajo, Matz, usaba Perl, mientras desarrollaba Ruby en paralelo, hasta que fue lo suficientemente bueno como para reemplazarlo. El nombre de Ruby, por tanto, está motivado por la similitud, en simbología, con Perl. La primera liberación fue en 1995.

En Japón, Ruby ha llegado a tener más popularidad que Python. Los adeptos de Ruby, así como su creador sostienen que Ruby fue diseñado para ser más fácil, y además divertido.

Viendo muchas de sus librerías, y sus similitudes con las librerías de Perl, se entiende lo que se menciona acerca del paso de Perl a Ruby, al igual que la sintaxis, en lo que se refiere a expresiones regulares, la declaración y uso de datos de tipo array y hash. No obstante, Ruby tiene una característica básica, y es que, todos sus datos son objetos, es decir, lo que en Perl serían datos scalar, aquí son todos objetos.

Podría seguir con más parecidos, trozos de código y explicando cómo se programa en este lenguaje que cada vez me atrae más… pero casi prefiero que lo leáis en sus sitios habituales de referencia:

http://www.ruby-doc.org/

Espero que lo disfrutéis.

Sistemas de Control de Versiones: ¿centralizados o distribuidos?

Desde hace tiempo, la tendencia de uso de los sistemas de control de versiones, ha sido el uso centralizado mediante sistemas tan populares como CVS o Subversion. Ahora, desde que muchos grandes proyectos optaran por los sistemas de control de versiones distribuidos, cada vez hay más gente que se va cambiando a ellos y, sobre todo, proyectos grandes.

¿Será que es mejor el enfoque distribuido al centralizado?

Vamos a verlos ambos para llegar a una determinación, o al menos una leve explicación del porqué del cambio.

Enfoque Centralizado

Cuando se desarrollaron los sistemas de control de versiones, muchos de ellos se hicieron en esquema cliente-servidor, con lo que el desarrollo de las herramientas está claramente diferenciado entre:

  • el cliente, que es la aplicación que se conecta al servidor y mantiene una copia local del repositorio, así como se encarga, generalmente de la corrección de conflictos y la mayoría de lógica del sistema.
  • el servidor, que es el sistema que toma los datos del cliente y los almacena a espera de una o múltiples peticiones de esos datos. Este sistema se encargaría del almacenamiento de las versiones, control de concurrencia, bloqueos y otras características parecidas a las de las bases de datos.

¿Qué limitaciones y características posee? Haremos una breve lista:

  • El sistema servidor es un repositorio, como los que mantienen los clientes, pero perfectamente sincronizado y sin que dé lugar a conflictos. Es la copia maestra de los datos.
  • Cuando un sistema web quiere hacer un listado, puede tomar los datos de este servidor y siempre serán seguros, con lo que no tendrá que resolver conflictos, ni tendrá que hacer mezclas.
  • Una copia local debe de poder mezclarse con el repositorio central cuando queramos publicar un conjunto de cambios o cuando queramos tomar la última versión publicada en concordancia con nuestra copia local.
  • Es normal ver en muchos de estos sistemas ramificaciones, versiones, etiquetas, o similares, a modo de tener varias copias según nos interese. Estas ramificaciones están en el servidor y en algunos casos puede llegar a ser muy costosa su diferenciación.

Enfoque Distribuido

Desarrolladores como Linus Torvalds, Eric S. Raymond y otros más, han desarrollado sistemas distribuidos de control de versiones tales como git, Baazaar, Mercurial, darcs, … estos sistemas se destacan por haber sido desarrollados en un formato distribuido, esto quiere decir que, en sí, no hay un servidor que mantenga una copia del repositorio, sino que está mantenida entre los clientes que estén en uso del repositorio y, al igual que los clientes P2P, mientras más desarrolladores haya conectados, mejor conectividad habrá entre todos.

Esto da una serie de ventajas al sistema centralizado, como son:

  • Disponer de forma distribuida de la información del repositorio al completo, tanto de forma local, como a través de los demás componentes del grupo.
  • Cada cambio se va replicando entre los demás equipos distribuidos, a modo de que puedan emplear esos datos y actualizarlos en sus sistemas.
  • El sistema de control de versiones distribuido ha sido pensado con la forma de trabajo basada en ramas, unión central en una sola versión (trunk) y liberaciones (o tags). Con lo que cada rama puede identificarse como cada copia distribuida que se use.
  • Una máquina servidora puede emplearse, al estar siempre conectada, como otro punto de sincronización, con la ventaja de que, aunque cayera, mientras haya más miembros conectados, el sistema siempre se mantiene activo y con buen ancho de banda.

Conclusiones

Después de ver las ventajas, desventajas y características de cada uno, vemos que el uso de los sistemas distribuidos es más indicado, sobre todo, para proyectos con gran afluencia de desarrolladores. Por lo que, tenemos nuestra explicación al hecho del cambio de modelo en los grandes proyectos.

Desarrollo Orientado a Pruebas (TDD)

El desarrollo orientado a pruebas (TDD, test driven development) es una forma de desarrollar basándose en que un cierto algoritmo responda de una forma específica a unos datos específicos. Para explicar mejor esto, voy a explicar primero el enfoque tradicional y luego expongo las mejoras que introduce esta forma.

Enfoque Tradicional

Cuando se pide el desarrollo de un proyecto, lo que se pide es qué hay que hacer sobre el problema planteado. Por ejemplo, un programa de contabilidad, podría consistir, a grosso modo en almacenar los datos contables y ofrecer los informes correspondientes.

En el momento que pasamos a desarrollar la idea, el problema, entramos en el cómo hay que hacerlo. Se desarrolla un modelo en el que se plasma cómo almacenar los datos, cómo presentar los informes y desarrollamos nuestra aplicación basándonos en esas premisas.

Teniendo ya el software desarrollado, el programa ejecutable, pasamos a las pruebas, tras las cuales podemos descubrir fallos y pasar a corregirlos, así hasta que todos los fallos previsibles están controlados.

Si la batería de pruebas es muy completa, se puede tener un programa con un reducido número de fallos, puesto que los modos de uso del mismo habrán sido comprobados.

El problema de este sistema es que, si la previsión o las fases han sido realizadas de forma superficial, es muy posible que ciertos usos hayan escapado de nuestro diseño, es más, es posible que, aún habiendo pedido el cliente un cierto uso, lo hayamos malentendido o no funcione de forma correcta por una decisión de diseño mal orientada.

En ese caso, habría que retroceder hasta el punto del diseño, comprobar de nuevo los requisitos con esta nueva información y continuar hacia adelante. Es un proceso muy lento y tedioso.

Enfoque TDD

Basándonos en el principio YAGNI (you ain’t gonna need it?, ¿realmente lo necesitas?), podemos pedir unos casos que cubran la mayor parte de los casos practicables, según los requisitos, de modo que tengamos los datos de entrada y los datos de salida de nuestra aplicación, es decir, no solo saber qué proceso se debe de hacer, sino además, tener un ejemplo palpable de los datos que se deben de poder conseguir, para construir la aplicación con solo y exclusivamente lo que nos pidan.

Teniendo claro qué se debe de hacer, ilustrado con los ejemplos, pasar al cómo es bastante simple, puesto que se trata de realizar un programa que permita hacer el paso de unos datos, de una forma a otra, sin más.

La batería de pruebas está definida, desde antes de comenzar a codificar, y se pueden desarrollar unidades pequeñas que pueden ir probándose para ver que cumplen lo que se pide. Para esto podemos emplear sistemas de pruebas unitarias… los cuales comentaré en otro artículo.

En el ejemplo de las cuentas contables, puede pasar por determinar el uso de las cuentas contables en sí, los datos que se requieren almacenar para los informes y los datos que se deben de introducir por parte del usuario: número de cuenta, concepto, valor, etc.; en lugar de desarrollar un complejo programa que incluya todo referente a la contabilidad en sí.

Este enfoque, en sí fusiona los conceptos de codificación y pruebas, de modo que se hacen de forma conjunta, al disponer de datos para ello. Así mismo, incluye el diseño de las pruebas en el análisis, y se usan como requisito para el diseño, con lo que se puede apreciar que las pruebas, están presentes en todas las etapas de desarrollo y, no hay una etapa separada o específica para ellas, aunque pueda hacerse.

Conclusiones

El desarrollo basado en TDD es muy usado por grupos de desarrollo de metodologías ágiles, está muy probado y combina bien con Xtreme Programming y Scrum, por lo que aconsejo su uso en proyectos de cualquier tamaño.

Base de Datos Relacionales: SQLite, MySQL y PostgreSQL

Sobre los SGBD, cabe destacar, entre los que son libres, estos tres motores, de los cuales, dos de ellos son sistemas servidores y gestores de base de datos relacionales (MySQL y PostgreSQL) y otro es tan solo un motor embebido para aplicaciones monousuario o de muy baja carga (SQLite).

Los sistemas libres han hecho gala del uso de LAMP (Linux, Apache, MySQL y PHP) para el desarrollo rápido de webs. Estos sistemas son fáciles, rápidos y cómodos para usuarios nóveles, dan mucho control sobre el desarrollo y permiten, gracias a la cantidad de proyectos ya desarrollados, tener a disposición Foros, Bitácoras, CMS, ERP, CRM y muchos más tipos de webs.

La elección de estos elementos es algo que se suele dejar al administrador de la máquina. No solo hay que instalarlos, eso tan solo se hará una vez, sino que hay que mantenerlos, y eso se debe de hacer de una forma reiterada. Por lo que la elección del sistema operativo: Windows, Linux, BSD, Solaris…; es algo que debe de decidir quien lo vaya a administrar, al igual que el servidor propio web, ya que si se usa solo para servir páginas HTML y PHP, puede emplearse cualquier servidor web: Apache, Cherokee, Lighttpd, Caudium, Yaws, etc.

El empleo del lenguaje de programación viene determinado por lo que se vaya a emplear. Como es lógico, sino sé programar y quiero usar WordPress, es normal que instale PHP, ya que sino es completamente imposible. Pero si sé programar en Java, C#, Ruby, Python, Perl, o cualquier lenguaje de scripting actual, es muy posible hacerlo, con los módulos correspondientes o sistemas de CGI.

Entonces, después de esto, nos centramos en la base de datos. Elegir un SGBD es algo que no se debe de considerar trivial, puesto que de su elección derivarán los problemas o virtudes que podamos tener a la hora de administrar el sistema, hacer copias de seguridad, etc.

SQLite

Por ejemplo, para una web a la que solo tenemos acceso para escribir artículos nosotros, los comentarios son moderados y no hay mucho tráfico, se puede configurar, sin ningún tipo de problemas, para usar SQLite. Usar este sistema nos asegura mayor facilidad a la hora de realizar copias de seguridad y nos quita un punto único de fallo, puesto que sino hay conexión con la base de datos, no hay posibilidad de que falle.

Lo mejor de todo es la cantidad de integración de SQL que tiene el motor, ya que permite una integridad referencial bastante buena, procedimientos almacenados, triggers y otras bondades muy deseables en un SGBD.

Lo peor es que si el tráfico de nuestro sitio web sube, y/o la información a guardar comienza a subir demasiado, como todo se guarda en un único fichero, el sistema podría verse ralentizado.

MySQL

Para sistemas web de alto número de visitas, con gran cantidad de datos en modificación, inserción y consulta, se desarrollo este SGBD: MySQL.

MySQL destaca de la mayoría de SGBD en su velocidad cuando se emplean las tablas MyISAM, puesto que, para su aceleración, hace omisión de uso de muchas características típicas en SGBD, como es el caso de la integridad referencial, la cual solo está disponible si se usa el engine de InnoDB.

Con una máquina de un solo procesador, tablas MyISAM y las acciones básicas de consulta, inserción, borrado y actualización, MySQL ha demostrado que es de los SGBD más rápidos del mercado, incluidos los SGBD privativos. Por lo que para el uso de webs de estas características, principalmente bitácoras, algunos tipos de CMS, foros y similares, este SGBD está muy indicado.

El punto débil, no obstante, es precisamente su libertad, la falta de integridad referencial controlada por el SGBD y su escalabilidad. MySQL dispone de un engine específico para montar clústers, pero su uso es aún un poco básico y con muchos flecos que remendar.

Otro punto positivo de MySQL es su gran cantidad de documentación, tanto en inglés como en castellano y otros idiomas que está en su propia página web.

PostgreSQL

Para altas cargas y sistemas de gran actividad concerniente a la base de datos, ya sea por consultas complejas, integridad referencial o gran cantidad de consultas, está mejor indicado PostgreSQL.

Este SGBD tiene una gran cantidad de mejoras con respecto a la concurrencia, escalabilidad y alta carga, que da un nivel de confiabilidad mucho mayor que los dos sistemas mencionados anteriormente. En principio, el hecho de que una consulta de gran tamaño no bloquee una tabla, sino que se vayan acumulando operaciones de lectura y escritura como si commits de un sistema de control de versiones se tratara, da un gran nivel de concurrencia, al mismo tiempo que permite procesar consultas mucho más eficientemente y rápidamente.

Por otro lado, la gran cantidad de proyectos que giran entorno al sistema, han hecho que dispongan de herramientas que le permitan estar configurado en forma de clúster y reaccione de la misma forma, pero con mucha más capacidad, haciendo su rendimiento creciente de forma logarítmica, ha demostrado que, en varias máquinas con varios procesadores, reacciona de una forma más eficiente y rápida incluso que MySQL.

El punto negativo de este SGBD es que no está tan facilitada su instalación y configuración, ya que se basa en unos principios que hay que conocer previamente. Lo bueno, a este respecto, es que dispone de gran cantidad de documentación, incluso en castellano.

Conclusiones

Para sistemas pequeños, de poca carga, sin duda, yo empleo siempre que puedo SQLite. En caso de desbordar, extraer una copia y ponerla en un sistema como MySQL o PostgreSQL no es nada complicado.

Para sistemas CMS, Bitácoras, Foros y sitios simples en Internet que tengan previsión de carga, siempre es mejor montar un SGBD y, si se quiere hacer simple, lo mejor es usar MySQL.

Cuando ya intervienen factores como que la base de datos tiene muchas tablas, está muy normalizada y tiene riesgos de que se pierda su integridad referencial, así como es el caso de la programación de un CRM, ERP o programa orientado a la empresa o red social, en ese caso es mejor emplear PostgreSQL, ya que dará mayor seguridad, al mismo tiempo que mayores prestaciones en caso de necesitar escalar.