Principios SOLID – Principio de Abierto/Cerrado (OCP)

En una anterior entrada, explicaba los principios SOLID y, además, hice un vídeo del primero de ellos con varios ejemplos.

En esta entrada, quiero explicar el segundo de ellos y dar a conocer la importancia de entenderlo y saberlo aplicar. Este, dice así,

Principio de Abierto – Cerrado (OCP)  toda clase debe ser extensible sin requerir modificación en la implementación de sus métodos internos. Esto se consigue mediante la abstracción.

Es decir, que una entidad (clase) en nuestro desarrollo debería estar abierta a extensión pero cerrada a modificación.
Para ver esto más claro y entender OCP más rápidamente, primero, veremos una violación del principio OCP. Dentro de un entorno profesional académico dónde tenemos diferentes perfiles y cada uno de ellos tiene variables salariales en función de su antigüedad. En un inicio, lo que haremos, será implementar este conjunto de clases,

public class Teaching {
      public double VariableSalary { get; set; }
      public double Antiquity { get; set; }
}

public class VariableSalaryCalculator {
      public double VariableSalary(IList<Teaching> personal)
      {
          double salary = 0;
          foreach(Teaching p in personal)
              salary = p.Antiquity * 1.2d;
          return salary;
      }
}

Cómo podemos observar, tenemos la clase Teacher con sus propiedades y posteriormente otra para calcular el salario variable.

Aparentemente, esto, parece correcto. El problema viene, cuando pasado un tiempo, nos solicitan que el salario variable ahora es aplicable para todo el personal relacionado con la enseñanza y no únicamente para los profesores, y que además, es diferente en función de ese rol.

Si no tenemos en cuenta este principio, nuestro código sería modificado con un resultado similar al siguiente,

public class VariableSalaryCalculator
{
    public double VariableSalary(IList<Object> teachers)
    {
        double salary = 0;
        foreach (var p in teachers)
        {
            if (p is Teacher)
            {
                Teacher pItem = (Teacher)p;
                salary = pItem.Antiquity * 1.2d;
            }
            else
            {
                Administrative pItem = (Administrative)p;
                salary = pItem.Antiquity * 1.1d;
            }
        }
        return salary;
    }
}

Cómo podemos observar, esto es incorrecto. No únicamente por el principio OCP si no porque estamos escribiendo un código altamente acoplado y una cohesión baja teniendo que modificar la clase para cada rol que tengamos.

Siguiendo el ejemplo, y para aplicar el principio OCP, tenemos una solución muy sencilla; crear una clase base que represente al personal docente y extenderlo mediante nuevas clases que sobrescriban el método según el rol del personal.

public class Teaching {
      public abstract double VariableSalary { get; set; }
      public double Antiquity { get; set; }
}

public class Teacher : Teaching {
      public override double VariableSalary {
      	salary = this.Antiquity * 1.2d;
      }
}

public class Administrative : Teaching {
      public override double VariableSalary { 
	salary = this.Antiquity * 1.1d;
      }
}

Sencillo, ¿Verdad?

Esto nos asegura que nuestro sistema se podrá extender, será fácil de mantener, de hacer Unit Testing en él… y además, cumpliremos con el principio OCP.

Happy clean code :)

Usando Windows Azure Content Delivery Network (CDN)

El Azure Content Delivery Network (CDN) esta diseñado para enviar audio, vídeo, imágenes y otros contenidos rápidamente a los usuarios en función de la proximidad del usuario a un nodo de su red global. Esto aumenta la velocidad y la disponibilidad haciendo su uso indispensable para ofrecer una gran experiencia de usuario dentro de nuestra aplicación web.

cdn

El CDN o Red de entrega de contenidos nos ofrece una red de servidores distribuidos que es fundamental para escalar cualquier aplicación HTTP en Azure. En la actualidad cuándo diseñamos una aplicación web que recibirá mucho trafico generado por miles de usuarios mediante llamadas concurrentes proporcionando diferente tipo de contenidos desde archivos CSS a imágenes, entre otros, sería un error plantear que un único nodo sea el responsable de ofrecer el contenido.

En este tipo  de escenarios y mediante el CDN conseguimos distribuir todos nuestros contenidos en servidores distribuidos de forma geográfica para que cuando un usuario de USA este conectado a nuestra aplicación web, el CDN le proporcione el contenido de nuestras páginas desde el nodo geográficamente más cercano.

Razones para usar un CDN

Una de las razones obvias es la distribución global y la caché de contenidos de cada uno de los nodos de la red global ofreciendo una menor latencia en la carga de la página a los usuarios de nuestra aplicación.

Con el uso de esta red ofreceremos un mejor rendimiento a nuestras aplicaciones y servicios, tendremos una aplicación escalable, reduciremos la posibilidad de failover de nuestra aplicación y además, ofreceremos contenido seguro en todo momento a través de la distribución del contenido mediante HTTPS.

Configurar Windows Azure CDN

Para configurar nuestro CDN en Azure debemos ir al portal y de ahí a Nuevo > Medios + CDN > CDN y configurar el nombre de nuestro CDN, la ubicación principal y el grupo de recursos dónde almacenaremos todo nuestro contenido. Es importante establecer el nodo principal cercano a nuestro mercado principal pues es del que se replicará a los otros nodos del CDN global de Azure.

cdn_azure

Una vez tenemos el CDN creado debemos crear un Endpoint o punto de conexión desde el mismo portal,

cdn_azure_endpoint

Para crear el endpoint necesitaremos especificar un nombre, el tipo de origen, y el host de origen. Si en el tipo de origen seleccionamos un origen personalizado deberemos escribir nosotros el host de origen, cómo por ejemplo, www.francescjaumot.net que será el dominio autorizado a consumir de nuestro CDN.

Una vez configurado nuestro endpoint este tendrá un nombre *.azureedge.net siendo * el nombre de nuestro dominio CDN y empezaremos a cargar contenido en él indicándole la ubicación del contenido mediante una ruta relativa. En mi caso el origen es un sitio web pero este puede ser el almacenamiento, un servicio en la nube, una WebApp o cómo en mi caso un dominio personalizado.

Lo más lógico para un entorno de producción es que tengamos un BLOB de Azure dónde subamos todo el contenido que queremos distribuir a través de un CDN y desde ahí administremos el contenido que cargaremos a nuestro endpoint.

cdn_azure_endpoint_load

Una vez tenemos nuestro contenido cargada podemos acceder a él y hacer referencia de el desde nuestra aplicación web mediante la URL que nos da el CDN, en nuestro caso, http://cdn4demo.azureedge.net/sliderAZURE_1.jpg.

Si nuestra aplicación ya esta desplegada en un entorno de producción y tenemos configurada la misma en un servidor IIS, podemos agregar una norma rewrite en el servidor web para que sobrescriba la URL de un grupo de contenidos directamente a nuestro CDN sin aplicar ningún cambio en nuestro código y con tan solo modificar nuestro web.config,

<rewrite>
  <rules>
    <rule name="Rewrite hacia el CDN">
      <match url="^wp-content/(.+)$" />
      <action type="Rewrite" url="http://cdn4demo.azureedge.net/{R:0}" />
    </rule>
   </rules>
</rewrite>

Tener en cuenta que el endpoint y su contenido no están disponibles de forma inmediata. De hecho puede tardar hasta 90 minutos para que sea registrado y distribuido en la red global de azure. Mientras no esté distribuido recibiremos un fantástico error 404 :) .

AngularJs, el framework MVC de JavaScript

En la actualidad, los sitios web son mucho más dinámicos ofreciendo una experiencia de usuario agradable y ligera realizadas con las tecnologías web que dominan esta era; HTML5, Javascript y CSS3 son los líderes indiscutibles para el desarrollo de nuestros front-end.

Cómo sabemos HTML es un lenguaje estático y requiere de Javascript para hacerlo dinámico. Sin embargo, esta dinamización de documentos HTML es una tarea que conlleva trabajo.

En anterioridad a este tipo de frameworks podíamos modificar nuestro DOM mediante métodos conocidos cómo el getElementById o createElement, entre otros, que nos permitían modificar según nuestra necesidad el documento HTML. Todo el código JS que íbamos desarrollando no seguía un patrón y, con el tiempo, todo era difícilmente manejable y podía terminar generando un Spaguetti Code.

En este punto, frameworks de desarrollo cómo AngularJS y el patrón MVC (Modelo, Vista, Controlador) nos puede ser de gran ayuda.

AngularJs es un framework MVC de JavaScript que permite crear aplicaciones SPA (Single Page Application) y que corre al lado del cliente (browser) para dinamizar documentos HTML.

Este framework nos trae un enfoque dinámico que debemos aplicar sobre los documentos HTML estáticos mediante la vinculación de elementos de nuestro documento HTML con nuestro modelo de datos (data binding). De esta forma, definimos un modelo de datos que se corresponde con determinadas partes de nuestro documento HTML y que, cuándo se produzcan cambios que deban modificar la vista, actualizarán este documento.

AngularJS extiende nuestro documento HTML

Mediante el uso de las directivas (Directives) ng- y las expresiones (Expressions) para bindear datos a las vistas, angular, extiende nuestro documento HTML.

La directiva ng-app define que la aplicación web es una aplicación web que hace uso de angular.
La directiva ng-model se encarga de hacer los bindear nuestras propiedades del modelo de datos con los diferentes controles de HTML.
La directiva ng-bind realiza el binding de nuestro modelo de datos en la View.

Veamos un ejemplo para ver con detalle su uso,

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
    <meta charset="utf-8" />
    <script src="Scripts/angular.min.js"></script>
    <script src="app/app.module.js"></script>
    <script src="app/app.controller.main.js"></script>
</head>
<body ng-app="app" ng-controller="Food as vm">
    <input type="text" ng-model="vm.item" placeholder="Entrar alimento" />
    <p>Tengo que comprar {{vm.item}}!</p>
</body>
</html>

Cómo vemos en la estructura de nuestro documento HTML lo primero que debemos hacer es descargar angular y poner una referencia a la librería.

Toda aplicación realizada con angular requiere ser inicializada mediante la etiqueta ng-app que hará referencia a nuestro modulo. Tenemos que ver el modulo cómo un contenedor de las diferentes partes de nuestra aplicación. Toda nuestra aplicación estará compuesta por módulos y a cada modulo le pertenecerá n controladores.

En nuestro fichero app.module.js tendremos la siguiente declaración para exponer nuestro modulo app,

(function () {
    angular.module('app', []);
})();

Y en el fichero app.controller.main.js tendremos el controlador foodController perteneciente al modulo app,

(function () {
    angular
        .module('app')
        .controller('Food', food);
 
    function food() {
        var vm = this;
        vm.item = 'leche';
    }
})();

Si seguimos con nuestro documento observamos que le indicamos el módulo mediange ng-app, el controlador mediante ng-controller al cuál le hemos puesto un alias vm y el modelo de datos (realizando en JS) mediante ng-model. Posteriormente, y en ese caso para la propiedad item, para mostrar el value hacemos uso de las expresiones {{vm.item}} substituyendo la directiva ng-bind. También podríamos hacer,

 <p>Tengo que comprar <span ng-bind="vm.item"></span>!</p>

Y veremos que el uso de las expresiones o de la directiva da el mismo resultado.

Cómo podemos observar AngularJs nos aporta beneficios en el momento de plantear una aplicación web dónde todo su funcionamiento sea en la parte del cliente y dónde el código JavaScript sea el principal actor de nuestro software. Nos aportará estructura, orden y un patrón con la que enfocar nuestras aplicaciones web.

Single-Page Application: Web Apps modernas

Single-Page Applications (SPAs) son aplicaciones web que cargan una única página de HTML y la actualizan de forma dinámica en función de las interacciones del usuario con esa página.

SPAs utiliza HTML5, CSS y AJAX para crear aplicaciones fluida sin recargar la página de forma constante. Básicamente, toda la carga de la página y toda su interacción se encuentra en el lado del cliente mediante JavaScript.

En una página tradicional, cada vez que se hace una navegación del cliente al servidor este renderiza una nueva página de HTML. Esto, ejecuta un refresco de la página en el navegador del cliente.

En una página SPA, después de que la página sea cargada por primera vez, todas las interacciones con el servidor suceden a través de llamadas AJAX. Este devuelve datos, no tags en HTML, normalmente en un formato JSON. La aplicación web usa los datos devueltos en JSON para actualizar la página de forma dinámica, sin tener que recargar la página completa.

Cómo podéis observar, el ciclo de vida de las páginas SPA ofrecerán un rendimiento más fluido sin tener que volver a hacer que la página se recargue al completo.

Uno de los aspectos más cambiantes es la arquitectura de nuestra aplicación web. El envío de peticiones mediante AJAX y recepción de resultados mediante JSON crea una separación entre la capa de presentación y la lógica de la aplicación.

Esta separación hace que sea más fácil diseñar y mejorar cada una de las capas por separado. Si implementamos nuestra arquitectura correctamente, podremos cambiar el código HTML sin tocar el código que implementa la lógica de la aplicaciones, haciendo nuestra solución la ideal.

En esta arquitectura, toda la interacción del usuario con la UI sucede en el cliente (browser) a través de JavaScript y CSS dejando al servidor cómo una capa de servicio, es decir, que el servidor encapsulará una Web Api para dar respuesta a las peticiones HTTP de la SPA.

Con esta arquitectura, el cliente y el servicio son independientes pudiendo reemplazar al completo todo nuestro back end siempre y cuándo las cabeceras de la API se conserven para que el cliente pueda ejecutar las llamadas HTTP sin modificación. Por supuesto, lo contrario, también sería completamente posible. Podríamos escribir una aplicación móvil nativa o cualquier otra aplicación que consumiera la API al completo.

Para hacer SPAs existen diferentes Frameworks de JavaScript que podemos usar. En próximos articulos veremos frameworks cómo KnockoutJs, AngularJs y Ember.Js para el lado del cliente sobre ASP.NET, y ASP.NET Web Api para nuestro back-end.

Un saludo!!

Novedades en C# 6.0 (II)

En mi anterior entrada hacia un anticipo de las novedades que ofrece la nueva versión de C#. Todas las novedades, recaen en una evolución hacia la simplicidad y mejora de la escritura del propio lenguaje.

Operador condición NULL

¿Cuantas veces has visto en tu aplicación un NullReferenceException por no controlar correctamente un posible valor null? Seguramente en diferentes ocasiones. En esta nueva versión se nos propone una forma simple y limpia de hacer esta validación.
Observemos cómo hacíamos la validación hasta el momento,

public string Truncate(string value, int length)
{
  string result = value;
  if (value != null)
    result = value.Substring(0, Math.Min(value.Length, length));
  return result;
}

Si no hacemos la validación del value a null, el método Substring nos devolvería una excepción NullReferenceException. Vamos a hacer exactamente lo mismo, pero con la nueva sintaxis de código,

public string Truncate(string value, int length)
{          
  return value?.Substring(0, Math.Min(value.Length, length));
}

Cómo podemos observar, nos simplifica la validación y la expresa de forma natural para que nos sea más simple y ágil tener en cuenta este tipo de validaciones que tantos quebraderos de cabeza nos dan cuándo las olvidamos.
Debemos tener en cuenta que el operador ? va a devolver siempre un tipo nullable, es decir, que si el tipo de devolución es int deberemos expresar el tipo cómo int? para que pueda aceptar el valor después de la validación con el operador o bien un null.
De hecho, si no indicamos esto, el IDE no nos dejará compilar indicando que el error es de conversión de tipos int? a int.

Mejoras en al gestión de excepciones

Tenemos dos mejoras muy importantes, la primera de ellas es el uso de operaciones async/await dentro de los bloques de excepciones y la segunda es el filtrado de excepciones.

try
{
  WebRequest webRequest = WebRequest.Create("http://contoso.com");
  WebResponse response = await webRequest.GetResponseAsync();
}
catch (WebException exception)
{
  await WriteErrorToDb(exception);
}

De forma totalmente asíncrona escribiríamos la traza en en nuestro log y seguiremos ejecutando el código mejorando así el performance de nuestra aplicación. Haciendo uso del mismo bloque de código podemos, ahora, filtrar por el tipo de excepción y actuar en consecuencia. Veamos el ejemplo,

try
{
  WebRequest webRequest = WebRequest.Create("http://contoso.com");
  WebResponse response = await webRequest.GetResponseAsync();
}
catch (WebException exception)
 when (exception.Status == WebExceptionStatus.Timeout)
  {
     await SendEmail(exception);
  }

Inicialización de diccionarios

Esta característica nos permite inicializar con valores por defecto nuestros diccionarios con mucho menos código que antes,

Dictionary<string, string> airportCode = new Dictionary<string, string>()
{
["BCN"] = "Barcelona",
["LER"] = "Lleida",
["SVQ"] = "Sevilla"
};

Constructores primarios

Esta es una fantástica feature para nuestro código, aunque a mi personalmente, me gusta más tener los constructores correctamente ubicados en regiones dentro de mi clase aunque debo reconocer que ubicar el constructor a nivel de clase es práctico y nos da, de un solo vistazo, que información precisa la clase para funcionar debidamente.

public class BasketItem(int unit, int productId, double price)
{
public string Unit{ get; set; } = unit;
public string ProductId { get; set; } = productId;
public string Price { get; set; } = price;
}

Espero disfrutéis de estas novedades y sobretodo, que las apliquéis 😉 ¡vuestro código lo agradecerá!