[Humor] I would do anything for you

Tras unos sufridos días, no quería dejar pasar la oportunidad de dedicar una sonrisa a la causa del problema. Así que sin más, dedico este post a todos esos métodos que detrás una linda interfaz, esconden algo muy gordo.

this.magic.IwouldDoAnythingForYou()

 

2dce27b190ed4657c7a4b930b918438d

3e1

Saludos

Publicado en Clean Code, Humor, Refactoring | Deja un comentario

¿Una Interfaz solo con propiedades? – Refactoring

e40f2722-bccf-45d5-8bbc-4ba2dff9c54cEl otro día pude compartir una hora hablando de clean code y algunas best practices con el grande de @elBruno. La verdad es que pasé un rato bastante agradable y ya espero la próxima 😉

Unos días después de esa charla me encuentro con una de esas situaciones en que preguntando y preguntando, la mayoría de las veces basta con preguntarse uno mismo, te llevan a una refactorización que hace más limpio tú código y deja alguna que otra conclusión chula.

Resulta que en un proyecto X tengo una interfaz IX que tiene 2 propiedades y ya está, dos propiedades con un get y esa es toda mi interfaz. Una interfaz, y seguro esto ya lo saben todos, define un contrato que hay que cumplir e implementar, por lo tanto, mi interfaz IX obligaba a cada clase que la implementa, a tener esas dos propiedades.

Con la primera clase todo bien, siempre hay alguna herramienta en Visual Studio que ayuda a generar las implementaciones. Cuando escribí la segunda clase, me acordé que el mismo código lo tenía en la clase anterior. Cuando iba a escribir la tercera clase, tuve una visión de futuro ¿Llegaré a escribir la décima clase que implementa esta interfaz?

Cuando llegamos a este punto, y antes de continuar soportando ver el mismo código una y otra vez, lo mejor es parar y buscar la base del problema.

Conversando con yo mismo

  • ¿Por qué en cada clase se repite exactamente el mismo código?
  • Porque la interfaz que implementa te obliga
  • ¿Qué hago si no quisiera repetir lo mismo en cada clase?
  • No deberías usar una interfaz. ¿Quizás una clase abstracta?
  • Pero por algo usé una interfaz
  • Para obligar a cada clase a cumplir un contrato e implementar un comportamiento
  • Mmm Estoy cumpliendo un contrato ¿y el comportamiento?
  • Clic! Aquí algo no me cierra. Estoy usando una interfaz para hacer algo que no hago.

Refactoring

  • Mi interfaz ha dejado de ser una interfaz para convertirse en una clase abstracta.
  • Las dos propiedades se implementan dentro de la clase abstracta con un get público y un set protected.
  • Cada clase que hereda, hace uso de esas propiedades.
  • Al estar en una clase padre y ser public/protected, cada clase hija tiene acceso a las propiedades sin necesidad de declararlas.

Hasta aquí “el problema” ya estaba resuelto, pero me quedaba una pregunta que me hice una vez que terminé el refactoring y fue el motivo por el cual me decidí a escribir el post.

  • ¿Tenía sentido tener una interfaz solo con propiedades?

Aún sigo buscando algún ejemplo que aplique, de momento la respuesta es NO. ¿Por qué no? Porque una interfaz tiene sentido cuando queremos obligar a que se haga algo sin saber cómo se hará. El qué y el cómo en este caso definen el comportamiento de un objeto.

En POO, las propiedades definen el estado de un objeto y no su comportamiento. Sabemos que un objeto se comporta según su estado, y aquí recordarán el clásico ejemplo de, “si un avión está en pista (estado), no podemos hacer que aterrice (comportamiento)“.  Por lo tanto, LQQD, si definimos solo propiedades dentro de una clase, no tendríamos comportamiento, y si no hay comportamiento, no necesitamos interfaz.

🙂

Publicado en Clean Code, POO, Refactoring | 4 comentarios

Documentar sí, pero ágil

Bonanjo_-_Centre_de_documentation_et_information_urbanisme_(CUD)_05

Uno de los temas más polémicos cuando hablamos de metodologías ágiles es la documentación. Documentar ¿Sí o No? A esta pregunta se suma uno de los puntos del manifiesto ágil que nos dice: “software que funcione, por encima de documentación exhaustiva”

Hay dos problemas fundamentales que ha arrastrado siempre la documentación relacionada con el desarrollo de Software.

  1. Documentación extensa: Entramos a un proyecto y nos encontramos con 400 páginas de documentación que son casi imposible de leer y entender. Aún así, vamos a suponer que tenemos un alto grado de abstracción y logramos entender cómo debería funcionar ese Software basado en esa documentación, al abrir el proyecto nos encontramos con el segundo problema.
  2. Documentación desactualizada: Somos desarrolladores, la fase superior del vago. Si dentro del propio código nos cuesta un enorme trabajo actualizar un comentario referente a una lógica que acabamos de modificar, imagina si esa documentación está en un documento Office almacenado en la nube en la carpeta… ¿cuál era? y con nombre… ¿cuál era?

Estos problemas son los que se intentan evitar cuando en el manifiesto ágil dan mayor importancia a que el Software funcione. Toda documentación que no se lee o queda desactualizada, es tiempo y esfuerzo perdido. Ahora bien, esto NO significa que la documentación desaparece. En la explicación del propio manifiesto ágil se indica que, cito: “aunque valoramos los elementos de la derecha, valoramos más los de la izquierda

La solución pasa por documentar puntos estratégicos de nuestro proyecto sin caer en los problemas mencionados anteriormente. Primero, documentación clara y concisa, nada de escribir un Quijote, y segundo, esta documentación debería persistir lo más posible en el tiempo y mantener su validez, sin necesidad de ser actualizada.

¿Qué y cómo deberíamos documentar?

Arquitectura
La arquitectura en un proyecto “debería” cambiar poco. Si seguimos diseños como Three-Tier o N-Tier, DDD, CQRS, Microservices, etc. Tendríamos un 80% de la documentación de este punto ya hecha y, solo nos quedaría documentar aquellos aspectos que hemos hecho de manera diferente.

Clases y métodos
Cero comentarios dentro de métodos o propiedades. Con comentar la cabecera de la clase y la cabecera de cada uno de los métodos incluyendo sus parámetros, debería ser suficiente.

Para la documentación de clases y métodos, usar un resumen corto y claro que nos diga qué se hace y no cómo se hace. De esta manera logramos que, si se cambia la lógica del método o se adicionan nuevos métodos a una clase, no tengamos que actualizar la documentación.

Actualización: Después de un corto pero buen debate con Juanma y Joaquín sobre este punto, creo necesario aclarar que la documentación en clases y métodos, puede incluso no ser necesaria. Para esto, es necesario lograr una buena elección de nombres capaces de indicarnos qué hace la clase o el método.

Dejo un artículo del propio Juanma sobre este tema: “Por favor, comenta el código“. Aunque el concepto del “por qué” lo veo interesante,  intentaría llevar el comentario a nivel de método y no incluirlo en el código.

¿Y la lógica?
Para la lógica no hay mejor documentación que el propio código. Si revisas un código escrito un mes atrás, y no eres capaz de saber lo que hiciste, malo.  Una buena programación orientada a objetos (que no es lo mismo que programar en un lenguaje orientado a objetos) puede salvarnos de estos problemas.

En los primeros pasos de un proyecto, herramientas de análisis de código nos pueden ser de mucha ayuda, con ellas podemos detectar qué se está haciendo mal y orientar las formaciones o debates hacia estos problemas.

Salu2 c.u

Publicado en Ágil, Clean Code | Deja un comentario

POO ¿Goodbye?

Diapositiva3

Llevaba mucho tiempo sin escribir aquí. Veré si poco a poco el tiempo me permite ser más constante. Vamos al asunto.

Una de las cosas que me hizo crecer como programador, fue aprender a programar orientado a objetos (POO). Aún recuerdo aquellos días de inicio de carrera cuando con mucho orgullo llevé a mi tutor una calculadora que permitía usar números imaginarios, que incluía más funciones que la propia calculadora de Windows y, además, ¡los resultados eran dos decimales más exactos!

Aquella calculadora se la entregué impresa (me niego a contar los motivos) en unos 80/90 folios de código*. Mi tutor miró solo las primeras hojas y me dijo, déjamelo unos días y luego hablamos. Como Jesucristo, “al tercer día resucitó”. Me entregó unos 15 folios y me dijo, aquí tienes tu calculadora. Lo hizo haciendo uso de algo llamado POO. Yo guardo el código de todo aquello que he hecho en mi vida como programador, todo menos esa calculadora.

(*) Para mejorar la idea de aquellas 80 hojas, aclaro que toda mi vida he odiado comentar código.

¿A qué viene la historia? Pues a este post que encontré en Facebook “Goodbye, Object Oriented Programming”.  Gracias Luis por compartirlo 😉

Me voy a centrar solo en tres aspectos del post, porque el resto no me merece la pena.

La primera es la frase “I couldn’t contain my excitement at the thought of mapping my real-world objects into their Classes and expected the whole world to fall neatly into place.”

Lo más interesante de esta frase, aparte de la excitación que seguro era provocada por algo ajeno a la POO, es el objetivo de mapear sus objetos al mundo real.

“Si es bueno vivir, todavía es mejor soñar, y lo mejor de todo, despertar.” Cuidado con los sueños, que el despertar, pueden provocar que se escriban post como el mencionado. La base de la programación orientada a objetos es mapear el comportamiento de nuestros objetos al mundo real y, los sueños, sueños son. Yo puedo soñar una cocina que seleccione el menú del día, los junte, los haga y, hasta me la traiga a la mesa del ordenador 🙂

La segunda es “The problem with object-oriented languages is they’ve got all this implicit environment that they carry around with them. You wanted a banana but what you got was a gorilla holding the banana and the entire jungle.”

Esto es una cita de Joe Amstrong y que entiendo, según su propio perfil de twitter (Writes programs and books. Invents things. Gives talks. Fixes broken software. Hobbies: Stroking cats, playing piano, grumbling, reading, thinking.), la escribiera en algún momento “grumbling”.

Mirad el artículo en la Wikipedia que hace referencia a la evolución humana y ahora decidme si cuando incluimos una clase Person en nuestros sistemas, llegamos hasta el diluvio.

Y por último, la referencia al problema del diamante, que no es otra cosa que el problema que presentan algunos lenguajes OO respecto a la herencia múltiple. Keep calm and use C++ 🙂

Para ejemplificar este problema, el autor del post usa 4 objetos.
– PoweredDevice
– Scanner
– Copier
– Printer

El problema se presenta cuando la clase Copier intenta heredar de Scanner y Printer. ¿Realmente esto es un problema de la programación orientada a objeto o hemos modelado mal nuestros objetos al real-world?

Si pensamos un poco en la vida real, una copiadora no necesita de un Scanner y un Printer para realizar su función. Yo puedo copiar de una cámara en forma de imagen o usando OCR (Optical character recognition). La salida tampoco tiene por qué ser un Printer, un fax no imprime y usa un modem como salida para enviar la información.

En realidad, una copiadora usa métodos de entradas y métodos de salidas. Heredar de una funcionalidad específica como un scanner o un printer y hacerlas propias (herencia), en el real-world, sería un error.

El post sigue enumerando los “problemas” de los pilares fundamentales de la POO, yo lo dejo aquí. Todo el que me conoce sabe que cuando hablo de estos temas, siempre digo lo mismo: esos cambios que nos llegan continuamente de gente que sabe mucho: POO, Patterns, DDD, Microservices, TDD, CQRS, Cloud, relámpagos, truenos y centellas, están ahí para que aprendamos de ellos. El uso que le des, será siempre tú responsabilidad.

C.U. y espero q pronto 🙂

Publicado en General, POO, Social | 1 comentario

¿Es útil mi interfaz?

Empecemos por ver la definición de interfaz, que aunque es muy antigua, contiene mucha influencia en la programación “moderna” (IoC, DI, TDD, APIs, etc.) “Una interfaz es un contrato donde se especifican todos los términos y especificaciones que se deben cumplir para realizar y concretar algo”.

Olvidemos por un momento que hablamos de una interfaz y resaltemos algunas palabras claves en esta definición:

– Contrato
– Términos
– Especificaciones
– Cumplir
– Concretar

El contrato contiene términos y especificaciones, quien lo firme, las tendrá que cumplir y concretar. Un contrato podrá cambiar en el tiempo, pero será un cambio demandado y acordado por ambas partes y siempre se deberá entender como una evolución del mismo.

Volvamos a la interfaz e imaginemos la siguiente situación:

Día 1:

public interface IA
{
void M1();
}

Día 2:

public interface IA
{
void M1(int p1);
}

Día 3:

public interface IA
{
void M1(int p1, int p2);
}

Día 4:

public interface IA
{
int M1(int p1, int p2);
}

Se ha definido una interfaz porque necesitamos que todo aquel que la implemente, cumpla con todos sus términos y especificaciones. El problema aquí es que día tras día esta interfaz ha sufrido modificaciones que implican un cambio del contrato.

Esto por muchos motivos “obvios” no es bueno y las dos razones principales por lo que esto sucede son:

1- No tenemos claro los términos y a medida que vamos desarrollando nos damos cuenta de que tenemos que cambiarlos
2- No hemos recibido las especificaciones que dicho contrato debe cubrir y durante el proceso de desarrollo nos van cambiando.

¿Esto quiere decir que tengo que tener en mi cabeza todos los términos y especificaciones antes de escribir mi contrato? NO. Al principio comentamos que una interfaz puede cambiar, y un ejemplo claro es cuando ampliamos los términos para cubrir más especificaciones.

public interface IA
{
void M1();
}

Si necesitamos ampliar las especificaciones de esta interfaz, modificar la misma sería un error, ya que obligamos a que todos los firmantes tengan que cambiar para soportar las nuevas especificaciones. En este caso lo más correcto sería no afectar a quienes ya implementan esta interfaz y crear las nuevas especificaciones en una nueva interfaz que herede de la ya definida.

public interface IAA : IA
{
void M2(int p1, int p2);
}

La interfaz en un API 🙂

La documentación de un API es un contrato que contiene términos y especificaciones inviolables si no se quiere afectar a quienes nos consumen. Sería un error que con la documentación de un API ocurra lo mismo que con la interfaz IA, y esta cambie constantemente. Las causas son exactamente las mismas: no tenemos claro el flujo lógico de nuestra API y los términos cambian constantemente o, las especificaciones nos llegan a cuenta gotas.

Para decir que estamos listos para escribir la interfaz IA o la documentación de un API, hay que tener claro los términos de la mínima unidad funcional que vamos a llevar a cabo. No tiene que ser toda la lógica, ni siquiera tiene por qué ser la mitad o un tercio, simplemente tiene que ser lo mínimo necesario para que aquello que vamos a desarrollar, podamos plasmarlo en la interfaz o en la documentación.

¿Y cuando quiera ampliar las especificaciones en el caso de un API? Aquí es donde entra el versionado, que irá cambiando en cada modificación del contrato. El versionado de un API no es algo que se tiene en cuenta una vez puesta en producción, sino que va unido a cada paso que da el equipo durante el tiempo de desarrollo.

Imaginemos por último que además de modificar constantemente un contrato, no avisamos a los firmantes. Así, te enteras luego de una semana o un mes, que has estado trabajando por mucho menos de lo pactado o que tu hipoteca se ha incrementado en un 500%… ¿un caos verdad? ¿Qué pensarías de tu empresa o banco? ¿Qué pensarías del equipo que desarrolla la interfaz o el API?

Saludos

Publicado en General, POO | Deja un comentario

Mockeando Window.location

Estoy en un proyecto donde tengo que interactuar con servicios RestFul desde javascript. El problema que tengo es que estos servicios están aún en desarrollo por lo que cuando me toca trabajar con ellos puede que estén o no disponibles.

Para evitar detener mi trabajo cuando los servicios no están disponibles he decidido que los test trabajen con mocks. Hace unos días me tocó hacer un test para chequear un método que internamente hacía uso de window.location.

Hay muchas soluciones disponibles para testear nuestro método, veamos una de ella:

  1. var MyNamespace = new function()
  2. {
  3.     this.MyObject = function(win)
  4.     {
  5.         var __win = win;
  6.  
  7.         this.NavigateTo = function(p1, p2)
  8.         {
  9.             var __url = "http://www.google.com/?q=" + p1 + "&s=" + p2;
  10.             __win.location.href = __url;
  11.         };
  12.     };
  13. };

Este sería nuestro objeto en javascript el cual contiene un método llamado NavigateTo y al que le pasamos dos parámetros para formar una url.

Probar este método es muy fácil: (usaremos qunit por su cómoda integración con ReSharper)

  1. test("Window location", function ()
  2. {
  3.     var __winMock = { location: { href: "" }};
  4.     var __myObj = new MyNamespace.MyObject(__winMock);
  5.  
  6.     __myObj.NavigateTo('abc', 'def');
  7.  
  8.     window.equal("http://www.google.com/?q=abc&s=def", __winMock.location.href, "is ok");
  9. });

Nuestro test pasa sin problemas.

moc-1

En el momento en que necesitemos que nuestro objeto trabaje con el objeto real, solo tenemos que pasar el window en el constructor.

  1. var __myObj = new MyNamespace.MyObject(window);

Otra solución y mi preferida, es encapsular la llamada a window.location.href en una función que podamos usar desde cualquier parte en nuestro proyecto. Luego solo tendríamos que mockear la función y testear que todo esté correcto.

  1. var MyNamespace = new function ()
  2. {
  3.     this.MyObject = function ()
  4.     {
  5.         this.NavigateTo = function (p1, p2)
  6.         {
  7.             var __url = "http://www.google.com/?q=" + p1 + "&s=" + p2;
  8.             Utils.Browser.Navigate(__url);
  9.         };
  10.     };
  11. };
  12.  
  13. var Utils =
  14. {
  15.     Browser: new function()
  16.     {
  17.         this.Navigate = function (url)
  18.         {
  19.             window.location.href = url;
  20.         };
  21.     }
  22. };

Aquí ya no estamos falseando el objeto window sino que encapsulamos su utilización dentro de un objeto Browser que contiene un método llamado  Navigate.

Para testear el ejemplo anterior, vamos a usar Sinon y su pluging para qunit. Como estamos trabajando con ReSharper para las pruebas, debemos indicar la referencia a estos frameworks en nuestro js de pruebas.

  1. /// <reference path="/resources/sinon-1.5.2.js"/>
  2. /// <reference path="/resources/sinon-qunit-1.0.0.js"/>

Ya con esto podemos crearnos nuestro test:

  1. test("Window location", function ()
  2. {
  3.     var __myObj = new MyNamespace.MyObject();
  4.  
  5.     var __mock = sinon.mock(Utils.Browser);
  6.     __mock.expects("Navigate").once().withArgs("http://www.google.com/?q=abc&s=def");
  7.  
  8.     __myObj.NavigateTo('abc', 'def');
  9.  
  10.     __mock.verify();
  11. });

y el resultado…

moc-1

Lo que me gusta de este método respecto al anterior es que no tenemos necesidad de falsear un objeto nativo del DOM. Por el contrario, lo que hacemos es mokear un objeto nuestro y testear su funcionalidad.

Publicado en General, Trucos | 2 comentarios

Microsoft Hosted Network Virtual Adapter

…o lo que es lo mismo, un router virtual WIFI en mi ordenador. 🙂 …y aquí es donde quizás los de IT digan: ¿Y ahora es que te enteras…?

Resulta que el próximo martes toca realizar una presentación de una aplicación Web y para la cual necesitamos que estén conectados a una misma red: dos ordenadores, un iPad y un Tablet con Windows 8.

Posibles soluciones y problemas:

1- WIFI
Solución: Espero a que el lugar de la presentación tenga WIFI, y además el salón tenga cobertura.

Problema: Pierdes tiempo configurando conexiones en los dispositivos, problemas de coberturas, la primera impresión que se deja es un poco de “estamos perdiendo tiempo”

2- Router WIFI
Solución: Me llevo un Router WIFI previamente configurado y conecto a todo el mundo: Imaginen llegar, sacar un iPad, un tablet de W8, dos ordenadores, una kinect y un router con antenita al estilo “Star Wars light sabers” 🙂

Problemas: Necesito un router físico y más conectores de alimentación

3- Tengo un Nokia Lumia 800
Solución: Puedo activar “Compartir conexión” lo cual activa en mi teléfono un host WIFI al cual puedo conectar a todo el mundo.

Problemas: Pobre Nokia Lumia… ¿Cuanto dudará la batería? 🙂

4- Si el teléfono crea un Host WIFI virtual, ¿no podré hacer lo mismo en mi ordenador? Googleando…

Solución: Mi querido amigo netsh

Pues bien, como este trabajo no es de desarrollo sino de IT, en vez de cargar Visual Studio 2012, cargamos la consola de comandos “cmd” y, recuerden que tienen que hacerlo con permisos de administración…

wifi-1

Ejecutamos un primer comando:
netsh wlan set hostednetwork mode=allow ssid=odelvalle key=MyPassword

wlan: Wireless Lan (vamos a trabajar sobre la conexión WIFI)
set hostednetwork: (vamos a trabajar con las propiedades del hostednetwork).

El hostedNetwork es una funcionalidad soportada en W7, W8 y los 2008R2 en adelante…  Su principal objetivo es (para IT) virtualizar un adaptador wireless (para desarrolladores) un router WIFI de toda la vida.

El resto de los comandos indican si vamos a permitir conexión (mode), el nombre que le pondremos a nuestra WIFI (ssid) y la contraseña (key).

Todo lo anterior configura y deja listo nuestro hostednetwork, pero necesitamos echarle a funcionar y, para eso ejecutamos un segundo comando:

netsh wlan start hostednetwork

Este segundo comando inicia el  hostednetwork y deja nuestra vista de adaptadores de red de la siguiente forma:

wifi-2

y mi Nokia Lumia….

Screen Capture

Espero q a alguien le sirva…. Salu2

Publicado en General | Deja un comentario

RESTFul en Windows 8

Para las aplicaciones que he realizado para WP7 tenía un helper que me ayudaba a consultar servicios RESTful, pero la verdad, con todo el tema de async, await y Task, es motivo suficiente como para plantearse rescribir cualquier código asíncrono escrito con anterioridad.

Para nuestro helper vamos a necesitar fundamentalmente 2 clases, aunque implementaremos una tercera clase para el tema de serialización.

A todas las clases les vamos a definir una interfaz, las ventajas ya las conocemos: no atamos las clases que usen nuestro helper a nuestra implementación y además, podremos inyectar el helper usando IoC si trabajamos con MVVM.

Empecemos justo por la clase que se encargará de serializar y de-serializar:

public interface IJsonResolver
{
    Task<byte[]> Serialize(object graph);
    Task<T> Deserialize<T>(Stream respnseResult) where T : class;
}

Nuestra interfaz tiene dos métodos que nos permitan serializar y de-serializar nuestros objetos. Estos métodos retornan un Task, por lo que podremos usar su condición asíncrona durante la implementación.

En mi caso, voy a usar Json.net para implementar esta interfaz, pero ustedes pueden elegir su propia implementación.

public class JsonResolver : IJsonResolver
{
    private async Task<string> SerializeToString(object graph)
    {
        return await JsonConvert.SerializeObjectAsync(graph, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
    }

    public async Task<byte[]> Serialize(object graph)
    {
        if (graph is string) return Encoding.UTF8.GetBytes(graph as string);

        var json = await SerializeToString(graph);
        return Encoding.UTF8.GetBytes(json);
    }

    public async Task<T> Deserialize<T>(Stream respnseResult) where T : class
    {
        T result;

        using (var sr = new StreamReader(respnseResult))
        {
            var r = await sr.ReadToEndAsync();
            result = await JsonConvert.DeserializeObjectAsync<T>(r, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
        }

        return result;
    }
}

Ya tenemos nuestra implementación, vamos a lo que de verdad nos interesa.

La utilización de un servicio web, ya sea Rest, Xml o cualquier otro formato, está compuesto principalmente por dos elementos:

  1. El Request: Este elemento podría contener la URL a la cual vamos a realizar la petición, qué tipo de petición vamos a realizar (si es GET, POST, u otra), el ContentType, los parámetros, etc…
  2. Un cliente que realiza la petición usando todas las opciones definidas en el Request.

Siguiendo esta lógica, mi Helper tendrá dos clases más: un RestRequest y un RestClient.

Vamos a definir la interfaz para el RestRequest.

public interface IRestRequest
{
    Uri Url { get; }
    string PostParameter { get; }
    Method Method { get; }
    string Accept { get; }
    string ContentType { get; }

    /// <summary>
    /// Add Parameter to URL. Value is not encode. If Method is POST, parameter is pass in body, if Method is Get, parameter is pass in URL.
    /// </summary>
    /// <param name="name">Parameter name</param>
    /// <param name="value">Parameter value</param>
    void AddParameter(string name, string value);

    /// <summary>
    /// Add Parameter to URL. This method encode parameter value by default
    /// </summary>
    /// <param name="name">Parameter name</param>
    /// <param name="value">Parameter value</param>
    /// <param name="pType"> </param>
    void AddParameter(string name, string value, ParameterType pType);

    /// <summary>
    /// Add Parameter to URL. This method encode parameter value by default
    /// </summary>
    /// <param name="name">Parameter name</param>
    /// <param name="value">Parameter value</param>
    /// <param name="encode"> </param>
    void AddParameter(string name, string value, bool encode);

    /// <summary>
    /// Add Parameter to URL. 
    /// </summary>
    /// <param name="name">Parameter name</param>
    /// <param name="value">Parameter value</param>
    /// <param name="encode">if true, encode parameter value</param>
    /// <param name="pType"></param>
    void AddParameter(string name, string value, bool encode, ParameterType pType);
}

En esta interfaz tenemos varios elementos que nos ayudan a configurar nuestro Request antes de realizar la petición.

El método AddPArameter cuenta con varias sobrecargas ya que vamos a tener varias posibilidades de pasar parámetros. Vamos a verlo uno por uno empezando por el más complejo (el último):

  1. Este método recibe un nombre, un valor, permite indicar si el valor del parámetro debe ser “encodeado” o no y el tipo de parámetro que estamos utilizando.
    1. El “encodear” el valor de un parámetro es usado fundamentalmente cuando pasamos el valor por GET, ya que hay caracteres que no son válidos como parte de la URL
    2. ParamType es un enumerado que me indica el tipo de parámetro que vamos a pasar a nuestro objeto: QueryString (GET?nombre=valor), Post (se pasa en el body) y UrlSegment que es utilizado cuando el parámetro es parte de la URL. Ej. http://odelvalle.com/{parametro}/Rest
  2. Un segundo método en que no es necesario pasar el tipo de parámetro. En este caso el tipo es determinado según el método usado para el Request, si es GET se pasa por QueryString, si es Post, se pasa en el body.
  3. Otro método que nos permite indicar solo el nombre, el valor y el tipo de parámetro. Todos los parámetros pasados mediante este método, el value es “encodeado”.
  4. Finalmente, tenemos un método que nos vale para pasar solo el nombre y el valor. Los parámetros que se pasen usando esta sobrecarga no se van a “encodear” y el tipo de parámetro es determinado por el tipo de Request (GET o POST)

Las propiedades definidas en la interfaz nos brindan el resto de la información necesaria para formar nuestro Request. Vamos a ver la implementación

public enum ParameterType
{
    QueryString,
    Post,
    UrlSegment
}

public enum Method
{
    GET,
    POST,
    PUT,
    DELETE,
    HEAD,
    OPTIONS,
    PATCH
}

public enum ContentType { Json, UrlEncoded }

public class RestRequest : IRestRequest
{
    struct Parameter
    {
        public string Name { get; set; }
        public string Value { get; set; }

        public ParameterType ParameterType { get; set; }
    }

    private readonly IList<Parameter> _parameters;

    private readonly string _url;
        
    public RestRequest(string url, Method method)
    {
        _parameters = new List<Parameter>();
        _url = url;

        Method = method;
    }

    public Uri Url
    {
        get
        {
            var buildUri = new UriBuilder(_url) { Query = BuildQueryString(ParameterType.QueryString) };
            return buildUri.Uri;
        }
    }

    public string PostParameter { get { return BuildQueryString(ParameterType.Post); }}
    public Method Method { get; private set; }

    public string Accept { get { return "application/json"; }}
    public string ContentType { get { return "application/x-www-form-urlencoded"; } }

    public void AddParameter(string name, string value)
    {
        AddParameter(name, value, false);
    }

    public void AddParameter(string name, string value, ParameterType pType)
    {
        AddParameter(name, value, true, pType);
    }

    public void AddParameter(string name, string value, bool encode)
    {
        AddParameter(name, value, encode, (Method == Method.GET) ? ParameterType.QueryString : ParameterType.Post );
    }

    public void AddParameter(string name, string value, bool encode, ParameterType pType)
    {
        var val = encode ? Uri.EscapeDataString(value) : value;

        if (pType == ParameterType.UrlSegment) _url.Replace(string.Format("{{0}}", name), val);
        else _parameters.Add(new Parameter { Name = name, Value = val, ParameterType = pType});
    }

    private string BuildQueryString(ParameterType pType)
    {
        var plist = _parameters.Where(p=> p.ParameterType == pType).Select(p => string.Concat(p.Name, "=", p.Value));
        return String.Join("&", plist.ToArray());
    }
}

Al constructor de la clase RestRequest le vamos a pasar la URL a la cual queremos realizar la petición y el método a utilizar.

Ya con esto tenemos nuestro RestRequest, vamos a ver el cliente que realizará la petición. Empezamos viendo la interfaz:

public interface IRestClient
{
    Task<T> Execute<T>(IRestRequest request) where T : class;
}

.. y eso es todo. No necesitamos nada más ya que estamos definiendo un cliente que recibirá un objeto RestRequest y hará una petición. Veamos la implementación.

public class RestClient : IRestClient
{
    private readonly IJsonResolver _resolver;

    public RestClient(IJsonResolver resolver)
    {
        _resolver = resolver;
    }

    public async Task<T> Execute<T>(IRestRequest request) where T : class 
    {
        var wr = WebRequest.CreateHttp(request.Url);

        wr.Method = request.Method.ToString();
        wr.Accept = request.Accept;
        wr.ContentType = request.ContentType;

        if (!string.IsNullOrEmpty(request.PostParameter))
        {
            return await ExecuteWithData<T>(wr, request);
        }

        var response = await wr.GetResponseAsync();
        return await _resolver.Deserialize<T>(response.GetResponseStream());
    }

    private async Task<T> ExecuteWithData<T>(WebRequest wr, IRestRequest request) where T : class
    {
        var body = await _resolver.Serialize(request.PostParameter);

        using (var stream = await wr.GetRequestStreamAsync())
        {
            await stream.WriteAsync(body, 0, body.Length);
        }

        var response = await wr.GetResponseAsync();
        return await _resolver.Deserialize<T>(response.GetResponseStream());
    }
}

Nuestro cliente recibe en el constructor el RestRequest que se desea realizar. Mediante el método Execute, el cliente se encarga de realizar la petición y si hay respuesta del servicio Rest, entonces nos retornará el objeto listo para usarse.

Para probar todo esto y ver lo simple que es de usar, me busqué alguna ejemplo Rest que ya existiera para Windows 8.  Aquí tenéis una: Metro client for Web API CRUD

En esta aplicación al final de la clase MainViewModel.cs tenemos el GET usando HttpClient y DataContractJsonSerializer.

using (var http = new HttpClient())
{
    var resp = await http.GetAsync(new Uri(ApiRoot));
    using (var stream = await resp.Content.ReadAsStreamAsync())
    {
        var djs = new DataContractJsonSerializer(typeof(List<Person>));
        People = new ObservableCollection<Person>((IEnumerable<Person>)djs.ReadObject(stream));
    }
}

Vamos a quitar ese código y vamos a usar el nuestro:

var request = new RestRequest(ApiRoot, Method.GET);
var restFul = new RestClient(new JsonResolver());

People = new ObservableCollection<Person>(await restFul.Execute<IEnumerable<Person>>(request));

… ¿probamos?

screenshot_10112012_004023

Aquí dejo la aplicación de ejemplo modificada y usando nuestro Helper.

PD: Aún no he probado todo el Helper, así que es posible que en un escenario específico pueda aparecer algún BUM Sonrisa

Publicado en General | 1 comentario

Carga de páginas en Chrome, rápido sí, pero ¿seguro?

Estoy haciendo una aplicación que usa Web Socket. Como navegador, por políticas del cliente, se está usando Chrome.

Resulta que en unas de mis pruebas, descubro algo que al menos a mi, me deja un “tin” preocupado respecto a Chrome.

Observen:

chrome

Lo que está pasando aquí es que yo abro Chrome, comienzo a escribir la URL y el navegador me propone la URL a usar. El problema es que yo aún no he confirmado que es esa, ni siquiera le he dicho a Chrome que navegue a esa URL, pero ya mi servidor de Web Socket ha detectado una conexión entrante.

¿Entonces?… Pues muy probablemente el listillo de Chrome navegue por detrás para dar la impresión posteriormente de que las páginas cargan más rápido… pero ¿Esto da un poco de miedo no? y más si yo sé que mi web socket en el cliente se inicializa y se ejecuta en el momento en que la página ha sido totalmente cargada, o sea, en el ready.

Probé con IE10 y no pasa. No he probado con más browsers.

Salu2

Publicado en General | 3 comentarios

Repository Pattern para ApplicationData en Windows 8

Con la llegada de Windows 8 y sus aplicaciones para el Store, muchas veces nos toca lidiar con datos almacenados en local.

La idea de este post es implementar el patrón repositorio para independizar nuestras aplicaciones del trabajo con los distintos tipos de almacenamientos en local que existen en Windows 8.

Para profundizar en este patrón puedes echar un ojo a este enlace de Martin Fowler: http://martinfowler.com/eaaCatalog/repository.html

El objetivo

– Evitar código duplicado
– Mejor gestión de errores (código centralizado)
– Menos dependencia de nuestras reglas de negocio a la persistencia
– Posibilidad de centralizar políticas relacionadas con datos como el almacenamiento en caché o Lazy load.
– Posibilidad de “testear” la lógica de negocio de forma aislada a la persistencia

Empezamos creándonos una clase abstracta que nos permita de forma genérica trabajar con cualquier tipo de datos. La clase incluirá los métodos más generales para interactuar con el almacenamiento.

Constructores

Nuestra clase genérica incluye dos constructores, uno que por defecto usará el LocalFolder y otro que nos permitirá especificar el lugar de almacenamiento.

protected Repository(string fileName) : this(fileName, StorageType.Local)
{
}

protected Repository(string fileName, StorageType storageType)
{
   _fileName = fileName.EndsWith(".json") ? fileName : string.Format("{0}.json", fileName);

   // set the storage folder
   switch (storageType)
   {
      case StorageType.Local:
         _storageFolder = _appData.LocalFolder;

         break;
      case StorageType.Temporary:
         _storageFolder = _appData.TemporaryFolder;

         break;
      case StorageType.Roaming:
         _storageFolder = _appData.RoamingFolder;

         break;
      default: throw new Exception(String.Format("Unknown StorageType: {0}", storageType));
   }
}

El parámetro fileName nos sirve para especificar un nombre de archivo para nuestros datos. El archivo será identificado siempre por la extensión json y podemos decidir pasar el parámetro con o sin ella, en cualquier caso el constructor se encargará de realizar el chequeo necesario.

El parámetro storageType es un enumerado que incluye los distintos tipos de almacenamiento.

public enum StorageType
{
   Local,
   Temporary,
   Roaming
}

Dependiendo de este parámetro, el constructor inicializa  el StorageFolder a usar por nuestro repositorio.

Los métodos

/// <summary>
/// Delete a file asynchronously
/// </summary>
public async void DeleteAllAsync()
{
   var file = await GetFileIfExistsAsync(_fileName);
   if (file != null) await file.DeleteAsync();
}

Este método nos permite eliminar todos los datos almacenados. La operación se realiza de forma asíncrona y se resume a eliminar el archivo donde se encuentran almacenados nuestros datos.

El método GetFileIfExists nos retorna de forma asíncrona un StorageFile si el archivo existe, de lo contrario retorna nulo.

/// <summary>
/// At the moment the only way to check if a file exists to catch an exception... 
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
private async Task<StorageFile> GetFileIfExistsAsync(string fileName)
{
   try
   {
      return await _storageFolder.GetFileAsync(fileName);
   }
   catch
   {
      return null;
   }
}

La única forma que tenemos de saber si un archivo existe es capturando el error. La razón que Microsoft nos da para no contar con un File.Exists en el API es que el estado del archivo puede cambiar entre que nosotros preguntamos si existe y realizamos alguna operación. Según Microsoft, si contáramos con un File.Exists, igualmente tendríamos que capturar posibles errores cuando trabajamos con el archivo.

/// <summary>
/// Persist data to StorageFolder
/// </summary>
public virtual void Flush()
{
   SaveAsync(Data.Value);
}

El método Flush usa Data.Value para indicar los datos a persistir. Esto no es más que el lugar en memoria donde está almacenado nuestro objeto.

protected Lazy<T> Data;

El uso de Lazy<T> nos permite acceder a StorageFolder en el momento en que se necesiten los datos  por primera vez.

Los datos de memoria se envían al StorageFolder que seleccionemos llamando a un método interno de nuestro repositorio que realiza la persistencia de forma asíncrona.

/// <summary>
/// Saves a serialized object to storage asynchronously
/// </summary>
/// <param name="data"></param>
protected async void SaveAsync(T data)
{
   if (data == null) return;

   var file = await _storageFolder.CreateFileAsync(_fileName, CollisionOption);
   await FileIO.WriteTextAsync(file, Serialize(data).Result);
}

El método interno SaveAsync crea nuestro archivo si este no existe, de lo contrario lo re-escribe.  Estamos usando ReplaceExisting como política de Colisión, de cualquier forma, esta  variable es protegida en nuestra clase base, así que puede ser cambiada por las clases que heredan.

protected CreationCollisionOption CollisionOption = CreationCollisionOption.ReplaceExisting;

De la misma manera que guardamos en el StorageFolder, también necesitamos leer. El siguiente método nos permite recuperar un objeto de forma asíncrona.

/// <summary>
/// Load a object from storage asynchronously
/// </summary>
/// <returns></returns>
protected async Task<T> LoadAsync()
{
   try
   {
      var file = await _storageFolder.GetFileAsync(_fileName);
      var data = await FileIO.ReadTextAsync(file);

      return await Deserialize(data);
   }
   catch (FileNotFoundException)
   {
      //file not existing is perfectly valid so simply return the default 
      return default(T);
   }
}

Tanto para leer, como para escribir datos en nuestro repositorio, se usan métodos que se encargan del trabajo de serialización del objeto.

Como cada cual tiene su propio mecanismo para serializar, estos métodos son declarados como abstractos dentro de nuestra clase base, de esta forma, podemos indicar en cada clase que herede, cual será la manera en que se serializarán los objetos, incluso, pudiéramos tener dentro de la misma aplicación, objetos que se persistan usando mecanismos de serialización totalmente distintos.

protected abstract Task<string> Serialize(T data);
protected abstract Task<T> Deserialize(string data);

He dejado para el final una propiedad que nos retorna nuestro objeto desde el StorageFolder o de memoria según sea el caso.

/// <summary>
/// Return T
/// </summary>
public virtual T All
{
   get { return Data.Value; }
}

Teniendo en cuenta que nuestro Repositorio puede valer para almacenar un simple objeto o una lista de objetos, tener una propiedad pública que nos retorne “todo” no es una muy buena práctica. De cualquier forma esto no viene a sustituir grandes almacenes de datos, ya que para eso tenemos bases de datos locales como SQLLite, sino que está pensado para pequeños datos. Es por esto que me tomo la libertad de incluir una “mala” práctica en mi código.

Nuestra clase base está lista, vamos a ver cómo usarla.

Para la implementación, voy a usar Newtonsoft.Json para la serialización de los objetos. Las clases a utilizar con los repositorios serán una simple y otra una lista, para poder ver las dos formas de utilizar nuestro repositorio.

public class Account
{
   [JsonProperty]
   public string Name { get; set; }
}
public class Family : List<Person>
{
   [JsonProperty]
   public IList<Account> Itenms { get; set; }
}

public class Person
{
   [JsonProperty]
   public Guid Id { get; set; }

   [JsonProperty]
   public string Name { get; set; }

   public bool IsTransient
   {
      get { return Id == Guid.Empty; }
   }
}

Nuestro repositorio siempre trabaja con un objeto, por lo que la única diferencia entre guardar un objeto simple o una lista, no es otra que usar uno o lo otro.

En el ejemplo crearemos un repositorio para Account y otro para Family que es una lista de Person.

Vamos a ver el repositorio de Family:

    public class RepositoryFamily : Repository<Family>, IRepositoryFamily
    {
        public RepositoryFamily(): base("Family")
        {
            CollisionOption = CreationCollisionOption.OpenIfExists;
            Data = new Lazy<Family>(() => LoadAsync().Result ?? new Family(), true);
        }

        public async Task<Person> Get(Guid id)
        {
            return await Task.Factory.StartNew(() => All.Single(p => p.Id == id));
        }

        public void Save(Person person)
        {
            if (person.IsTransient)
            {
                person.Id = IdentityGenerator.NewSequentialGuid();
                Data.Value.Add(person);

                return;
            }

            var idx = Data.Value.FindIndex(a => a.Id == person.Id);
            Data.Value[idx] = person;
        }

        protected override Task<string> Serialize(Family data)
        {
            return JsonConvert.SerializeObjectAsync(data);
        }

        protected override Task<Family> Deserialize(string data)
        {
            return JsonConvert.DeserializeObjectAsync<Family>(data);
        }
    }

Como se ve, implementamos los métodos abstractos del repositorio para serializar y ya solo nos queda ir implementando los métodos que necesitemos según el tipo de datos que estemos trabajando.

Para el ejemplo, tengo el método Save que adiciona una persona en la lista si no existe, o de lo contrario, lo actualiza.

Cuando deseemos guardar una nueva persona en nuestro repositorio, el código a utilizar sería así:

private void SaveFamilyNameCommand(string name)
{
   _familySrv.Save(new Person { Name = name});
   _familySrv.Flush();

   Family = new ObservableCollection<Person>(_familySrv.All);
   RaisePropertyChanged(()=> Family);
}

La aplicación que les dejo de ejemplo, en la vista principal tiene dos TextBox, uno para que escriba su nombre y otro para que adicione los nombres de su familia.

screenshot_10072012_135829

Después de escribir su nombre y guardar y después de entrar nombres de sus familiares, puede cerrar la aplicación y volverla a abrir para ver cómo los datos se persisten.

screenshot_10072012_135936

El ejemplo requiere MVVM Light y Newtonsoft.json. Source

Salu2

Publicado en General, Patrones, Trucos | Deja un comentario