miércoles, 15 de agosto de 2007

Meaningful

Según el significado encontrado en google esta palabra significa: having a meaning or purpose; "a meaningful explanation"; "a meaningful discussion"; "a meaningful pause"

En español podríamos traducir como: Que tiene un significado o propósito. Esto nos da una mejor idea del significado de esta palabra que dentro del desarrollo ágil el desarrollo guiado por pruebas de sus siglas en inglés TDD (Test Driven Development), acuña el termino Meaningful o Significativo para el nombramiento de los métodos (ver pagina 42 del libro Test-Driven Development in Microsoft .NET de James W. Newkirk y Alexei A. Vorontsov).

Veamos literalmente el comentario: "Meaningful method names are important for code readability and in turn its overall maintainnability. In short, method names should convey their intentions." Que parafraseado diriamos lo siguiente: los nombres de los metodos deben de comunicar un significado o su propósito para la legilibidad del codigo y mantenimiento. En resumen los nombres de los métodos deberían transmitir sus intenciones.

Y para ser justos haremos una referencia al libro de Refactoring de Martin Fowler que acuño el concepto de Refactorización del código y que luego surgió el concepto de desarrollo ágil. De hecho en el libro de TDD la referencia de la página hace mención de la refactorización como una disciplina importante a tomar en cuenta en el desarrollo guiado por pruebas o TDD.

En la página 273 del libro de Martin Fowler "Refactoring". Una técnica de la refactorización es el renombrar los métodos y explica: La Motivación es los métodos deberían nombrarse en un forma que comunica su intención. Recuerde su código es para humanos primero y luego para la computadora. Termina diciendo los buenos nombres, es una habilidad que requiere práctica: mejorar esta habilidad es la llave para empezar ha ser un verdadero programador hábil.

Y para finalizar esta introducción al termino Meaningful vamos acuñar el concepto de la disciplina llamada "Refactoring", no es mas que: El proceso de cambiar un sistema de software de tal manera que este no altera el comportamiento externo del código pero mejora su estructura interna (Pagina XVI del libro en mención).

Esta breve introducción da pie al siguiente ejemplo:

Escenario:

Es una aplicación Web y tenemos un control de usuario que hace la búsqueda de proveedores por tres filtros que serán controles de texto o Textbox identificados de la siguiente manera: NITProveedor, NombreProveedor y CodigoInternoProveedor. Deseamos darle el comportamiento de tal forma que si el usuario ingresa un valor en alguno de los controles de entrada los otros controles nos aseguremos que es eliminado cualquier valor de los demás controles para que al buscar por cualquiera de ellos y no por la combinación de varios de ellos nos traiga la información requerida por el usuario.

Para ir directo al grano y delimitar de alguna forma el alcance de este ejemplo no nos detendremos a redactar la parte de búsqueda de la información requerida por el usuario, sino únicamente el comportamiento que deseamos que tenga los controles para mostrar un ejemplo del concepto Meaningful que es la motivación de una de las técnicas de Refactoring de renombrar métodos. El ejemplo esta hecho en Visual Studio 2005 y en C# 2.0 para los que preguntan.

Veamos por una mera referencia o idea visual el código html de la página en la cual vamos a trabajar:

<%@ Page Language="C#" AutoEventWireup="true" Codebehind="TeachingTheConceptMeaningFul.aspx.cs"

Inherits ="TeachingTheConceptMeaningFul" %>

<! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" " http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

< html xmlns="http://www.w3.org/1999/xhtml">

< head runat="server">

<title>Busqueda de Proveedores</title >

</ head >

< body >

<form id="form1" runat ="server">

<div>

Proveedor:&nbsp;

<asp:TextBox ID ="NITProveedor" runat="server" OnTextChanged="NITProveedor_Cambio"

AutoPostBack="true" ToolTip="Ingrese el NIT del proveedor."/>

&nbsp;

<asp:TextBox ID ="NombreProveedor" runat="server" OnTextChanged="NombreProveedor_Cambio"

AutoPostBack="true" ToolTip="Ingrese el nombre del proveedor."/>

&nbsp;

<asp:TextBox ID ="CodigoInternoProveedor" runat="server" OnTextChanged="CodigoInternoProveedor_Cambio"

AutoPostBack ="true" ToolTip="Ingrese el codigo interno del proveedor."/>

</ div>

</form>

</ body>

</ html>

Veamos la parte remarcada donde esta el caso de nuestro ejemplo, Tenemos los tres controles y cada uno de ellos tiene un evento que se ejecuta cada vez que cambia el valor ingresado en cada uno de los controles de texto la propiedad AutoPostBack nos indica que hará un postbak al servidor cada vez que cambie el texto al perder el foco del control, esto sucede asi por el ambiente Web en que estamos trabajando y la orientación de las aplicaciones asp.net que fueron diseñadas para validar del lado del servidor preferiblemente y no del lado del cliente, aunque se puede. Y por ultimo el útil Tooltip que aparece un recuadro en amarillo que aparece al acercar el cursor sobre el control en el cual estamos navegando.

Ahora veamos el código del lado del servidor que es el que realmente nos interesa.

public partial class TeachingTheConceptMeaningFul : System.Web.UI.Page

{

protected void Page_Load(object sender, EventArgs e)

{

}

protected void NITProveedor_Cambio(object sender, EventArgs e)

{

this.NombreProveedor.Text = null;

this.CodigoInternoProveedor.Text = null;

}

protected void NombreProveedor_Cambio(object sender, EventArgs e)

{

this.NITProveedor.Text = null;

this.CodigoInternoProveedor.Text = null;

}

protected void CodigoInternoProveedor_Cambio(object sender, EventArgs e)

{

this.NITProveedor.Text = null;

this.NombreProveedor.Text = null;

}

}

Al apreciar este código parece que todo esta muy claro y que no es difícil que comprender, pero que pasa si tenemos que agregar otros filtros digamos unos 2 o 3 o tal vez 5 filtros mas deberemos repetir el código y tener el cuidado de no limpiar el contenido del control en el que el usuario. Pero ver asignar null al contenido de cada control de texto verdaderamente comunica el propósito de lo que estamos haciendo?. Bueno no me conteste ahora apliquemos la refactorización a nuestro código para hacerlo mas legible o por lo menos para centralizar las mismas operaciones.

Digamos que vamos a tener un solo método que se conecta a todos los controles y desde allí centralizamos el comportamiento de cada control.

Para ello comentamos el código html original para regresar al código anterior si todo nos sale mal (esto es una buena practica no eliminar el código hasta estar seguro que el cambio quedo bien. Y luego indicamos que el método al cual se pegará el disparar el evento del cambio del texto de cada control es el mismo y lo llamaremos "FiltroProveedor_Cambio". Veamos el código:

< div >

Proveedor:&nbsp;

<asp :TextBox ID="NITProveedor" runat="server" OnTextChanged ="FiltroProveedor_Cambio"

AutoPostBack="true" ToolTip="Ingrese el NIT del proveedor." />

&nbsp;

<asp :TextBox ID="NombreProveedor" runat="server" OnTextChanged ="FiltroProveedor_Cambio"

AutoPostBack="true" ToolTip="Ingrese el nombre del proveedor." />

&nbsp;

<asp:TextBox ID ="CodigoInternoProveedor" runat="server" OnTextChanged="FiltroProveedor_Cambio"

AutoPostBack ="true" ToolTip="Ingrese el codigo interno del proveedor." />

</ div>

Veamos ahora el código del lado del servidor:

protected void FiltroProveedor_Cambio(object sender, EventArgs e)

{

TextBox ControlTexto = (TextBox)sender;

switch (ControlTexto.ID)

{

case "NITProveedor":

this.NombreProveedor.Text = null;

this.CodigoInternoProveedor.Text = null;

break;

case "NombreProveedor":

this.NITProveedor.Text = null;

this.CodigoInternoProveedor.Text = null;

break;

case "CodigoInternoProveedor":

this.NITProveedor.Text = null;

this.NombreProveedor.Text = null;

break;

default :

break;

}

}

Que hicimos ahora, no mucho solo centralizamos el problema, no nos comunica mucho, es prácticamente el mismo código pero así es en la refactorización empezamos con pequeños cambios, para prepararnos para mejorar nuestro código. Es importante mencionar que aunque es valido utilizar el switch como una estructura de selección es muy rígida y que dentro de los patrones de diseño (Gof Design Patterns ) sugiere evitar su uso lo mas posible, con el objetivo que nuestro código sea mas adaptable y extensible con el menor cambio posible. Aplicando este concepto e implementando una solución posible y sencilla modificaremos nuestro código para hacerlo extensible y adaptable a los futuros cambios sin alterar nuestro código luego de estos cambios:

Primero vamos a convertir el div que agrupa los controles como un control de servidor y lo utilizaremos como un contenedor de controles para utilizar un loop para recorrer los controles dentro del div. Así como aparece a continuación:

<div id="ContenedorFiltrosProveedor" runat ="server">

Proveedor:&nbsp;

<asp:TextBox ID ="NITProveedor" runat="server" OnTextChanged="FiltroProveedor_Cambio"

AutoPostBack="true" ToolTip="Ingrese el NIT del proveedor." />

&nbsp;

<asp:TextBox ID ="NombreProveedor" runat="server" OnTextChanged="FiltroProveedor_Cambio"

AutoPostBack="true" ToolTip="Ingrese el nombre del proveedor." />

&nbsp;

<asp:TextBox ID="CodigoInternoProveedor" runat="server" OnTextChanged ="FiltroProveedor_Cambio"

AutoPostBack ="true" ToolTip="Ingrese el codigo interno del proveedor." />

</ div>

Ahora veamos el código del lado del servidor:

protected void FiltroProveedor_Cambio(object sender, EventArgs e)

{

TextBox ControlTexto = (TextBox)sender;

foreach (Control control in this.ContenedorFiltrosProveedor.Controls)

{

TextBox texto = control as TextBox;

if (texto != null)

{

if (texto.ID != ControlTexto.ID)

texto.Text = null;

}

}

}

Esto cambio completamente la rigidez de la estructura switch y nos permitirá agregar otros filtros tipo TextBox sin alterar el código. Veamos un ejemplo, digamos que vamos agregar un nuevo filtro tipo TextBox veamos lo que necesitamos hacer en el código html:

<div id="ContenedorFiltrosProveedor" runat ="server">

Proveedor:&nbsp;

<asp:TextBox ID ="NITProveedor" runat="server" OnTextChanged="FiltroProveedor_Cambio"

AutoPostBack="true" ToolTip="Ingrese el NIT del proveedor." />

&nbsp;

<asp:TextBox ID ="NombreProveedor" runat="server" OnTextChanged="FiltroProveedor_Cambio"

AutoPostBack="true" ToolTip="Ingrese el nombre del proveedor." />

&nbsp;

<asp:TextBox ID ="CodigoInternoProveedor" runat="server" OnTextChanged="FiltroProveedor_Cambio"

AutoPostBack ="true" ToolTip="Ingrese el codigo interno del proveedor." />

<asp:TextBox ID="RazonSocialProveedor" runat="server" OnTextChanged="FiltroProveedor_Cambio"

AutoPostBack="true" ToolTip="Ingrese el nombre de la razón social del proveedor." />

</ div>

Y del lado del servidor, absolutamente nada. Pero un minuto no hemos terminado ser recuerdo el objetivo del ejemplo es aprender a darle un nombre a los métodos que expliquen su propósito o significado, para ello vamos a utilizar la opción de Visual Studio 2005 Refactor (click derecho sobre el código seleccionado( y Seleccionaremos la opción ExtratMethod y ahora si colocaremos el nombre del método, como aparece a continuación:

protected void FiltroProveedor_Cambio(object sender, EventArgs e)

{

TextBox ControlTexto = (TextBox)sender;

LimpiarValorControlesTexto(ControlTexto);

}

private void LimpiarValorControlesTexto(TextBox ControlTexto)

{

foreach (Control control in this.ContenedorFiltrosProveedor.Controls)

{

TextBox texto = control as TextBox;

if (texto != null)

{

if (texto.ID != ControlTexto.ID)

texto.Text = null;

}

}

}

De alguna manera encapsulamos la funcionalidad y explicamos claramente lo que hace nuestro codigo sin decirlo como lo hace ya que esto no es el objetivo de la encapsulación y si del Concepto Meaningful Method Name.

Hasta la próxima. Write Code For Fun!,

Manolo

viernes, 27 de julio de 2007

Error Microsoft.Practices.EnterpriseLibrary.Data.Instrumentation.DataConnectionFailedEvent

Les escribió por este error porque es un dolor de cabeza y la solución en algunos escenarios es muy fácil , también utilizó mi blog como una memoria por si se me olvida vengo a consultar aquí.

Este error sucede cuando ha habido un error de conexión a la base de datos y las enterprise library de Microsoft intentan escribir en el log del sistema y la cuenta conque nos conectamos no tiene derechos de escritura . Como solucionarlo de una forma sencilla. Si no necesita utilizar el identity impersonate=true (sección del web.config de su aplicación) apáguelo es decir póngale el valor a “false”. De esa manera utilizará la cuenta del sistema para escribir en el log de Windows y el error se quitará.

Si es necesario utilizar la opción identity impersonate=true vea este siguiente link para darle acceso a las Microsoft Enterprise Library para que puedan escribir el log. http://softwaretalk.info/ptopic1861.html&sid=921065b6ade5a60947aad1aa4e1c42b0

Si tiene duda cuando utilizar esta opción del web.config vea este link: http://msdn2.microsoft.com/en-us/library/xh507fc5.aspx

Saludos, hasta la próxima!.

Manolo

martes, 19 de junio de 2007

FW: Proxima Reunion Miércoles 27 de Junio de 2007

Tema:  Lo ultimo del .NET Framework 3.0

Expositor:  Ing. Jose Antonio Chajón (Miembro del Buró de Expositores de la Comunidad .NET en Guatemala  & MVP) 

Fecha:  Miércoles  27  de  Junio de  2007 

Horario: 6:30 P.M. – 8:30 P.M.

Lugar:  Hotel Intercontinental  Salón Guayacán

Costo: Gratis

Otros: Habrá Coffee Break, Parqueo  y Premios

Invita: Comunidad de Desarrolladores .NET en Guatemala, con Apoyo de Microsoft de Guatemala

 

Atentamente,

 

Manolo Herrera

Coordinador de La Comunidad de Desarrolladores .NET en Guatemala (Blog: http://jmhogua.blogspot.com/)

 

 

viernes, 8 de junio de 2007

FW: [DotNETGTGroup] Proxima Reunion Miércoles 13 de Junio de 2007

Otra reunión más de la comunidad tendremos a nuestro amigo y compañero Cristian Prieto Software Arquitect y gran colaborador de la comunidad de desarrolladores en Guatemala.

Los dejo con la información.

Tema: Windows Office and Vista Preview Handlers y el Windows Vista RSS SDK

Expositor: Cristian Prieto (Miembro del Buró de Expositores de la Comunidad .NET en Guatemala & Software Architect)

Fecha: Miércoles 13 de Junio de 2007

Horario: 6:30 P.M. – 8:30 P.M.

Lugar: Hotel Intercontinental Salón Guayacán

Costo: Gratis

Otros: Habrá Coffee Break, Parqueo y Premios

Invita: Comunidad de Desarrolladores .NET en Guatemala, con Apoyo de Microsoft de Guatemala

Atentamente,

Manolo Herrera

Coordinador de La Comunidad de Desarrolladores .NET en Guatemala (Blog: http://jmhogua.blogspot.com/)



miércoles, 4 de abril de 2007

Unica Reunión del Mes de Abril de la la Comunidad MIERCOLES 18 DE Abril DE 2007 (Invitado Especial)

Tengo el agrado de presentar en esta reunión única del mes de abril a nuestro Invitado Especial Ing. Jose Antonio Chajón MVP de Microsoft que nos trare noticas de los ultimos avances sobre el .Net framework 3.0.  No se lo pierdan y aprovechen a nuestro invitado especial:
 
 
Expositor:   Ing. Jose Antonio Chajón (MVP)

Fecha:   Miércoles  18 de    Abril de  2007 

Horario: 6:30 P.M. – 8:30 P.M.

Lugar:   Hotel Intercontinental  Salón Guayacán

Costo: Gratis

Otros: Habrá Coffee Break, Parqueo  y Premios

Invita:  Comunidad de Desarrolladores .NET en Guatemala, con Apoyo de Microsoft de Guatemala

 Atentamente,

 

Manolo Herrera

Coordinador de La Comunidad de Desarrolladores .NET en Guatemala (Blog: http://jmhogua.blogspot.com/)
 

 

 



--
Saludos,

Manolo Herrera