Mejores Practicas

Links del dia #1

Ya que de perdido paso 2 horas al día leyendo artículos técnicos sobre desarrollo de software o cosas relacionadas a sistemas, y durante los últimos 5 años la mayoría de lo que he aprendido ha sido en base a blog posts, he decido empezar una serie de posts recomendado uno o más artículo/posts que haya leído durante ese día, categorizados por tecnología o área.

No se si logre hacer esto diariamente, pero al menos el intento se hará. Aquí estan los primeros artículos interesantes que he leído el día de hoy:

SQL

Introduction to JOINS – Basic of JOINS: Escrito por Pinal Dave, un experto de SQL. Mucha gente no sabe explicar los JOINS en SQL o la diferencia exacta entre ellos, buen artículo.

Personal Improvement

Basic Presentation Skills Training – Notes from Joel Abrahamsson: Parte de mi rol de trabajo es dar algunas presentaciones técnicas, y la verdad es que la mayoría de la gente no somos buenos para esto. Buenas notas y tips de este desarrollador que está tomando un curso al respecto.

.NET / C# / ASP.NET

ALT.Next – ALT.NET es un “movimiento” o “corriente” integrado por varios desarrolladores enfocados en traer las mejores prácticas y herramientas de otras comunidades de desarrollo (Java, Ruby, Python, etc) a la comunidad de Microsoft y .NET en general. Aunque su auge más fuerte ya pasó, este artículo da una idea de hacia donde van.

Desarrollo de Sistemas en General

Metodologies at a GlanceJ.D. Meier, un Principal Program Manager de Microsoft, en el equipo de Patterns & Practices, escribe posts muy útiles constantemente. Este post es un mapa de algunas actividades/artefactos clave en varios procesos de desarrollo de software.

That’s it. Read on.

Automapper y un buen articulo de diseño de software

Logo AutoMapper

La semana pasada descubrí AutoMapper, que es un proyecto de .NET gratis y open-source de Jimmy Bogard.

Un desarrollador de la oficina me preguntó si había una manera integrada en el framework de transformar las clases generadas por LINQ-To-SQL en clases sencillas (DTOs). No creí que lo hubiera…pero le comenté que seguramente lo podía hacer por Reflection. Yo ya habia hecho eso antes, pero supuse que debía haber alguna mejor manera. Después de buscar un poco en StackOverflow.com, alguna de las respuestas linkeaba a AutoMapper y descubrí que era exactamente lo que aquel desarrollador estaba buscando.

AutoMapper es descrito en su página principal de la siguiente manera:

AutoMapper uses a fluent configuration API to define an object-object mapping strategy. AutoMapper uses a convention-based matching algorithm to match up source to destination values. Currently, AutoMapper is geared towards model projection scenarios to flatten complex object models to DTOs and other simple objects, whose design is better suited for serialization, communication, messaging, or simply an anti-corruption layer between the domain and application layer.

Excelente…no solo utiliza interfaces fluidas, sino que también se basa en Convention Over Configuration. Es decir…solo tenemos que (y podemos!) configurar las situaciones excepcionales. Las ventajas que le veo a utilizar AutoMapper (a pesar de estar incorporando una referencia más a nuestros proyectos) es que es un proyecto público (de open source) y que además tiene a un muy buen desarrollador respaldándolo, que por ser su proyecto, se enfoca en mejorarlo y perfeccionarlo con nuevas funcionalidades, haciéndolo más eficiente, etc. Además, debido a que ya tiene una considerable base de usuarios (3,702 downloads), la mayoría de los bugs que pudiéramos toparnos, ya han sido resueltos.

Un ejemplo exagerádamente básico del uso de AutoMapper:


public class Class1
 {
   public string FullName { get; set; }
   public int Age { get; set; }
   public char Gender { get; set; }
   public void DoIt()
   {
     Console.WriteLine("Test");
   }

   public List<string> Addresses { get; set; }

   public Class1()
   {
     Addresses = new List<string>();
   }
 }

 public class Class2
 {
   public string FullName { get; set; }
   public int Age { get; set; }
   public char Gender { get; set; }
 }

private void Form1_Load(object sender, EventArgs e)
{
   Mapper.CreateMap<Class1, Class2>();

   var c2 = Mapper.Map<Class1, Class2>(c1);
   MessageBox.Show(c2.FullName);
}

Ok, de este ejemplo podemos ver:

  • Class1 es poco más compleja que Class2, ya que tiene una List<string> y un método definido (DoIt())
  • Class2 es una versión simple de Class1, con el objetivo de funcionar como un Data Transfer Object.

Como pueden ver, con la instrucción:

Mapper.CreateMap<Class1, Class2>();

estamos indicándole a AutoMapper que la Class1 y Class2 están relacionadas (mappeadas). Y la siguiente línea de código:

var c2 = Mapper.Map<Class1, Class2>(c1);</pre>

está creando una instancia de tipo Class2, basada en la instancia de c1 que ya teníamos, inicializada y asignando dinámicamente los valores de dicha instancia (c1) a la nueva instancia c2.

Class1, en este caso, sería un ejemplo de una clase de LINQ-To-SQL, mientras que Class2 sería la clase que queremos usar como DTO.

Esta funcionalidad es sólamente la más básica de AutoMapper (flattening). También soporta proyecciones (utilizar ciertas propiedades o sub-sets de un valor para mapear a otra propiedad), Listas y Arrays, etc. Para más información, visisten la documentación de AutoMapper.

Y sobre el buen artículo de diseño…para mi sorpresa lo encontré 2 dias después de haber descubierto AutoMapper, y el artículo lo escribió Jimmy Bogard.

El artículo se llama originalmente “Strengthening your domain: Encapsulated collections“. Jimmy habla de como debemos de diseñar nuestras clases para no exponer inadvertidamente funcionalidad de más (extra, innecesaria) que podría permitir operaciones no lógicas sobre nuestras entidades, y enfocarnos en soportar exclusiva y claramente sólo las operaciones que el dominio de negocio debe permitir sobre las entidades de nuestro proyecto. El artículo también me hizo pensar que los accesors son algo que mucha gente no considera a la hora de exponer sus propiedades. Léanlo y si gustan dejar sus comentarios…adelante.

Como medir tiempo de ejecucion de codigo en C# y .NET

Proximamente voy a hacer un comparativo de performance entre Entity Framework y Subsonic, así que se me ocurrió de una vez escribir este post sobre la manera correcta en que se debe medir el tiempo de ejecución de un cierto bloque de código utilizando C# y .NET.

La medición del tiempo se hace usando una instancia de la clase StopWatch, que se encuentra en el namespace de System.Diagnostics. La clase StopWatch provee un conjunto de métodos y propiedades que pueden ser usados para medir con alta precisión el tiempo transcurrido entre intervalos.

Los métodos disponibles sobre esta instancia serían:

  • Start() – inicia el contador a partir del último lapso. La cuenta es acumulativa, es decir, si se verifica la propiedad ElapsedMilliseconds después de 4 llamadas a los métodos de Start y Stop, el tiempo desplegado será el acumulado de los 4 intervalos.
  • Stop() – detiene momentaneamente el timer.
  • Reset() – reinicia los valores almacenados del timer

Las propiedades disponibles, que usaríamos para desplegar el tiempo que tomó alguna rutina, serían:

  • Elapsed – Regresa una instancia de tipo TimeSpan que determina el tiempo que ha transcurrido desde que se llamó al método Start() por primera vez.
  • ElapsedMilliseconds – Regresa un valor de tipo long que indica los milisegundos transcurridos desde la primera vez que se llamó al método Start().
  • ElapsedTicks – Regresa un valor de tipo long, que indica los Ticks que han pasado desde la primera vez que se llamó al método Start(). Nota importante respecto a esta propiedad: Los ticks de un StopWatch no son iguales a los ticks de un DateTime. En DateTime, cada tick representa un intervalo de 100 nanosegundos. En StopWatch, un tick representa un intervalo de tiempo equivalente a 1 segundo dividido entre la propiedad Frequency del StopWatch.
  • IsRunning – determina si el timer está activo y contando Ticks.

Las propiedades IsHighResolution y Frequency no son propias de una instancia StopWatch, sino de la clase StopWatch.

IsHighResolution indica si el timer utilizado está basado en un contador de performance de alta resolución. Esto depende del procesador/arquitectura de la computadora en la que está corriendo el código

Frequency representa el numero de StopWatch ticks por segundo.

Ahora, un poco de código de ejemplo:

Console.WriteLine(string.Format(“IsHighResolution: {0}”, Stopwatch.IsHighResolution ? “Yes” : “No”));
Console.WriteLine(string.Format(“Frequency: {0}”, Stopwatch.Frequency));
Console.WriteLine(“———————-“);

var dos = “2”;
var suma = 0;

//Medir int.Parse
var timer = Stopwatch.StartNew();

for (var i = 1; i <= 1000; i++) { suma += int.Parse(dos) * i; } timer.Stop(); Console.WriteLine(string.Format("Suma: {0}", suma)); Console.WriteLine(string.Format("Elapsed para int.Parse: {0}", timer.Elapsed)); Console.WriteLine(string.Format("ElapsedMilliseconds para int.Parse: {0}", timer.ElapsedMilliseconds)); Console.WriteLine(string.Format("ElapsedTicks para int.Parse: {0}", timer.ElapsedTicks)); Console.WriteLine("----------------------"); suma = 0; //Medir Convert.ToInt32() timer = Stopwatch.StartNew(); for (var i = 1; i <= 1000; i++) { suma += Convert.ToInt32(dos) * i; } timer.Stop(); Console.WriteLine(string.Format("Suma: {0}", suma)); Console.WriteLine(string.Format("Elapsed para Convert.ToInt32: {0}", timer.Elapsed)); Console.WriteLine(string.Format("ElapsedMilliseconds para Convert.ToInt32: {0}", timer.ElapsedMilliseconds)); Console.WriteLine(string.Format("ElapsedTicks para Convert.ToInt32: {0}", timer.ElapsedTicks)); [/code] da el siguiente resultado:

Midiendo intervalos de tiempo con la clase StopWatch

Midiendo intervalos de tiempo con la clase StopWatch

Como se puede apreciar, int.Parse es ligeramente más rapido que Convert.ToInt32().

De manera simplemente informativa…hay otra manera de medir intervalos de tiempo que mucha gente usa, y NO es correcto ni recomendable. Lo hacen asignando el valor de DateTime.Now a una variable de tipo DateTime y luego lo resta al valor de DateTime.Now en el momento que quieren dejar de medir.

Hay todavía otra manera similar al uso de DateTimes, que es usando la propiedad Environment.TickCount.Esto es incorrecto por tres razones:

1. Si existe una clase especializada para hacer esto en el framework, digase StopWatch, hay que usarla.
2. Environment.TickCount es signed (puede representar valores negativos también) lo cual implica que después de 25 dias, se va a entrar al rango negativo y se tendría que eliminar el bit del símbolo para poder hacer calculos correctos. Después de 50 dias, se llenarían todos los bits de la variable y la cuenta se reiniciaría. Ver discusión en StackOverflow.com donde se menciona esto.
3. En palabras del mismo Scott Hanselman, y mencionado en el mismo link de la razon #2: As an unrelated aside, if you DO use DateTime for Date-related math calculations, always use DateTime.UtcNow as DateTime.Now is susceptible to Daylight Savings Time…your calculations could be off by a hour, or worse, negative numbers.

Es decir, es muy facil que a la gente se le olvide que si va a cronometrar de esta manera, usar DateTimes para medir intervalos puede ser susceptible a los conocidos “horarios de verano”, que desfazan por temporadas el reloj por +- 1 hora. Cualquiera de las dos alternativas a StopWatch (DateTime o Environment.Ticks) es relativamente riesgosa para ser útil.

Links de Referencia:

Clase StopWatch @ MSDN

 Scroll to top