Saltar al contenido

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript... y lo que venga ;)

17 años online

el blog de José M. Aguilar

Inicio El autor Contactar

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web
ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript...

¡Microsoft MVP!
lunes, 3 de diciembre de 2007
Hace unos días publicaba una entrada donde hablaba de los problemas que generan la inclusión y el mantenimiento de comentarios en el código fuente de nuestras aplicaciones, aunque para no extenderme mucho sólo cité brevemente algunos aspectos a tener en cuenta a la hora de afrontar estos inconvenientes.

Ahora, partiendo de estos consejos, la abundante literatura que hay sobre el tema y mi propia experiencia, he creado los 13 consejos para comentar tu código, que contribuirán a hacerlo más inteligible y por tanto a incrementar su mantenibilidad a lo largo del tiempo.

1. Comenta a varios niveles

Comenta los distintos bloques de los que se compone tu código, aplicando un criterio uniforme y distinto para cada nivel. Puedes, por ejemplo, seguir un modelo como:
  • En cada clase, incluir una breve descripción, su autor y fecha de última modificación
  • Por cada método, una descripción de su objeto y funcionalidades, así como de los parámetros y resultados obtenidos
En realidad, lo importante es ceñirse a unas normas (comúnmente aceptadas si se trata de trabajo en equipo) y aplicarlas siempre. Las reglas concretas pueden ser elegidas a la conveniencia de cada cual.

Obviamente, una solución bastante aceptable e incluso aconsejable es utilizar las convenciones y herramientas (como XML en C# ó Javadoc para el mundo Java) que ayudan y facilitan esta tarea.

2. Usa párrafos comentados

Como complemento al punto anterior, es recomendable dividir un bloque de código extenso en "párrafos" que realicen una tarea simple, e introducir un comentario al principio de forma que se guíe al lector, precediéndolos, además, de una línea en blanco que ayude a separar cada uno del anterior.
  ...


// Comprobamos si todos los datos
// son correctos
foreach (Record record in records)
{
if (rec.checkStatus()==Status.OK)
{
...
}
}


// Ahora pasamos a realizar las
// transacciones
Context ctx = new ApplicationContext();
ctx.BeginTransaction();
...

3. Tabula por igual los comentarios de líneas consecutivas

Si tenemos un bloque de líneas de código donde existe por cada una de ellas un comentario, es buena costumbre tabularlos todos a la misma posición, de forma que quedarán alineados y serán más sencillos de leer, sobre todo si forman parte de la misma frase.
  const MAX_ITEMS = 10; // Número máximo de paquetes
const MASK = 0x1F; // Máscara de bits TCP
 
Ojo a las tabulaciones. Hay editores que usan el carácter ASCII (9) y otros, en cambio, lo sustituyen por un número determinado de espacios, que suelen variar según las preferencias personales del desarrollador. Lo mejor es usar espacios simples o asegurarse de que esto es lo que hace el IDE correspondiente.

4. No insultes la inteligencia del lector

Debemos evitar comentarios absurdos como:
   if (a == 5)     // Si a vale cinco, ...
counter = 0; // ... ponemos el contador a cero
...
 
Este exceso necesita mucho tiempo a la hora de su creación, lo necesitará para su mantenimiento y, además, la mayoría de las veces distraerá al lector con detalles que no es necesario conocer o que pueden ser deducidos echando un vistazo al código.

5. Sé correcto

Evita comentarios del tipo "ahora compruebo que el estúpido usuario no haya introducido un número negativo", o "este parche corrije el efecto colateral producido por la patética implementación del inepto desarrollador inicial".

El uso de este tipo de comentarios no dice nada a favor de su creador, y, además, nunca se sabe quién los va a leer en el futuro. Emarts, en "Sapos, culebras y código fuente" muestra ejemplos de comentarios de este tipo.

Otro tema relacionado y, a mi entender, igualmente importante: cuida la ortografía. El hecho de que los comentarios no se vean desde el exterior no implican que puedas descuidarlos. Una ortografía correcta mejora la calidad de la expresión escrita y, por tanto, de la comunicación, que es de lo que se trata.

6. No pierdas el tiempo

No comentes si no es necesario, no escribas nada más que lo que necesites para transmitir la idea. Nada de diseños realizados a base de caracteres ASCII, ni florituras, ni chistes, ni poesías, ni chascarrillos.

En resumen, mantén los comentarios simples y directos, pues de lo contrario harás perder tiempo a tu sucesor. Para entender el efecto negativo de una verborrea excesiva, no hay como echar un vistazo a Hyperverbosity, publicado en Worse Than Failure hace unos días.

7. Utiliza un estilo consistente

Hay quien opina que los comentarios deberían ser escritos para que los entendieran no programadores. Otros, en cambio, piensan que debe servir de ayuda para desarrolladores exclusivamente.

En cualquier caso, coincidiendo con Ryan Campbell en su post Successful Strategies for Commenting Code, lo que importa es que siempre sea de la misma forma, orientados al mismo destinatario. Personalmente, dudo mucho que alguien de un perfil alejado a la programación vaya a acercarse al código, por lo que, para mi gusto, bastaría con cubrir el segundo caso de los expuestos anteriormente.

8. Para los comentarios internos usa marcas especiales


Y sobre todo, aunque no únicamente, cuando se trabaja en un equipo de programación en el que varias personas pueden estar tocando las mismas porciones de código. El ejemplo típico es el comentario TODO (to-do, por hacer), que describe funciones pendientes de implementar:
  int calcula(int x, int y)
{
// TODO: implementar los cálculos
return 0;
}
 
En este caso los comentarios no se usan para explicar una porción de código, sino para realizar anotaciones sobre el mismo a las que hay que prestar especial atención. Eso sí, si usas esta técnica, recuerda que debes actualizarlos conforme las anotaciones dejen de tener sentido.

9. Comenta mientras programas

Ve introduciendo los comentarios conforme vas codificando. No lo dejes para el final, puesto que entonces te costará más de el doble de tiempo, si es que llegas a hacerlo. Olvida las posturas "no tengo tiempo de comentar, voy muy apurado", "el proyecto va muy retrasado"... son simplemente excusas. Si tu intención es comentar el código, no te engañes y ¡hazlo!

Hay incluso quien opina que los comentarios que describen un bloque deberían escribirse antes de codificarlo, de forma que, en primer lugar, sirvan como referencia para saber qué es lo que hay que hacer y, segundo, que una vez codificado éstos queden como comentarios para la posteridad. Un ejemplo:

public void ProcesaPedido()
{
// Comprobar que hay material
// Comprobar que el cliente es válido
// Enviar la orden a almacén
// Generar factura
}

La codificación de cada una de las tareas descritas en el lenguaje correspondiente se realizaría justo debajo del comentario, quedando éste como encabezado de párrafo (como se describe en el consejo 2).

10. Comenta como si fuera para tí mismo. De hecho, lo es.

A la hora de comentar no pienses sólo en mantenimiento posterior, ni creas que es un regalo que dejas para la posteridad del que sólo obtendrá beneficios el desarrollador que en el futuro sea designado para corregir o mantener tu código.

En palabras del genial Phil Haack,
"tan pronto como una línea de código sale de la pantalla y volvemos a ella, estamos en modo mantenimiento de la misma"

Como consecuencia, nosotros mismos seremos los primeros beneficiaros (o víctimas) de nuestro buen (o mal) hacer.

11. Actualiza los comentarios a la vez que el código

De nada sirve comentar correctamente una porción de código si en cuanto éste es modificado no se actualizan también los comentarios. Ambos deben evolucionar paralelamente, pues de lo contrario estaremos haciendo más difícil la vida del desarrollador que tenga que mantener el software, al facilitarle pistas incorrectas para comprenderlo.

Atención especial a las refactorizaciones automáticas, que suelen introducir cambios en distintos puntos del código de un proyecto, dejando los comentarios obsoletos en ese mismo instante.

12. La regla de oro del código legible

He dejado para el final uno de los principios básicos para muchos desarrolladores: deja que tu código hable por sí mismo. Aunque se sospecha que este movimiento está liderado por programadores a los que no les gusta comentar su código ;-), es totalmente cierto que una codificación limpia puede hacer innecesaria la introducción de textos explicativos adicionales.

Recordemos, por ejemplo, el código introducido en el post "Interfaces fluidos (fluent interfaces)", donde se muestra lo que esta técnica puede aportar a la claridad y autoexplicación en un desarrollo:

Console.WriteLine("Resultado: " +
new Calculator()
.Set(0)
.Add(10)
.Multiply(2)
.Substract(4)
.Get()
);
 
A la vista del ejemplo, ¿es necesario añadir algún comentario para que se entienda qué hace el código? El uso de nombres apropiados (aconsejo leer el clásico Ottinger's Rules), indentación correcta y la adopción de guías de estilo (podéis ver algunas en la wikipedia, o googleando un poco) facilitan enormemente la escritura homogénea e inteligibilidad directa del código.

El no cumplimiento de esta regla hace que a veces los comentarios puedan parecer una forma de pedir perdón al desarrollador que se encargará del mantenimiento del software.

13. Difunde estas prácticas entre tus colegas

Obviamente, aunque ya hemos comentado en el punto 10 que nosostros mismos nos beneficiamos inmediatamente de las bondades de nuestro código comentado, la generalización y racionalización de los comentarios y la creación código inteligible nos favorecerá a todos, y sobre todo en contextos de trabajo en equipo. No dudes, por tanto, en crear cultura de comentarios en tu entorno.

Publicado en: Variable Not Found.
domingo, 2 de diciembre de 2007
Antiguo diseño de variable not found... ¡hasta nunca!Tras muchas horas de encarnizada batalla contra el sistema de plantillas de blogger, que tiene sus narices, Variable not found estrena imagen. Para mi gusto, un diseño mucho más moderno, limpio, y, sobre todo, alejado de la estética de plantilla estándar que estaba utilizando hasta el momento.

Acepto críticas (constructivas, eso sí ;-)), sugerencias y opiniones.

PD: ¡Gracias, Javi!

Publicado en: Variable Not Found.
miércoles, 28 de noviembre de 2007
De vez en cuando reviso las palabras por las que se llega a Variable Not Found a través de los buscadores, más que nada porque suelen reflejar dudas o problemas comunes de los desarrolladores y pueden servir como inspiración sobre nuevos temas a tratar en el blog.

Pues bien, llevo tiempo observando que hay muchas personas que preguntan a Google algo similar a "anular postback en botón", es decir, se tienen dudas sobre cómo evitar el disparo del postback al pulsar un botón de un formulario ASP.Net. El tema me ha parecido tan interesante que intentaré dar una respuesta a la duda estudiando algunas de las distintas posibilidades que pueden darse. Eso sí, si echáis en falta algún caso, no dudéis en comentarlo y lo trataremos lo antes posible.


I. ¿Hablamos de botones con lógica exclusivamente en cliente?

La primera cuestión es preguntarse para qué queremos un botón que no realice un postback al ser pulsado. Pensad que si todas las acciones desencadenadas por la pulsación del botón se realizarán en cliente es posible que no necesitemos un control ASP.Net. Imaginemos, por ejemplo, un botón que queremos que haga un cálculo en el cliente y muestre un cuadro de alerta con el resultado... ¿es necesario que sea un control de servidor (runat="server")? Seguro que no.

Para este caso lo más apropiado es incluir en el .aspx un HTML INPUT de los de toda la vida:

<input id="Button1" type="button" value="button"
onclick="hacerAlgo();" />
 
Si eres de los que prefieren arrastrar y soltar, puedes hacer exactamente lo mismo utilizando los controles incluidos en la pestaña HTML de Visual Studio, en este caso el llamado Input(Button). El resultado visual será idéntico al de un Button (un botón de servidor) y estaremos aligerando tanto la página enviada al cliente como la carga del servidor.

II. Anular el postback en un botón de servidor

Otra posibilidad es que vayas a usar un control de servidor (un Button, por ejemplo) y sólo bajo determinadas circunstancias quieras anular el postback desde el cliente. Obviamente, estas circunstancias serían calculadas/obtenidas por script, por lo que podríamos aplicar un patrón como el siguiente:

...
<asp:Button ID="Button1" runat="server"
Text="Pulsa"
OnClientClick="return comprueba();" />
...
<script type="text/javascript">
function comprueba() {
return confirm("Confirme el postback");
}
</script>
 
Como se puede observar, se ha modificado la propiedad OnClientClick del botón para hacer que retorne el resultado de la llamada a la función comprueba(). Si ésta retorna cierto, se realizará el postback, mientras que si retorna falso, no lo hará. En el ejemplo anterior se permite al usuario decidir si desea enviar el formulario al servidor o no.

III. Anular la posibilidad de envíos múltiples

Hay otras ocasiones, sin embargo, en las que estamos utilizando un botón de servidor de forma normal y simplemente queremos evitar duplicidades en el envío del formulario, es decir, bloquear el botón correspondiente una vez el usuario lo haya pulsado la primera vez.

Esto es muy habitual debido a la falta de feedback: el usuario envía el formulario, se impacienta esperando la respuesta o no está seguro de haberlo enviado, y cual poseso, inicia un ataque implacable sobre el botón de envío. ¿A que os suena?

El comportamiento típico, adoptado por la mayoría de sitios web, es deshabilitar el botón y seguir con el postback. Sin embargo, esto que podría ser realmente sencillo mediante scripting, causa algún que otro problema cuando el botón es de tipo Submit, puesto que en determinados navegadores (por ejemplo IE6) no realizará el envío si lo está generando un botón deshabilitado. Una forma de evitar este problema es hacer que el botón no sea de tipo submit e incluir un pequeño script:

<asp:Button ID="Button2" runat="server"
Text="Pulsa"
OnClientClick="this.disabled=true"
UseSubmitBehavior="False"/>

Si el botón debe ser obligatoriamente de tipo submit, se deben utilizar soluciones alternativas. Googleando un poco he encontrado varias, como deshabilitar el botón pasadas unas décimas de segundo mediante un timer, o retocar los estilos del botón para, simplemente, hacerlo desaparecer y mostrar en su lugar un mensaje informativo. La mejor, para mi gusto, consiste en capturar el evento onsubmit del formulario web, así:

...
<form id="form1" runat="server" onsubmit="deshabilita()">
...
<script type="text/javascript">
function deshabilita()
{
var btn = "<%= Button1.ClientID %>";
if (confirm("Confirme postback"))
{
document.getElementById(btn).disabled = true;
return true;
}
return false;
}
</script>
 
Este último ejemplo lo he aprovechado para, además, mostrar cómo es posible realizar la captura del envío justo antes de que se produzca, en el evento OnSubmit, e introducir las confirmaciones de envío y deshabilitado de botones.

Publicado en Variable not found.
martes, 27 de noviembre de 2007
Aunque he visto que es conocido desde hace tiempo, yo me he enterado ahora de que en http://www.connectionstrings.com/ hay una excelente recopilación de cadenas de conexión a fuentes de datos de todo tipo:
  • Motores de bases de datos SQL Server, SQL Server 2005, SQL Server 2005 Compact Edition, Oracle, MySQL, Interbase, IBM DB2, Sybase, Informix, Ingres, Mimer SQL, Lightbase, Postgre SQL, Paradox, Firebird, AS/400 (iSeries), Pervasive, SQLBase, Progress y Caché.

  • Archivos de datos Excel 2007, Excel, texto plano, Access 2007, Access, Visual FoxPro / FoxPro 2.x DBF / FoxPro, SQLite y Filemaker.

  • Otras fuentes, como MS Project, Active Directory, Exchange, Lotus Notes, DSN y UDL.

Seguro que algún despistado (como el menda, todo sea dicho), todavía no lo conocía. Y es que no hay nada como internet para tener a mano toda la información que necesitamos.

Publicado en: Variable not found
lunes, 26 de noviembre de 2007
Hasta hoy no sabía que la arroba, además de permitir la definición de constantes string literales y multilíneas (mi gran descubrimiento del mes pasado), también puede ser utilizado en C# para utilizar nombres reservados del lenguaje como identificadores.

Según la especificación del lenguaje C#, un identificador (de una variable, clase, propiedad...) puede ser una de las palabras clave del lenguaje (for, if, int, string...) si va precedida por una arroba, permitiendo aberraciones como la siguiente:

class @class
{
public static void @static(bool @bool)
{
if (@bool)
System.Console.WriteLine("true");
else
System.Console.WriteLine("false");
}
}
 
En fin, dudo mucho que vaya a utilizar esta posibilidad alguna vez, pero está bien saber que existe.

Publicado en: Variable Not Found.
domingo, 25 de noviembre de 2007
Si existieran los diez mandamientos del programador, seguro que uno de ellos sería "comenta tu código". Y es que está claro que la mantenibilidad de una aplicación o módulo es posible siempre que los profesionales encargados de ella sean capaces de entender perfectamente qué hace el software y cómo lo hace, y es aquí donde un código correctamente documentado puede facilitar enormemente la tarea.

Todos los lenguajes de programación facilitan la inclusión de texto libre, no estructurado, con objeto de que el programador explique a futuros mantenedores del software los principales aspectos del código fuente que está observando, el por qué de determinadas decisiones, o, en definitiva, aclarar lo que considere oportuno. Sin embargo, esta libertad y falta de normalización acarrea una serie de inconvenientes que deben ser tenidos en cuenta, y que comentó Chad Myer hace unas semanas.

En primer lugar, es importante ser conscientes de que estos textos están fuertemente ligados al código que comentan y, obviamente, al no ser comprobados por ningún sistema automático (como un compilador), es fácil que contengan errores:

// Retorna la suma de a y b
public int multiplica(int a, int b)
{
...
 
Tampoco puede asegurarse que los comentarios sean útiles; de hecho, parte de los comentarios que leemos son obviables y totalmente innecesarios, auténticos insultos a la inteligencia, del tipo:

if (a > 5) // Si a es mayor que cinco, ...
counter = 0; // ... ponemos el contador a cero
...
 
La inclusión de este tipo de comentarios no harían sino añadir "ruido" a un código perfectamente inteligible de forma directa.

Y hablando de comentarios prescindibles, es curioso ver su utilización como vía de escape y desfogue de algunos programadores, que no dudan en añadir todo tipo de artillería a sus creaciones, como las mostradas en el Contador de palabrotas del Kernel de Linux, arremetiendo contra los usuarios, colegas o todo aquél que pase por delante en el momento apropiado.

Otro hecho bastante frecuente es que los comentarios sean introducidos al crear un código pero que no sean actualizados de forma paralela a éste, lo que da lugar a textos obsoletos y sin sentido en su contexto. Y no hablo sólo de actualizaciones tiempo después de su creación, también las realizadas minutos u horas después de la programación inicial como consecuencia de optimizaciones y refactorizaciones, incluso realizadas por el mismo desarrollador.

// Si x es true, retorna a+b
// Si no, retorna a-b
public int calcula(int a, int b)
{
...
 
A pesar de todos estos problemas, normalmente generados por falta de rigor durante su creación y actualización, los comentarios son absolutamente necesarios para el futuro mantenimiento de un sistema y deben tratarse como parte fundamental en una pieza de código y prestarle la misma atención que a éste. Recordemos la famosa frase de Martin Fowler:
"Cualquier tonto puede escribir código que entienden las computadoras. Los buenos programadores escriben código que entienden las personas"


Para ello, como dice Bernhard Spuida en su magnífico documento The Fine Art of Commenting, hay que luchar contra actitudes negativas como:
  • el orgullo del programador ("no me hacen falta comentarios para entender lo que hace cualquier código", "yo escribo código que entiende cualquiera"). No te engañes, un código medianamente complejo te llevará tiempo entenderlo en cuanto hayan pasado unos meses incluso a tí mismo, así que imagina a otro desarrollador.
  • la pereza y procrastinación ("ya comentaré el código más adelante"). No te engañes, no lo harás; además, se estima que el tiempo necesario para añadir comentarios útiles a un código se duplica (como mínimo) si no se realiza en el momento de la codificación.
  • la excusa del deadline ("el proyecto va demasiado apurado como para ponerme a comentar el código"). No te engañes, los minutos de tardarás en comentar apenas afectarán a los plazos, y sí añadirán mantenibilidad al sistema.

Y es que, citando a Ryan Campbell en su post Successful Strategies for Commenting Code,
"comentar el código es como limpiar el cuarto de baño; nadie quiere hacerlo, pero el resultado es siempre una experiencia más agradable para uno mismo y sus invitados"


Publicado en: Variable Not Found.