miércoles, febrero 25, 2009

Reunión 27 de la comunidad TJ.NET

Hoy será la reunión 27 de la comunidad TJ.NET donde estaré presentando el tema de XML Literals en Visual Basic.

Mostrare como carga un archivo XML y con los datos crear un objeto del dominio y a partir de un objeto del dominio del problema crear un archivo XML. Ademas de mostrar como realizar una búsqueda en el documento XML utilizando LinqToXml.

Debido al poco tiempo sera una presentacion sencilla sin entrar mucho a detalle. Espero que los asistentes tengan preguntas, para hacerlo mas interesante.

domingo, febrero 01, 2009

Iniciando con Test Driven Development (TDD)

Al iniciar con TDD , en algunos proyectos, note que esto ha hecho que cambie mi manera de programar. Ya que al tratar de escribir código de manera que sea testeable, termino escribiendo código mas desacoplado y con mas clases que hacen un trabajo mas especifico y con un poco de dependency injection. también he notado que ahora escribo mucho mas código y el resultado a veces es el mismo que antes (con la desventaja que me tarde mas). Aunque muchas veces los tests me han ayudado a encontrar errores mas rápido y me siento mas seguro de que el código que escribo funciona correctamente.

Por el momento estoy utilizando NUnit y NMock para mis unit test en .Net. Para mi gusto estos frameworks están bien para el tipo de tests que realizo.

Por ejemplo, supongamos que estamos construyendo un registro para usuarios. Y queremos que (cuando un usuario nuevo se registre) se validen los datos del usuario, se inserte a la base de datos y se envié correo de bienvenida.

Al escribir el test para el método de registro, debemos de evitar que este tengan dependencias en otras partes del sistema ya que solo queremos validar que se realicen las reglas de negocio y no tanto como se implementa cada tarea (para cada tarea se realizarán sus propias pruebas unitarias) esto me hace escribir mas clases de tal forma que pueda hacer mock objects para las dependencias.

Entonces en lugar de una sola clase para el registro (RegistrationService) que se encargue de validar, insertar y enviar correo, tendremos varias clases que colaboran para realizar el registro. Como pueden ser: RegistrationService, RegistrationValidator, EmailService y RegistrationDAL. Así podemos probar que el RegistrationService realice la regla de negocio y por separado probar cada una de las tareas. Ademas, si por alguna razón cambia la manera de validar el registro, solo tendríamos que modificar la clase RegistrationValidator y no tenemos que cambiar el resto del proceso de registro. Como ven esto implica realizar mas código, pero se supone que a la larga es mejor, Ahora tenemos código que valida nuestro código.

En mi caso realizar unit tests si me ha ayudado a encontrar errores y a estar seguro de que el código hace lo que tiene que hacer. Aunque debo admitir que hay veces que quisiera no tener que escribir tantas clases y pruebas para cada una de estas clases. En fin todo es cosa de saber que no todo requiere unit test y encontrar el balance entre lo que lo requiere y lo que no.

Firebird 2.1 List Function

The List function in Firebird 2.1.

This is an aggregate function that returns a string with the field values concatenated using a delimiter. the default delimiter is the comma. So it's similar to the SUM function, but instead of adding numbers, this function concatenate strings. if some of the values is null then the function returns null.

So suppose I have 2 tables, projects and resources, and I know that a project will have a few resources assigned. Now I need to write a report of projects showing their resources assigned.

CREATE TABLE projects(
project_id INTEGER,
name string
);

CREATE TABLE resources(
project_id integer,
user_name string
);



Without the LIST function I have to write this query

SELECT
p.project_id as id,
p.name,
r.user_name
FROM
projects p INNER JOIN
resources r ON p.project_id = r.project_id

my result will be like this

id name user_name
-------------------------
1 Project_1 Steve
1 Project_1 John
2 Project_2 Jim
2 Project_2 Ed

Then in the report I will need to group the records with the same project_id so I don't show duplicate projects for each resource assigned.

Now with Firebird 2.1 I can write the query using the LIST function

SELECT
p.project_id AS id,
p.name,
LIST(r.user_name, ', ') AS resources
FROM
projects p INNER JOIN
resources r ON p.project_id = r.project_id
GROUP BY
p.project_id,
p.name


my result will be like this

id name resources
-----------------------------
1 Project_1 Steve, John
2 Project_2 Jim, Ed


then in my report I only need to show the results of my query, I don't need to create groups.

The list function returns a BLOB data type, so if I need to display the result in a grid I often CAST the result to varchar. The delimiter parameter is not required (I added because I like to add a space after the comma). You can see more details of how to use the LIST function in the Firebird 2.1 Release Notes

This function is also useful in reports when you need details values in the same row as the master data like in reports headers or footers.