10.24.07
Posted in .NET, PHP, Ruby On Rails, Tecnología, Web at 10:05 pm by Miguel
Una conversación en la noche de ayer con un amigo ha inspirado este post, ¿cuál es la tecnología web más adecuada para mi proyecto?
Uf, ¡qué difícil pregunta! Como siempre una respuesta genérica a esta pregunta es, PUES DEPENDE. Y es que la verdad es cierto, va a depender de muchos factores. No pretendo sacar ningún tipo de conclusión al respecto después de haber terminado este post, pero sí almenos aproximar un poco los factores que bajo mi punto de vista afectan a nuestra decisión.
Antes de nada empezar diciendo que no existe una tecnología absolutamente mejor que las otras, habrá una tecnología que para los factores que rodean tu proyecto será mejor que las otras en un momento dado. Y digo en un momento dado porque ese es el primer problema a la hora de elegir, que contamos con las circunstancias y las previsiones del momento. Las previsiones y las planificaciones, pueden fallar, quedarse cortas o pasarse de largo… y si esto puede ser crítico a la hora de definir un requerimiento funcional imagínate al decidir la plataforma tecnológica sobre la que tu aplicación se va a asentar.
Pero bueno, vayamos al grano y pasemos a hablar un poco de los factores que pueden influenciarnos. Empiezo con los más típicos para luego ir dándole vueltas a otros algo más rebuscados.
Multi-Plataforma
Si tu proyecto tiene entre sus restricciones que sea publicable a través varias plataformas del mercado estás de suerte, almenos a la hora de tachar algunas de las opciones que estés barajando. De todas maneras, un humilde consejo en este aspecto es recapacitar realmente si es realmente necesario que sea multi-plataforma, porque muchos veces lo ponemos de restricción cuando luego al final trabajamos con una y listo. El concepto de multi-plataforma vende mucho, es un cartel muy bueno de marketing, ¿pero realmente lo necesitas?
Sin Coste Económico o de Coste Bajo
¿Puedes pagar licencias? ¿Quieres pagar licencias? Tal vez tengas presupuesto para ello, o tal vez no.
Alta Productividad
Cuidadín con este aspecto, existen plataformas tecnológicas que están directamente orientadas a la productividad, si este es uno de nuestro requerimientos principales, adelante con ellas.
Tamaño del Proyecto
No es lo mismo un proyecto de dos meses que uno de seis que uno de un año. Y aquí no juega sólo lo que tienes pensado hacer ahora, si no la previsión de crecimiento que crees que vas a tener. No es lo mismo estar convencido que vas a desarrollar un componente web que saber que si la cosa va bien vas a tener que empezar a agregar más módulos a la aplicación.
Formación de tus Recursos
Tal vez en tu equipo de trabajo cuentes con personas que tengan experiencia en una plataforma en concreto. Y aprovecho aquí para hacer un inciso: el llevar a cabo una formación de dos, tres semanas en una determinada tecnología para luego acometer un proyecto nada más salir no suele traer buenos resultados (retrasos sobre todo) si no acompañas el grupo de trabajo de algún recurso que ya tenga experiencia contrastada en ella.
IDE
.NET tiene Visual Studio, Java tiene Eclipse/NetBeans/Java Studio Creator, PHP tiene Zend Studio, Ruby on Rails tiene Aptana…
Seguridad
¿Te preocupa especialmente la seguridad? ¿La información que provee o captura tu web debe tratarse de forma especialmente segura?
Servicios Web, Ajax…
Existe plataformas que aportan más facilidades que otras para crear Servicios Web o trabajar con Ajax. Y vuelvo a aprovechar la ocasión para hacer otro inciso, cuidadín con el uso de Ajax, si queréis que vuestra aplicación web funcione como una aplicación de escritorio, no construyáis una aplicación web, construid una de escritorio. Ajax es una herramienta que nos puede ayudar puntualmente para resolver ciertos problemas, pero no se debe abusar, o se volverá contra vosotros.
Integración con el Sistema Gestor de Bases de Datos
Me explico, .NET está especialmente diseñado preparado para trabajar contra SQL Server, Java contra Oracle, PHP contra MySQL… Combinaciones del tipo .NET + Oracle o PHP + SQL Server pueden traeros problemas.
Comunidad, Soporte
Algunas plataformas tienen una empresa detrás que te puede dar soporte ante los problemas que puedan surgir, o una comunidad de usuarios más o menos amplia que te ayude a resolver las dudas.
…
Y aquí me paro, creo que por ahora ya quedan presentes algunos de los factores para echarles un ojo y darles alguna vuelta… pero antes de terminar quisiera comentar cuatro cosas sueltas más a la hora de encarar el desarrollo de una aplicación web.
1) Existen tecnologías satélite a las diversas plataformas del mercado y que son comunes a todas ellas. Estas tecnologías conviene conocerlas, saber cual es su función, para qué las podemos usar y para qué no. Me estoy refiriendo a Javascript, CSS, HTML, XHTML, XML, XSL, JQuery, JSON, AJAX, SOAP, WSDL… No me refiero a empollármelas todas, pero sí saber para qué son cada una de ellas y dónde les puedo sacar partido.
2) Desarrollar una aplicación de escritorio no es lo mismo que desarrollar una aplicación web. La gente que trabaja en web tiene muy fácil pasar a trabajar con aplicaciones de escritorio, cuando la historia es alrevés la penalización es más grande (pero no imposible claro está, estoy hablando de que se necesita algo más de tiempo para ubicarse).
3) Intentad definir un único navegador y una versión del mismo para vuestro proyecto, o seguramente os volváis locos. Si trabajáis con una intranet o algo más cerrado os será viable definirlo así, si tenéis como requisito que vuestra web funcione con varios navegadores del mercado, almenos intentad marcar la versión de cada uno. No es lo mismo desarrollar para un Internet Explorer 6 que para un 7.
Fuf, cada vez me enrollo más en los post, voy a tener que empezar a recortar
Saludos.
Miguel.
Permalink
10.23.07
Posted in Bases de Datos, Patrones, Programación at 10:14 pm by Miguel
Y como no, sigo dándole vueltas a mejorar el acceso y la protección de los datos.
Antes de empezar a haceros un breve resumen de lo que es un DAO y un DTO os dejo primero unos links donde podréis verlos en marcha de forma mucho más concreta.
http://en.wikipedia.org/wiki/Data_Access_Object
http://en.wikipedia.org/wiki/Data_Transfer_Object
http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html
El chiste del DAO es que nos provee de una forma totalmente abstracta de acceso a datos. Es decir, puedo acceder a mi modelo de datos, pero únicamente a través del conjunto de métodos que me brinda un DAO. Si tengo un DAO para coches, por ejemplo CocheDAO, en él deberé tener definido por ejemplo un método Count() que me retornará el total de coches que tengo en mi base de datos. No sé cómo está implementado, ni qué base de datos utiliza (si es que accede a una base de datos), lo único que sé es que resuelve mi problema.
Por lo tanto, desde la parte del Controlador de mi aplicación, puedo acceder a mi Modelo utilizando el patrón de diseño que ofrece DAO, de forma totalmente transparente. Esto por ejemplo nos llevaría a pensar que nuestro CocheDAO podría contener otros métodos, como el método Delete (que borraría un coche de la base de datos), Update (que actualizaría los datos de un coche), GetCochesByMarca (que a partir de una marcha retornaría los coches de la marca que hay en la base de datos), etc.
Todo esto suena en principio a lo mismo que sería tener una clase llamada Coche llena de métodos static a los cuales llamaría cuando fuera necesario. Esto, pues claro, resuelve el problema de tener todo el acceso a la tabla Coche centralizado, olé, bien, somos ordenados, pero DAO va mucho más allá. ¿Cómo resolveríais el problema de devolver un listado de coches a través de vuestra clase con métodos static? Pues a lo mejor vuestro método GetCoches() retorna un dataset rellenado con los coches, o un datareader/recordset, o una lista separada por comas, o una estructura xml, o un array… Pero los DAO incluyen otro concepto que es del los DTO. Los DTO son un tipo de objetos que sirven únicamente para transportar datos. Por ejemplo, el objeto de transferencia de datos de un coche podría ser un CocheDTO (o CocheBean para los javeros). Entonces, DAO, lo que devuelve es una lista genérica de CocheBean, o tal vez un CocheBean si estamos buscando información de un solo coche. Para que os hagáis una idea, un CocheBean contiene únicamente propiedades de un coche como por ejemplo Marca, NumeroPuertas, Matrícula, etc. El DAO, tras una petición del Controlador, rellena un DTO o un conjunto de ellos, y lo devuelve al Controlador.
¿Y todo este lío para qué? Pues muy sencillo, si vuestro controlador ataca al modelo utilizando DAO y DTO estáis consiguiendo 100% la separación entre el Controlador y el Modelo. Ante cualquier cambio que se diera en la forma de acceder a los datos, pongamos por ejemplo que a partir de ahora en lugar de sacar los coches de una tabla coches se hace de un servicio web que retorna coches, vuestro modelo no se va a enterar, ya que lo que le va a seguir llegando van a ser siempre CocheBean. Conseguís un impacto cero patatero en vuestro Controlador (y en la Vista claro, pero eso ya lo habíamos conseguido separando la Vista del Controlador).
Y aún más, si cada uno de vuestros DAO lo preparáis para seguir el patrón Singleton, tendréis siempre una única instancia de la clase CocheDAO en memoria, por lo que aunque tengáis 200 usuarios tirando de dicho DAO tendréis una única copia en memoria, con el ahorro que esto supone. Esto no ocurre por ejemplo si usáis static en todos los métodos de vuestras clases de acceso a datos (y os recuerdo que en un proyecto mediano el número de métodos que llegan a acumularse para acceso a datos suele ser bastante grande).
¿Un ejemplo de código? Venga, vale, aceptamos barco, imaginaos que atacamos a una hipotética clase CocheDAO:
// GetInstance pide la instancia de la clase mediante el Singleton, CocheDAO tiene su constructor en modo privado.
CocheBean coche = CocheDAO.GetInstance().GetCocheByMatricula(‘IB-3234-ZX’);
// ahora tenemos un CocheBean, si no es nulo es que ha llegado bien, cogemos sus datos
if (coche != null)
{
txtMatricula.Text = coche.Matricula;
txtMarca.Text = coche.Marca;
txtNumeroPuertas.Text = coche.NumeroPuertas;
}
¿Y qué ocurre en el Controlador si cambiamos el nombre del campo matrícula en la tabla coches? Pues nada, ni se entera.
Para finalizar os añado un link a un rar que he preparado con un DAO y un DTO preparados, que acceden a una hipotética tabla de Coches. Fijaros en el DAO lo que hace el Singleton, que además de forzar la utilización del método GetInstance, utiliza exclusión mútua para evitar que se tenga más de una instancia del DAO en el caso de no haberse creado aún la instancia y dos usuarios accedieran al mismo tiempo al método GetInstance. El método GetCoche retorna un CocheBean, pero el método GetCoches lo que hace es retornar un lista genérica de CocheBean. Veréis además que CocheDAO hereda de BaseDAO, todos los DAOS deberían heredar de allí ya que BaseDAO les ofrece entre otras cosas la conexión a la base de datos y una serie de métodos comunes que pueden utilizar (BaseDAO lo he dejado algo básico sólo para que se entienda conceptualmente qué es lo que se supone que debe hacer). También tenéis la definición de CocheBean. Por último, veréis que existe un archivo llamado Excepciones donde se tipifican las excepciones que puede generar un DAO, una de las buenas prácticas de las que ya hemos hablado en otros artículos.
Os contaría además que DAO puede implementarse junto a DTO, pero además utilizando el modelo de Factoría, pero esto, lo dejaremos para más adelante.
Ejemplo DAO (esta vez os lo preparo en VB.NET, por variar un poco).
¿Interesante?
Saludos.
Miguel.
Permalink
10.22.07
Posted in Bases de Datos, Programación at 11:02 pm by Miguel
Y es que últimamente le doy muchas vueltas a la protección del modelo de datos. Me quedan aún en la manga almenos un par de artículos más al respecto, siendo este uno de ellos.
Hoy hablaremos un poco de cómo proteger la base de datos mediante un método que me parece bastante curioso, y un poco peñazo sobre todo. Este método lo utilizan sobre todo empresas que dan acceso a una de sus bases de datos a un equipo de trabajo externo, ajeno a la empresa.
Resumiendo la historia un poco, la “técnica” se basa en que todo acceso a la base de datos (SELECT, INSERT, UPDATE, DELETE) se lleve a cabo mediante un procedimiento o función almacenada. Desde una SELECT algo pesada, a cualquier inserción modificación y borrado simple de un registro. ¿Y por qué trabajar de esta manera? Pues es para asegurarse de que sólo se va a acceder a la base de datos a través de dichos procedimientos almacenados. Se crea un usuario de base de datos que tenga permiso de ejecución sobre dichos procedimientos, y sólo para dichos procedimientos, y ese usuario se le da a la empresa externa para que haga login contra la base de datos mediante ese usuario.
Este sistema, a parte de la protección tiene alguna cosa más buena, y es que todos los procedimientos de acceso a datos están centralizados en un único punto… y que además, los procedimientos que sean pesados, al llevarse a cabo directamente sobre la base de datos, se ejecutan mucho más rápido que si se estuvieran lanzando sobre el cliente.
¿Cosas malas? Pues como siempre alguna hay. Por ejemplo, si trabajáis con SQL Server, los procedimientos almacenados no pueden agruparse en Paquetes (así como sí puedes hacerlo en ORACLE), por lo que si tienes un número grande de procedimientos almacenados, al final tienes una lista interminable que cuelga de una rama y que es un rollo de gestionar. Otra cosa mala, que parecerá una chorrada pero a mi me molesta especialmente es que para hacer una select simple que devuelve un registro o un grupo de registros o incluso un valor… tener que crear un procedimiento almacenado la verdad es que me parece un verdadero engorro. Además, tened en cuenta una cosa, a la hora de actualizar cualquier procedimiento almacenado vais a tener que generar un script de actualización y otro con las contramedidas, para luego desplegarlo en el servidor de pruebas… preproducción, producción… (vale, en otro caso tendríais que actualizar aplicación, pero bueno, que está claro que lleva trabajo).
¿Y qué os parece el utilizar una mezcla entre ambos extremos, es decir, parte del acceso a datos definido en el cliente y parte en procedimientos almacenados? Pues… una vez leyendo un informe de una persona Certificada por Sun lei que no era una forma adecuada el tener parte del acceso a datos definido en la base de datos y parte en la aplicación, porque a la hora de desarrollar no sabes muy bien por donde buscar, al tener repartido los accesos en diferentes componentes de la aplicación… ¿tenía razón esta persona? Pues la verdad es que aún le sigo dando vueltas…
Saludos.
Miguel.
Permalink
10.21.07
Posted in PHP, Personal at 2:54 pm by Miguel
Es una noticia que se publicó a mediados de julio en http://www.php.net pero que no había caido en comentar por aquí. El soporte de PHP4 termina a finales de este año. PHP5 está con nosotros desde hace ya tres años, y PHP6 empieza a asomar la cabeza, por lo que se ha decidido finalizar el soporte que se estaba dando a PHP4.
La verdad es que esta noticia me toca bastante en lo sentimental, ya que PHP4 fue la primera plataforma en la que desarrollé mi primera “verdadera herramienta”, aquella ya lejana KTFCL, Liga Española de Team Fortress Classic, en la que al final de sus días llegaron a estar registrados más de 800 jugadores, tanto españoles como del resto de europa.
PHP4 me enseñó de verdad lo que era trabajar en web con un lenguaje de servidor. Atacando a una base de datos MySQL, utilizando javascript para el cliente, sesiones, autenticación de usuarios, hoja de estilos, incluso un rudimentario pero efectivo método para hacer la web multi-idioma. Más adelante vino alguna otra web, como la de Profundo Azul, donde ya además se empezó a explotar de verdad la pobre orientación a objetos que disponía PHP4. Monté clases para gestionar el acceso a la base de datos, crear thumbnails al vuelo, incluso algunas para generar controles de servidor a través de PHP4 y que permitían generar el HTML directamente de listbox, textbox, repeaters… al más puro estilo los controles de servidor de ASP.NET 1.1 del momento, pero todo hecho en PHP4.
La verdad es que fue todo muy divertido, y además, me sirvió para aprender muchos conceptos que hoy en día siguen siendo muy útiles.
He estado ahora leyendo parte del código PHP de esas clases y me ha parecido curioso así que lo voy a dejar aquí publicado para que veais un poco como fue su desarrollo. Me hace gracia porque es código que hice hace más de tres años, y veo en él muchas aspectos de programación que aún quedaban por pulir, mejorar… incluso que alguna de las buenas o malas prácticas que he propuesto en la web se cumplen o no se cumplen en el mismo. Qué curioso… te ves un poco a ti mismo al mirar ese código
Clase MySQL v0.3
Clase Thumbnail v0.3
Clase DropDownList v0.1
Hasta siempre PHP4.
Saludos.
Miguel.
Permalink
10.17.07
Posted in Gestor de Curriculums, Herramientas, Metodologías, UML at 9:29 pm by Miguel
Buceando por la red he encontrado una plantilla (en inglés) bastante buena para completar casos de uso.
Tanto me ha gustado que en el Documento de Casos de Uso que estoy preparando para el Gestor de Curriculum (no me he olvidado de su desarrollo, la cosa es que no tengo demasiado tiempo para dedicarle), voy a seguir la plantilla prácticamente al completo.
Como podréis ver, se incluye una descripción completa de cada uno de las entidades a rellenar en la plantilla.
Descargar Plantilla de Casos de Uso
Saludos.
Miguel.
Permalink
Posted in .NET, Buenas Prácticas, Gestión del Mantenimiento, Programación at 3:46 pm by Miguel
Y es que muchas veces nos olvidamos de que nuestro código va a tener que ser interpretado, leído y mantenido por otras personas, o incluso por nosotros mismos en un futuro.
Mantener estructuras similares a la hora de programar, un estilo de programación, un orden determinado y un código claro, harán que la mantenibilidad de nuestras aplicaciones se dispare. Este aspecto se ve aún más potenciado en grupos de trabajo de alta volatilidad, donde la estabilidad del número de profesionales que forman el grupo es alta. Me refiero tanto a la baja de miembros del equipo como a la rápida incorporación de nuevos profesionales para aumentar el tamaño del grupo.
Quisiera dejar patente la diferencia de legibilidad y mantenibilidad entre dos fragmentos de código que llevan a cabo exactamente la misma funcionalidad
Ejemplo de baja legibilidad y mantenibilidad (código C#):
public bool NumPuerMayorQue(int t)
{
int n = 0;
coche[] lista = DameListaCoches();
for(int i=0;i<lista.lenght;i++)
n = n + (coche)lista[i].NumPuertas;
if (n>t)
return true;
else
return false;
}
Ejemplo de mejor legibilidad y mantenibilidad
/// <summary>
/// Añade un nuevo parámetro a la lista
/// </summary>
/// <param name=”numPuertas”>Número de puertas a comparar</param>
/// <param name=”lista”>Lista genérica de coches sobre la que hacer el cálculo</param>
/// <returns>Retorna verdadero en el caso de que la variable numPuertas pasada por parámetro sea mayor que el resultado de sumar todas las puertas de los coches pasados por parámetro en la variable lista. Retorna falso en caso contrario, es decir cuando es menor o igual.</returns>
public bool IsNumeroPuertasMayorQue(int numPuertas, List<coche> lista)
{
int total = 0;
foreach (coche unCoche in lista)
{
total += unCoche.NumPuertas;
}
return (total > numPuertas);
}
Aspectos que hacen notar la mejora de la mantenibilidad y la legibilidad de ambas funciones
1) Se dispone de un comentario sobre qué labor va a realizar la función, qué papel juega cada uno de sus parámetros y qué valores se esperan retornar y en qué condiciones.
2) El nombre de la función, al marcar el prefijo “Is” ya nos da la pista de que va a devolvernos un booleano. IsNumeroPuertasMayorQue da más pistas al desarrollador que NumPuerMayorQue.
3) La lista de coches es pasada por parámetro a la función, siendo además una lista genérica. Sabemos exactamente de dónde nos llega la lista.
4) Uso de foreach en lugar de for. Usando foreach aumentamos la legibilidad y la elegancia de nuestro código.
5) Uso de lista genérica en lugar de arrays. Nos estamos evitando hacer el cast “(coche)lista[i]“, que además no nos asegura que lo que realmente tenga la lista sean objetos de tipo coche, puede darse un error de casting.
6) El nombre de las variables utilizadas es mucho más descriptivo.
7) Llaves en sentencias de una sóla línea. Realmente funcionan igual, pero si a las sentencias for, foreach, if y else le añadimos llaves de apertura y cierre aunque incluyan una única sentencia, lo leeremos mejor.
Creo que queda bastante claro que se lee mejor “return (total > numPuertas)”
9) Una linea en blanco entre bloques. ¿La vista lo agradece, no?
Saludos.
Miguel.
Permalink
10.10.07
Posted in Bases de Datos, Malas Prácticas, Programación at 2:27 pm by Miguel
Hace no demasiado inaguré la sección de Buenas Prácticas, sección en la que ya se han añadido algunas entradas con recomendaciones al desarrollador.
Hoy dándole vueltas a una nueva buena práctica para añadir (y después de haber oído una barbaridad por la oficina), he pensado que tal vez sería interesante hablar también de las cosas que no hay que hacer bajo ningún caso, de ahí surge esta nueva sección llamada “Malas Prácticas”.
Como primera mala práctica vamos a hablar de una forma que se utiliza para obtener la secuencia de la primary key de una tabla. Insisto es una mala práctica, la cual no recomiendo para nada usar, más adelante se explicará por qué.
Como siempre, lo describo con un ejemplo, que es la forma en la que creo yo que todo queda más claro.
Pongamos el caso de que tenemos una tabla llamada COCHE que consta de dos campos, COCH_CODIGO Y COCH_NOMBRE. COCH_CODIGO es la clave primaria de la tabla, y es de tipo numérico. COCH_NOMBRE es un texto de tamaño 50 caracteres.
Un requerimiento de nuestra aplicación exige que al dar de alta un nuevo coche en nuestra base de datos, asociemos el código del coche al usuario que ha insertado el coche (imaginemos que la tabla USUARIO contiene un campo llamado COCH_CODIGO donde se guarda la referencia al coche del usuario).
Una MALA PRÁCTICA es intentar resolver este problema de la siguiente manera (utilizo pseudocódigo)
/* Obtenemos el código del usuario */
codigoUsuario = obtieneCodigoUsuarioActual();
/* Obtenemos la Id del último coche que añadimos */
int ultimaId = devuelvePrimerRegistro(“SELECT MAX(COCH_CODIGO) +1 FROM COCHE”);
/* Insertamos el registro */
ejecutarSQL(INSERT INTO COCHE (COCH_CODIGO, COCH_NOMBRE) VALUES (ultimaId, ‘Coche Fantástico’));
/* Actualizamos los datos del usuario */
ejecutarSQL(UPDATE USUARIO SET COCH_CODIGO = ultimaId where USUA_CODIGO = codigoUsuario);
¿Dónde está aquí el problema? …
¿Que ocurriría si dos usuarios al mismo tiempo fueran a dar de alta un nuevo coche? Fijaros en la secuencia
1) El primero haría el SELECT MAX y obtendría el código 23.
2) Antes de que el primero haga el INSERT en la tabla COCHE, el segundo haría el SELECT MAX y obtendría también 23
3) El primero hacer el INSERT, todo va bien.
4) El segundo hacer el INSERT… y PUM, CONSTRAINT ERROR, Clave Primaria duplicada.
¿Soluciones? Afortunadamente existen unas cuantas.
1) Secuencias ORACLE
Si usáis como base de datos ORACLE estáis de suerte, ya que aquí existe el concepto de secuencia. Puedes crearte una secuencia para cada tabla, y antes de realizar el insert pedir el siguiente número de dicha secuencia.
int secuencia = devuelveEscalar(“SELECT SEQ_COCHE.NEXTVAL”);
ejecutarSQL(INSERT INTO COCHE (COCH_CODIGO, COCH_NOMBRE) VALUES (secuencia, ‘Coche Fantástico’));
ejecutarSQL(UPDATE USUARIO SET COCH_CODIGO = secuencia where USUA_CODIGO = codigoUsuario);
Cuando el segundo usuario que ataque al código concurrentemente pida la secuencia, nunca será la que ha tenido el primero, por lo que nunca saltará la constraint de la foreign key.
2) Secuencias a media
Si trabajáis por ejemplo en SQL Server no tenéis secuencias. Pero eso no quiere decir que no podáis currároslas vosotros. Por ejemplo, podríais crear una tabla llamada SECUENCIA, donde tengas campos por cada una de las tablas de vuestra base de datos. Los campos serían de tipo entero.
Os creais una función que le paséis el nombre de la tabla, y que os busque en la tabla SECUENCIA el campo correspondiente a esa tabla, os lo retorne y actualice el campo en la tabla SECUENCIA.
Realmente con esta forma de trabajar podríais hacer igual que con Oracle, pero currado por vosotros.
3) Procedimientos Almacenados
Los procedimientos almacenados os proveen de herramientas para devolveros los datos producidos en un INSERT. Por ejemplo en PL/SQL tenéis la instruccion RETURNING, y en Transact/SQL tenéis el comando @@IDENTITY que te devuelve la última identidad obtenida para la conexión activa.
Saludos a todos.
Miguel
Permalink
10.03.07
Posted in .NET, Buenas Prácticas, ClasesAvanzadas.dll, Programación at 8:41 pm by Miguel
Fruto del anterior post sobre buenas prácticas, se me ha ocurrido la idea de ir añadiendo las clases que os vaya comentando en una dll, para que así podáis probar su funcionamiento y aprovecharlas para vuestros desarrollos. La dll está realizada en C# y podréis referenciarlas en vuestros proyectos con la plataforma .NET
En la primera release incluyo la clase Redireccion, que os ayudará a hacer más legibles y mantenibles vuestros response.redirect.
ClasesAvanzadas.dll v1.0.0.0
Se aceptan comentarios, mejoras, errores…
Saludos.
Miguel
Permalink
Posted in .NET, Buenas Prácticas, Programación, Web at 1:51 pm by Miguel
Supongo que estaréis acostumbrados a ver cosas como estas (código C#)
Response.Redirect(“~/home/pepito.aspx?idarticulo=” + idarticulo.toString() + “&idusuario=” + idusuario.toString() + “&idcategoria=” + idcategoria.toString() + “&activo=” + activo);
En el caso del ejemplo tenemos la instrucción response.redirect, la cual muchos de vosotros conoceréis, y que se encarga de redireccionar a nuestro navegador a la url que se le pasa por parámetro. Muchas veces vamos a necesitar pasar valores en la URL para que sean recogidas en la página de destino, y “no nos queda más remedio” que hacerlo de esta manera.
La verdad es que para redirecciones con urls sencillas aún es tratable, pero como tengamos que empezar a concatenar parámetros y más parámetros, te puedes volver loco. Por ello, una buena práctica resulta el encapsular todos estos oomportamientos para ayudar en la lectura del código y el posterior mantenimiento de la aplicación.
Os dejo aquí el comportamiento de hipotética clase que encapsula esta buena práctica, a ver si qué os parece (código C#)
Redireccion miURL = new Redireccion(“~/home/pepito.aspx”);
miURL.AddParameter(“idarticulo”, idarticulo);
miURL.AddParameter(“idusuario”, idusuario);
miURL.AddParameter(“idcategoria”, idcategoria);
miURL.AddParameter(“activo”, activo);
miURL.Ir();
¿Cómo lo leéis mejor? ¿Os hacéis una idea de lo que hace por dentro la clase, no?
AddParameter es un método sobrecargado donde el primer parámetro es el nombre y el segundo el valor. Podemos pasarle como valor diferentes tipos de datos, ya que está sobrecargado con el tratamiento para cada uno de ellos.
El constructor acepta un parámetro de entrada que es la base de la url a la que vamos a llamar, aunque podríamos instanciar la clase sin pasarle ningún parámetro, y luego usar la propiedad miURL.URLBase para definirla.
Por supuesto, y siguiendo las buenas prácticas, la clase Redirección debería encapsular también sus excepciones propias que lanzaría en los casos necesarios y que podrían capturarse desde fuera. Por ejemplo, ¿y si instanciamos la clase sin pasarle la URL base y tampoco la añadimos usando la propiedad? Al lanzar el método Ir() debería saltar una “NoHayURLBaseDefinidaException”, ¿no creéis?
Otro consejo para rematar, sería sobreescribir el método toString() de la clase, para que devolviera la URL generada hasta el momento, y así poder hacer cosas del tipo:
MostrarMensaje(“Esta es la URL Generada: “+ miURL);
Esta forma de encapsular las construcciones complejas es aplicable a otros campos, como por ejemplo para generar una secuencia SQL. Otro día os dejo un ejemplo.
Saludos.
Miguel.
Permalink