jueves, 14 de noviembre de 2013

Prototype en Javascript. ¿Y eso que es?

Hola de nuevo,

Voy a tratar el tema de prototype de forma "literaria", los artículos más técnicos de momento los publico en codeproject.com, ya que tiene más lectores que este estupendo blog.

El tema a tratar hoy es:

Prototype en Javascript. ¿Y eso que es?

Permitirme el defecto de formato, que no de forma, en el título, cosas del SEO :-)

Bien, vayamos al grano, mi profesor del colegio, JA, decía que hay dos normas básicas a la hora de definir algo, una es no incluir la propia palabra en la definición, y la otra es "no decir lo que no es".
Pues bien, para el caso de prototype, encaja bien decir "lo que no es" ya que es una "cosa" que da lugar a mucha confusión según el contexto donde lo leas y quien lo haya escrito, así que mi primer consejo para comprender que es prototype es leer este post, y después no volver a leer ningún otro nunca más, así no nos invadirán las dudas.

Siendo científicos prototype es
"Una propiedad de todos los objetos de Javascript, que actúa como plantilla para los objetos"
 o,
"Una propiedad para añadir propiedades y/o métodos a una clase".

Bien, pues después de estas definiciones wikipedikas, que no ha entendido nadie, yo tampoco, voy a seguir con mi definición de "lo que no es", ya que enciclopedias ya hay muchas, y esto es literatura,

Prototype NO:

1) No son métodos estáticos, "son algo parecido"

2) No son métodos de extensión aunque pueden servir para este propósito

3) Puede servir como herencia, pero no es herencia

Porqué:

1) Es la forma correcta de declarar métodos dentro de objetos (funciones, esto es otro tema) en javascript. Según el ejemplo que veas en Internet, permiten una sintaxis que "hace pensar" que son métodos estáticos, pero en realidad no lo son. Esa sintaxis es la siguiente:
 
           NombreClase.prototype.metodo = function () { codigo }

Bien, ¿Verdad que parece un método estático? Pues bien, no lo es, ya que los métodos declarados de esta forma son llamados por instancias de objetos y el código de estos métodos tiene acceso a las propiedades del mismo. Por tanto no son métodos estáticos aunque su sintaxis lo parezca.

Es la forma correcta de declarar métodos en una clase, pero por un tema de funcionamiento interno de javascript, al añadir los métodos dentro de la propiedad prototype, su definición solo se almacena una sola vez en memoria, cosa muy recomendable si vamos a crear múltiples instancias de una clase, e insignificante si la utilizamos como singleton o "pairLeton". Pero las buenas prácticas, dicen que debes declararlo así.

En Javascript, realmente no existen los métodos estáticos. Eso sí, si un método de prototype no accede a ninguna propiedad de la clase, se parece bastante a un método estático, ¿no?
Pues se podría decir que sí, que "se parece", pero no lo es.

2) No son métodos de extensión, veamos este ejemplo:

Date.prototype.mondayOfWeek = function () {
    return (this.addDays((6 - (7 + (this.getDay() - 2)))));
}

A ver, eso en C# se llama método de extensión.   Cierto, a la clase Date, clase nativa de Javascript de la que no tenemos acceso a su código,  le estamos añadiendo la propiedad "mondayOfWeek", eso sin ninguna duda en .NET se llama método de extensión.

Sí, pero prototype no tiene solo esta finalidad, por tanto prototype "sirve para extender métodos, pero no es exclusivamente eso, por tanto no es un método de extensión. Por hacer una comparativa un "yogur tiene leche" pero "no es leche"

Ojo al dato, prototype también se puede usar para añadir métodos a instancias concretas de objetos, por tanto en ese caso estaría actuando como "decorador"

3) No es herencia pura, sirve para hacer herencia, pero no la herencia que estudiamos de toda la vida, con propiedades publicas/privadas/protegidas, es más bien composición. Con prototype se consigue que una clase "Hijo" contenga a toda una clase "Padre" de la siguiente forma

Hijo.prototype= new Padre();

pero esto no significa que "Hijo" hereda de "Padre" y accede a sus métodos públicos y protegidos, sino que directamente Hijo "Tiene" un Padre entero. Ciertamente se aproxima bastante a la herencia, pero no la de los libros. Todas las instancias de la clase "Hijo" contendrán todas las propiedades y métodos de la Padre, sin distinción de acceso privado/publico.  Se podría decir que es "herencia Full", termino que no debéis buscar porque creo que no existe, pero se entiende, o eso creo, no esto seguro...


Bueno, pues en resumidas cuentas prototype se podría definir como:

"Una propiedad de todos los objetos de Javascript con la que se pueden implementar/simular las características principales de la POO: Herencia, extensión, polimorfismo, decoración, métodos estáticos" 

Si nos podemos a mirar con lupa cada una de estas características siempre encontraremos matices, peros, en los que nos podremos basar para afirmar que "se parece a Herencia, .... " pero "NO lo es"

Y es que los tipets que implementaron prototype para Javascript creo que debían estar pensando en lo siguiente

"La gente critica Javascript porque dicen que no es un lenguaje con funcionalidades POO, pues bien, vamos a hacer una 'cosa', con la que se podrá 'simular' los aspectos principales de la POO"

Y a mi entender, lo consiguieron, efectivamente, y es que estos últimos meses, estoy encantado de conocer mejor Javascript, un lenguaje muy flexible que como mi buen amigo Cancho (principal, y casi único lector de este blog) dice, ha sido injustamente tratado, tal vez por desconocimiento


Bueno, como decía al principio, el blog lo dejo para reflexiones filosóficas, si a alguien le interesan los temas más técnicos puede seguirme en codeproject.com, aquí dejo el link a un articulo, "simular" LINQ para JQuery.
http://www.codeproject.com/Tips/665477/LINQ-to-JQuery

Y en el próximo post hablaré de un cuento muy divertido de los "three monkeys", dejaré un link al cuento, contaré una anécdota y daré mi opinión sobre el.

Si has llegado hasta aquí, tiene mérito, saludos.

martes, 8 de octubre de 2013

LINQ en JQuery

Ejemplo de LinQ en JQuery

Haciendo uso de la función Jquery $.grep y los métodos de extensión en Javascript, a continuación expongo un ejemplo de como implementar un "simulador" de Linq para JQuery.

Primero expongo una breve explicación, y abajo pego el código entero con ejemplos de uso.

Conceptos:

JQuery $.grep :  Es una utility de JQuery, que permite filtrar vectores de objectos. También pueden ser útiles $.map y $.each

prototype: Es la forma de extender métodos en javascript, el equivalente a los métodos de extensión en C#.

eval : Gracias a esta función javascript, que ejecuta una cadena como una función, cualquier expresión lógica es pasada como parámetro a las funciones y evaluada.


A continuación el código:


//LinQ to javascript extensions methods for class Array
//Need JQuery


// *** Samples of use ****

    //var myArray = [
    //                 { id: 1, name: "luis", checked: false }
    //                , { id: 2, name: "juan", checked: true }
    //                , { id: 3, name: "ana", checked: false }
    //];


    //console.log("Count sample: " + myArray.Count("item['checked']==true || item['id']==1"));
    ////word item it's not necessary
    //console.log("Count sample: " + myArray.Count("['checked']==true || ['id']==1"));
    //console.log("Count sample: " + myArray.Count("['name']=='luis'"));
    ////If not params, return array length
    //console.log("Count sample: " + myArray.Count());

    //console.log("FindFirst sample: " + myArray.FindFirst("['id']==1").id);
    //console.log("FindFirst sample: " + myArray.FindFirst().id);

    //console.log("Exists and FindFirst sample: " + (myArray.Exists("['name']=='anaXX'")
    //                                            ? myArray.FindFirst("['name']=='anaXX'").id
    //                                            : "not exits"));

    //var vectResult = myArray.Where("item['id']==2");

//*** Samples of use ****



function itemParser(str) {
    var result;

    result = str.replace("item", "");
    result = result.replace("[", "item[");

    return result;
}

//Extend Array with prototype

Array.prototype.Count = function (expr) {
    if (expr == null || expr == "") return this.length;

   
    return ($.grep(this, function (item, index) {
        return (eval(itemParser(expr)));
    }).length);
};


Array.prototype.FindFirst = function (expr) {
    if (expr == null || expr == "") expr = "true";

    var result = ($.grep(this, function (item, index) {
        return (eval(itemParser(expr)));
    }));

    return (result.length > 0 ? result[0] : null);
};


Array.prototype.Exists = function (expr) {
    if (expr == null || expr == "") expr = true;

    var result = ($.grep(this, function (item, index) {
        return (eval(itemParser(expr)));
    }));

    return (result.length > 0);
};


Array.prototype.Where = function (expr) {
    return ($.grep(this, function (item, index) {
        return (eval(itemParser(expr)));
    }));
};



miércoles, 18 de septiembre de 2013

Convertir dataReader en un tipo IEnumerable a través de reflexión con c#

En otro post puse un ejemplo de reflexión.
Ahora vamos a ver otro uso de la reflexión, en este caso para convertir un dataReader en un lista genérica, es decir en un tipo IEnumerable<T>

El escenario es útil en los siguientes casos:

  • Trabajamos con LINQ y nos hemos acostumbrado a utilizarlo para tratar las entidades de negocio.
  • Si trabajamos con un ORM (Entity, NHibernate) enlazaremos fácilmente las entidades de negocio y consultas con listas.
  • Pero, si, no trabajamos con un ORM, no lo tendremos tan cómodo.
  • Tampoco si trabajamos con un ORM con enfoque Code First y obtenemos los datos de un procedimiento almacenado.
  • Independientemente de la utilidad del método, queremos ver un ejemplo de método de extensión y/o reflexión.

Paso 1. Crear Método de reflexión.
Recibe por parámetro:
 Un Objeto al que copiar el valor de la propiedad. Observar que es un paso por referencia.
 El nombre/Valor de la propiedad a establecer al objeto.

public class Reflection
{
    public void FillObjectWithProperty(ref object objectTo, string propertyName, object propertyValue)
   {
        Type tOb2 = objectTo.GetType();
         tOb2.GetProperty(propertyName).SetValue(objectTo, propertyValue);
   }
}
Ya tenemos la función. No tiene ningún misterio, utiliza tres métodos básicos de reflexión que hablan por si solos (GetType, GetPropery, y SetValue).

Paso 2. Crear método de extensión.
Es el más complejo, podemos encontrar mucha información en google sobre los métodos de extensión. Pego la función, que está comentada con detalle.
public static class IENumerableExtensions
{
    public static IEnumerable<T> CopyDataReader<T>(this IEnumerable<T> list, DbDataReader dr)
    {
        //Instanciar objecto reflec de la clase Reflection codificada antes
        Reflection reflec = new Reflection();
        //Declarar un objeto "instance" tipo Object y una lista de objetos
        Object instance;
        List<Object> lstObj = new List<Object>();
       
        //Recorrer dataReader
       while (dr.Read()){
            //Crear instancia del objeto necesario. La instancia se crea obteniendo el 
            //tipo de objeto T del objeto list, que es el propio objeto que llama al método de extensión.
            //Es decir se infiere el tipo T y se instancia
            instance= Activator.CreateInstance(list.GetType().GetGenericArguments()[0]);
            
            //Se recorren todos los campos de cada fila del dataReader, y mediante
            //el objeto reflec (método del primer paso) rellenamos el objeto instance con los valores
            //del datareader
        foreach (DataRow drow in dr.GetSchemaTable().Rows){
                    reflec.FillObjectWithProperty(ref instance, drow.ItemArray[0].ToString(), dr[drow.ItemArray[0].ToString()]);
             }
            
            //Añadir objeto instance a la lista
            lstObj.Add(instance);
        }
       
        //Convertir la lista de objetos (lstObj) en la lista List<T> resultante(lstResult)
        List<T> lstResult = new List<T>();
        foreach (Object item in lstObj){
             lstResult.Add((T)Convert.ChangeType(item, typeof(T)));
        }


         return lstResult;
     }
 }


Paso 3. Llamar al método de extensión.
Dado un dataReader (dr)
 var listaTipoT= new List<T>();
 var listaResult = listaTipoT.CopyDataReader(dr).ToList();


Y ya tenemos un List T !!

viernes, 13 de septiembre de 2013

fechas y POO en Javascript

El siguiente ejemplo, trata sobre fechas y Programación orientada a objetos en Javascript.


El ejemplo expuesto, es una clase sencilla con funciones básicas de fecha que se pueden encontrar fácilmente en google, no obstante se exponen en una clase para usarlas cómodamente, y con el objetivo de explicar los conceptos básicos de POO en Javascript, aspecto poco utilizado en este lenguaje.



 
var fech = new classFecha(new Date());
console.log(fech.DiaLargo());

function classFecha(date) {
    var diasSem = new Array("Domingo", "Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sábado");

    var meses = new Array("Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre");


    this.DiaSemana = function () { return diasSem[date.getDay()]; }

    this.Mes = function () { return meses[date.getMonth()]; }

    this.DiaLargo = function () { return this.DiaSemana() + ", " + date.getDate() + " de " + this.Mes() + " de " + date.getFullYear(); }


    this.LunesSemana = function () {
        if (date.getDay() != 0)
            return (date.getDate() + (6 - (7 + (date.getDay() - 2))));
        else
            return (date(date.getDate() - 6));
    };
}

Bien, ahora vamos a comentarlo por partes, que hay mucho que comentar.

 ¿Que es function classFecha? Pués es la definición de una clase en Javascript, estás se definen como funciones.

 Diferencia entre variables definidas como var y this: las definidas como var son campos privados. Las definidas como this son propiedades o métodos públicos.

 Pero, ¿Propiedades o métodos?: Esto es otra cuestión, en general las propiedades, se definen como function, en ese caso siendo puristas son métodos/funciones públicos. Pero se pueden definir como propiedades puras de la siguente forma, por ejemplo:
 DiaSemana: En lugar de, 

this.DiaSemana = function () { return diasSem[date.getDay()]; }

 Codificaríamos,
          this.DiaSemana = (diasSem[date.getDay()]); 

 Y luego la llamaríamos así:  fech.DiaSemana
  En lugar de así: fech.DiaSemana()

 En la mayoría de ejemplos las propiedades son métodos definidas como funciones anónimas, es una costumbre en javascript debido a su sintaxis.


Todavía más cuestiones:

Los más puristas en POO se preguntarán,

¿Y porqué declara métodos de instancia si es una clase sin estados? Cierto, no se están utilizando estados, lo lógico desde un enfoque POO sería definir los métodos como estáticos.
Una razón es para que esté preparada para extenderse añadiéndole propiedades de estado.
Otra razón, y la principal,  es que no me gusta la sintaxis de los métodos estáticos en javascript.

Ese link la explica: http://mistrastadas.blogspot.com.es/2012/01/metodos-estaticos-en-javascript.html


Como podeis ver en el primer link, para definir un método estático hay que sacarlo fuera de la clase y añadirlo con la notación nombreClase.nombreFuncion=(...);  

El segundo link aún tiene otro tema, como añadir propiedades a un objeto en tiempo de ejecución con la clase prototype. No lo vuelvo a explicar pués ya está explicado en el link. En definitiva viene a ser un análogo a los métodos de extensión de C#, pués lo que se consigue así es extender la clase.

viernes, 6 de septiembre de 2013

Reflexión en C# : comparar campos de dos objetos utilizando LINQ


Un ejemplo de reflexión en C# utilizando LINQ. En el caso que se expone se crea la función fieldValuesDiff, que lo que hace es dados dos objetos, que pueden ser de distinto tipo, para todos aquellos campos con el mismo nombre y valor distinto, devuelve un IEnumerable<stObjDif>, es decir una lista de una estructura con el nombre del campo y los dos valores.

En particular yo lo he aplicado para hacer un log de campos modificados. Dados dos entitades de tipo A, le paso por parámetro una instancia de la entidad antes de modificar y otra modificada. Así puedo guardar el log.  

No obstante  se pueden añadir o cambiar fácilmente funciones basadas en esta, por ejemplo la función fieldsValuesEqual, para extraer campos iguales.

public class Reflection
{
    public struct stObjDif
    {
      public string Campo;
      public string ValorObj1;
      public string ValorObj2;
    }

    public List fieldsValuesDiff(object obj1, object obj2)
    {
      Type tOb1 = obj1.GetType();
      Type tOb2 = obj2.GetType();

      var listPropOrig = tOb1.GetProperties().Select(p => p).ToList();
      var listPropMod = tOb2.GetProperties().Select(p => p).ToList();

      return listPropMod.Where(pM =>
              listPropOrig.Count(pO => (pO.Name == pM.Name && pO.GetValue(obj1)!=null && pM.GetValue(obj2)!=null
                              && pO.GetValue(obj1).ToString() != pM.GetValue(obj2).ToString())) == 1
               ).Select(pResult => new stObjDif(){
                     Campo = pResult.Name,
                     ValorObj1 = pResult.GetValue(obj1).ToString(),
                     ValorObj2 = listPropMod.FirstOrDefault(pM => pM.Name == pResult.Name).GetValue(obj2).ToString()
                 }).ToList();
    }

domingo, 18 de agosto de 2013

Ejemplo MVC - Controladora base / Evento OnActionExecute

Para el inicio de la serie Ejemplos MVC vamos a ver sel siguiente ejemplo:

Crear una clase abstracta controladora y sobrescribir evento OnActionExecute
El ejemplo sirve para: 
  1. Tener Constructor/Objetos/propiedades/Dispose comunes para todos los controladores.
  2. Uso centralizado de sesiones y facilitar pruebas unitarias.
  3. Gestión de permisos.

Si heredamos las controladoras de la aplicación de una clase abstracta, podemos añadir objetos y/o propiedades comunes en el constructor. 

Primer paso. Clase abstracta básica de ejemplo

public abstract class ControllerBase:Controller
{
        protected IAplicacion oApp;
        protected BDEntities db = new BDEntities();

        public ControllerBase()
        {
        }

        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }
}

Con este código se consigue:
Tener objetos comunes compartidos por todos los controladores. En el ejemplo un objeto tipo IAplicacion y BDEntitie. Son dos ejemplos básicos, IAplicacion es un ejemplo tipo de una interfaz con un objeto/s básico/s necesario en toda nuestra aplicación: Usuario, Permisos, Breadcrumbs, etc... BDEntitie representa un objeto de Entity Framework, también muy común en todo controlador de cualquier aplicación que use Entity.
Tener un constructor común de inicialización, en este caso ControllerBase, que está vacio.
Destructor común que liberará los recursos.

Segundo paso. Sobrescribir evento OnActionExecute
Además, si sobrescribimos el evento OnActionExecute en la clase base, podemos tratar de forma centralizada el estado del contexto http, es decir principalmente las sesiones. Esto permite facilitar la gestión de las mismas al estar centralizado, y a la vez facilita las pruebas unitarias. El evento OnActionExecute, es un evento del contexto http, y no se ejecuta al realizar las pruebas, por tanto facilita tener que hacer mocking del contexto de la sesión, bastará con hacer mocking de la interfaz de aplicación IAplicacion para realizar las pruebas. 
No obstante, quiero aclarar que esta es una solución para centralizar el contexto http y evitar tener que simularlo en las pruebas, sin embargo también es posible hacer mocking de las sesiones, dejo un link de ejemplo. 

protected override void OnActionExecuting(ActionExecutingContext ctx)
{
   //En la pantalla de Login NO se comprueba estado sesión.
    if (ctx.ActionDescriptor.ControllerDescriptor.ControllerName == "Login") return;

   //Recoger variable de sesión objeto Aplicación.
   oApp = System.Web.HttpContext.Current.Session[Constantes.sesApp] as Aplicacion;

   //Chequear permisos (Se trata este tema en el siguiente Post)

   if (oApp.Permisos.TienePermiso){
    //Si tiene permisos sigue el flujo de ejecución
    base.OnActionExecuting(ctx);
    return;
   }

   //Si no tiene permisos se limpia la sesión
   System.Web.HttpContext.Current.Session.Clear();
   //Redirige a pantalla de Login
    ctx.Result = RedirectToAction("Index", "Login");
}

Tercer paso: Declarar todos los controladores como heredados de la clase ControllerBase.
                    Declarar constructor que recibe por parámetro la interfaz IAplicacion.
Se consiguen controladores limpios de variables de sesión, fáciles de testear simulando el estado del objeto oApp, simulando el objeto/estado deseado a través de la interfaz IAplicacion.
La clave está en que al ejecutar los controladores el estado del objeto oApp se recoge de sesión, y al realizar las pruebas se le pasa falsificado(mockeado) por parámetro al constructor. Al estar el tratamiento de la sesión en el evento OnActionExecuting, no se producirá ninguna excepción.

    public class HomeController : ControllerBase
    {
        public HomeController(IAplicacion aplicacion)
        {
            oApp = aplicacion;
        }

        public ActionResult Index()
        {
           //Tu Código que hace uso de un objeto oApp(de IAplicacion)
        }
    }




jueves, 15 de agosto de 2013

Serie de ejemplos MVC

Hola de nuevo,

A riesgo de repetirme, voy a iniciar una serie de ejemplos de MVC, en concreto versión 4, con C#, pues no solo de reflexiones vive el programador, también debe de trabajar. Como estoy con un nuevo proyecto con MVC 4, a medida que avance, me voy encontrando con numerosos problemas comunes, que soluciono en su mayoría googleando. No obstante no siempre hago un copiar/pegar, sino que en ocasiones añado mejoras a esas soluciones o las tomo como base para adaptarlas a mi escenario. Con esto quiero decir que no tengo la intención de publicar nada que sea un copiar/pegar de otra web; todo lo que publique tendrá un añadido o adaptación personal, con la intención de agregar valor.

Voy a empezar con los temas que citaré a continuación, aunque por supuesto tengo la intención de ir ampliando el número de temas a tratar. De momento expondré ejemplos de los problemas que he adaptado, sobre los problemas con los que aun no me he enfrentado ni aun se que existen, espero poder escribir pronto. Así que espero que la serie sea tan larga como sea posible, tanto como dure mi trabajo como programador MVC y tenga vida la aplicación, que según se dice, si es útil, ha de ser por un tiempo indefinido.

Temas a tratar en los siguientes Posts:

Controladoras. Crear una clase abstracta controladora y sobrescribir evento OnActionExecute. Ejemplo de aplicación uso de sesiones y permisos.

Patrón ViewModel: Aplicar patrón ViewModel. Crear una clase abstracta para todos los viewModels. Ejemplo de aplicación control básico de navegación.

Vistas modales. Como simular vistas modales típicas de aplicaciones Windows, equivalente a ShowDialog() de Winforms.


domingo, 11 de agosto de 2013

Antipatrones (o antimarranadas)

Patrones de diseño de Software hay y muchos, en el artículo de la wiki son todos los que están, pero no están todos los que son, la lista es en realidad mucho más larga.
Ya que estamos de Vacaciones, hay tiempo de ponerse filosófico, el post de hoy trata sobre antipatrones de diseño, y no sobre patrones. La reflexión que hago es que tan importante o más es saber como no se deben hacer las cosas, que saber un patrón en concreto. Por poner un ejemplo, con el patrón singleton podremos resolver un problema de sección crítica en un lenguaje orientado a objetos, pero también podremos resolverlo de otras formas en un lenguaje funcional. Es decir que un patrón es una solución a un problema, pero no la única.

Sin embargo si hay un consenso universal sobre los antipatrones, que traducido a lenguaje llano quiere decir "No hagas marranadas". Si entras en un nuevo proyecto que utiliza el patrón X podrás adaptarte a gusto, sin embargo si tienes el legado de un programa que hace uso de antipatrones vas a odiar al programador que lo hizo y las horas que pasas con el mismo; esto es algo que a muchos programadores nos ha pasado alguna vez, y creo que también coincidiremos en esta sensación.

Cito algunos de los antipatrones más comunes, con los que casi todos nos hemos topado:

Botón mágico   Incrustar la lógica de la aplicación en el clic de un botón. Un secreto inconfesable de la mayoría de los principiantes.

Código espagueti Otro secreto inconfesable de los principiantes. En los años 90, cuando aun no existian frameworks web, era algo inevitable.

Cadenas mágicas Cadenas de texto "inteligentes" que determinan el flujo del programa, definen sesiones etc. Es un pecado cometido incluso por los generadores de código, por ejemplo el propio visual studio 2012 lo hace con el scaffolding y con los links a las vistas. Esto puede dar lugar a muchos errores tontos por errores tipográficos. Deben substituirse por constantes.

Programación por excepción y Ocultación de errores   Programar la lógica a base de Try/Catch, y para asegurarse, en caso de que falle algo imprevisto, no mostrar ningún mensaje de error. Así el programador cree que se lava las manos.

DRY (Don't Repeat Yourself): Copiar/Pegar código en un programa. Muy típico.

Reinventar la rueda: Aveces a los programadores nos gusta más inventar nuevas soluciones a un problema, que buscar si ya existe una solución para ese problema. Terrible error muy antiproductivo.



viernes, 9 de agosto de 2013

GDSYCT - Desarrollo guiado para que se pueda probar

Hola de nuevo,

Esta semana he estado un día aplicando en mi nuevo proyecto los patrones de diseño y principios relacionados con las pruebas: DI, IoC, Mocking, pruebas unitarias, TDD.

Hoy en día están muy de moda, así que como no quiero quedarme chapado a la antigua, he decidido que como estoy empezando un proyecto nuevo en MVC, era un buen momento para ponerme con el tema. Aparte de estar muy de moda, me lo habían aconsejado (eufemismo de casi obligado).

Bueno, no voy a ser yo quien defina estos conceptos, para eso ya está la wikipedia y numerosos posts. Esto es literaturaprogramada, no un blog para repetir los que otros dicen. Tengo la intención de postear artículos técnicos, pero solo si aportan algo que no sea fácil de encontrar; no es este el caso. Espero encontrar una excusa pronto para hacerlo.

En conclusión, yo tenía una idea equivocada del concepto TDD (Definición Wikipedia) , que es el que engloba todos estos conceptos. Hacer pruebas me parece bien, pero no acababa de entender el orden propuesto pero esta práctica:
  1. Elegir un requisito
  2. Escribir una prueba
  3. Verificar que la prueba falla
  4. Escribir la implementación

Mi opinión era que, me parecía absurdo escribir la prueba(paso 2) y verificar que falla(paso 3), antes que escribir la implementación (4).  El caso es que como soy muy cabezota, me he empeñado en que este orden estaba mal planteado (aunque no he llegado a presentar una queja a la wikipedia), y he hecho el paso 4 antes que el 2 y el 3.

Con esta decisión me he generado un problema. En concreto estaba probando una acción simple de un controlador. La prueba fallaba, pero la razón no era la lógica de la función que quería probar. La lógica era correcta, pero el problema es que no se podía probar porque la función tenía dependencias vinculadas al contexto de la petición Http y a la sesión. Por tanto de ahí se concluye que ese código, aunque solo cumplía un objetivo, tenía dependencias acopladas nada deseables y que era conveniente desacoplar. 

Aunque la función en si misma era trivial, solo el hecho de utilizar TDD obliga a programar de forma desacoplada, siguiendo por tanto uno de los principios fundamentales de la ingenería: "Una cosa es una cosa, y otra cosa es otra cosa".

No me detendré en detallar el problema técnicamente, el objetivo del post es dar mi opinión favorable sobre el TDD. Es un placer dejaros el link de los dos posts que me han ayudado a aplicar esta técnica, a comprender mejor el TDD, y por tanto a programar mejor:

En resumen, que el TDD es una muy buena práctica, en mi opinión más que por ejecutar las pruebas unitarias (que también), porque obliga a programar bien para que estas se puedan realizar.

La confusión que me generó este concepto es solo por el nombre, creo que el nombre que propongo deja más claro el concepto, y puede ayudar a otra gente a no generarse el mismo prejuicio que yo me cree. El nombre es , GDSYCT, acrónimo de "Guided Development So You Can Try" , que según el traductor de google es la traducción al inglés de "Desarrollo guiado para que se pueda probar".

Para finalizar remarco que el objetivo es programar mejor, no garantizar que el programa no vaya a tener errores, por supuesto. Seamos honestos, dentro de unos límites razonables, por nuestro bien, es deseable que un programa pueda fallar, para que el cliente/empleador necesite de nuestros servicios.

Hasta otra.


sábado, 27 de julio de 2013

Delegados o criptografía

Delegados ¿¿¿¿???

Es curioso lo criptográficas que llegan a ser la explicación de algunos conceptos, por ejemplo el concepto de delegado, que está vinculado al de evento. Si buscas información encontraras una y otra vez las siguientes descripciones "firma de un evento", "puntero a una función", y ponen ejemplos que no se entienden un carajo, están escritos para listos, de hecho muchas veces parece que esté escrito a propósito para que no se entienda y así le da más glamour al concepto.

Microsoft no es una excepción en este caso, en realidad la msdn muchas veces deja que desear, dando explicaciones muy teóricas pero sin exponer ejemplos claros (http://msdn.microsoft.com/es-es/library/system.delegate(v=vs.80).aspx) , ves el ejemplo y piensas, "pero que carajos están haciendo...", al final lo que se acaba interpretando (al menos los normalitos) es que para llamar a una función se están complicando la vida, para hacer una analogía da a entender que si un tío que está en Pamplona tiene sed, se va a San Sebastián y pide agua.

Después lees muchos otros post donde remarcan "firma del evento...el controlador de evento clic responde a la firma del delegado de un evento..." y otras frases tecnicistas que no explican nada.

Pués bien, al final si ves el vídeo del link que dejo a continuación, sí que se entiende. La explicación más apropiada, comprensible y fácil para un delegado que se me ocurre es que en el contexto de ejecución de dos objetos (por ejemplo dos formularios winforms) y también por ejemplo en el contexto de los threads, con los delegados se consigue COMUNICACIÓN entre los mismo.

En el video se ve claro que dado dos forms (form1 y form2) el form2 podrá enviarle notificaciones al form2 pasándole argumentos, es decir que form2 puede llamar a funciones de form1 aunque ni siquera sepa que existe. Esto es aplicable a N forms o Threads.

Ahí va el link http://www.youtube.com/watch?v=gRSc6PPNjvk

Hasta otra

miércoles, 17 de julio de 2013

Katas

Las Katas en programación son ejercicios "simples" y fascinantes para practicar determinados aspectos de la programación. Sirven para practicar algorítmica, probar nuevas funcionalidades de un lenguaje, comparar eficiencia de algoritmos, y además también son un buen ejercicio para empezar a familiarizarse con el TDD.

Hay varias Webs donde se proponen numeros Katas muy divertidos y "fáciles", para todos los  lenguajes. Aquí dejo el link de Solveet , Web con muchos Katas propuestos para muchos lenguajes, hay muchos desafíos con las soluciones de varios programadores, te puedes picar con ellos y comparar soluciones, incluso puedes publicar tu propio desafío. Hay ejemplos incluso de un lenguaje que se llama Ruby, por tanto le gustará a un buen amigo mio.

Katas típicos pueden ser por ejemplo cálculo factorial, fibonacci, números primos, etc...

También es divertido inventarse uno propio, yo me propuse el siguiente Kata:

1. Función calculo Número primo clásico
2. Función cálculo número primo con LINQ usando expresiones Lambda.
3. Función cálculo número primo con solución 2 recursiva.

Cosa que me ha permitido practicar las expresiones Lambda, y no solo eso, además ha permitido comprobar la eficiencia de LINQ. A través de las pruebas unitarias se ha comprobado que las solución 2 y 3  con expresiones Lamda, son con mucha diferencia mucho más efectiva que la primera. La solución 3 es ligeramente más efectiva que la 2.

Pego a continuación una foto con las 3 funciones.



martes, 16 de julio de 2013

Body Shoppers

Continuando con mis historias de búsqueda de trabajo, merece un artículo aparte el tema de los "Body Shoppers"

Me hizo gracia la primera vez que escuche este adjetivo para referirse a las consultoras que contratan trabajadores para hacer outsourcing. Literalmente lo traduciría como "Tiendas de carne a medida", el nombre encaja como un guante, la experiencia que yo tuve en mi búsqueda es que puedes optar a un puñado o dos de "Body Shoppers" a la semana, pero si no estas cortado a medida no tienes nada que hacer, es decir, ejemplo, la oferta viene a decir, se busca programador con:
1 año experiencia MVC 4
2 años de experiencia de JQuery
etc...

Y si tú no estas cortado a medida, no tienes nada que hacer, da igual que tengas 3 años de experiencia en MVC 3, o que tengas año y medio de experiencia en JQuery, o cumples los requisitos al milimetro o olvidate de inscribirte a la oferta, no tienes nada que hacer.

Así que si quieres trabajar en una "Body Shopper" necesitarás mucha experiencia en muchas tecnologías, así quizas encajes en alguna :-)

Aquí acaban mis reflexiones sobre búsqueda de trabajo, no había dicho que yo lo encontré en una body shopper para un proyecto en WinForms.

Hasta otro día.

domingo, 14 de julio de 2013

Entrevistas de trabajo para AP .NET

¿Estáis buscando trabajo como AP .NET? Cómo yo ya lo he encontrado voy a compartir mis experiencias y consejo con vosotros, para echaros una ayuda, ya que ahora mismo no sois competencia ;)

 Bueno, pues resulta, que por allá por mediados de 2013, me cansé de ser autónomo - o quizás la crisis me obligó a cansarme - y me puse a buscar trabajo, llevaba unos 6 años sin ir a una entrevista de trabajo; hasta el momento siempre que había buscado trabajo en mi tierra de adopción, Castellón, lo había encontrado muy rápido, unas dos semanas, y sin demasiada dificultad, 2 o 3 entrevistas. No era consciente de que el escenario había cambiado totalmente, menos ofertas y mucha más gente preparada sin trabajo, por tanto muchísima más competencia. Me encontré con unos procesos de selección mucho más complejos y largos que os resumo a continuación.

Mi primer golpe en la frente fue cuando fui a infojobs y filtre búsqueda de empleo por Castellón/Informática, esperaba encontrarme unas 10 ofertas para apuntarme, jaja ni una sola, totalmente vacío. Acto seguido cambié la provincia por Valencia y tampoco había mucho, sí de informática en general, pero muy poco de mi especialidad en concreto .NET, así que me hice la idea de que tendría que hacer las maletas, y empece a buscar en Barcelona, donde sí que había muchas ofertas.

 En mis primeras entrevistas, lo más divertido fue encontrarme con unos psicotécnicos muy divertidos, me pidieron dibujar un árbol, escribir un cuento, me preguntaron que pensaba de las mujeres modernas, que envidiaba de algunos hombres, jeje las respuestas estan protegidas por la LOPD y no os las contaré, os compartiré esta, jeje:
Pregunta: Los hombres de mi edad....
Respuesta: tienen 35 años.

 Ya entrando en aspectos más técnicos os comparto todo lo que me han preguntado y hay que saber para poder pasar las entrevistas. Comentar que todo esto se centra en entrevistas para puesto de AP .NET en consultoras.

 Inglés. Pero de verdad, no ese nivel "medio" del "from lost to the river" que pone todo el mundo el el CV sin soltar palabra
 Hay que saber hablar con fluidez, ya que las consultoras, al no haber pan en España, lo buscan en Europa. Si sabes además Francés y/o Aleman es un plus.

 En todas las entrevistas os preguntarán sobre:

Metodologías ágiles, Scrum, TDD, ORM, SOLID, LINQ , patrones de diseño, y arquitectura.

En muchas os harán un examen test donde os pueden preguntar por muchas cosas relacionadas con la Ingeniería del Software:
  Singleton (Que no soltero), Patron observer, decorator.
  Pruebas unitarias, Mocking (Buscar en la wiki, no quiere decir mocoso ;), stub, pruebas de stress
  SOLID. Dependency Inyection, etc...
Y por supuesto, cualquier cosa directamente relacionada con el framework .NET, POO y C#

En algunas os harán pasar un examen práctico.

O sea que no solo hay que saber programar sino que también hay que estar documentado y mostrar interés por la Ingeniería del Software.

En muchas os preguntaran si tenéis hijos, si estáis casados etc etc... cosa que no juega mucho en vuestro favor. En principio todas estas preguntas se consideran discriminatorias según las buenas normas, como también lo es la foto en el CV, que no debería estar; pero la realidad es bien distinta.

Por hoy, esto es todo, otro día hablaré de los Body Shoppers...

Bienvenidos

Hola y bienvenidos, Soy Jaume González, programador informático apasionado del mundo .NET, la Ingeniería del Software, y la programación en general.

Os presento literatura programada, un blog para escribir sobre Ingeniería del Software y programación, especialmente del mundo .NET, aunque también se aceptan reflexiones pyThonianas y Javeras, las de PHPeros me lo pensaré :-). Se trata de un blog en el que hablaré temas técnicos sobre mi experiencia en el mundo de la programación, intentando ser ameno, exponiendo temas técnicos con un lenguaje llano y ameno. Estáis invitados