ComboBox con checkboxes como items usando XAML

Me parececio bastante sencillo la forma de crear un nuevo control utilizando XAML, en este caso necesitaba una especie de filtro en el cual se pudieran agregar de una lista de opciones, varias. Aunque existe algun otro control que lo permite, me parecio bastante elegante utilizar un ComboBox que permitiera seleccionar varias opciones.

El resultado que se obtiene es como el siguiente:

Para lo cual necesitaremos agregar en nuestro archivo con extension *.xaml el siguiente codigo

        
            
                
                    
                        
                    
                
            
        

y para el control de los eventos, ya sea con C# o VB .Net el siguiente codigo.

VB .Net

Private Sub chk_Checked(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
   ' TODO : Agregar el codigo para el manejo del evento
End Sub

Private Sub chk_Unchecked(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
   ' TODO : Agregar el codigo para el manejo del evento
End Sub

C#

        private void chk_Checked(object sender, RoutedEventArgs e)
        {
            // TODO : Agregar el codigo para el manejo del evento
        }

        private void chk_Unchecked(object sender, RoutedEventArgs e)
        {
            // TODO : Agregar el codigo para el manejo del evento
        }

Personalizacion de mensajes de error para JSF

En ocasiones es necesario personalizar los mensajes de error estándar que son mostrados en el cliente, estos mensajes pueden tener un formato comenzando con un prefijo de código de error seguidos por el código del mismo, y por ultimo una descripción del mensaje de error como puede ser algo como lo siguiente:

Validation Error: Value is greater than allowable maximum…

Para poder personalizar dicho mensaje, se necesitan dos cosas, la primera es necesario agregar la ruta del archivo de propiedades que sobreescribira los mensajes estándar, esto se define como un «message-bundle» en el archivo de configuracion de faces-config.xml (el nombre del archivo depende del sistema)

messages

y segundo, como es de suponerse, crear el archivo de propiedades con la ruta que especificamos agregando los valores que sobrescribiremos.

messages.properties

javax.faces.converter.IntegerConverter.INTEGER=Requiere un valor de tipo numerico

En esta pagina puedes encontrar todos los valores posibles para las claves de los mensajes estándar.

Modificadores de acceso – Default

El siguiente modificador de acceso sera Default, algo enredoso, pero muy valioso de tener en cuenta.

Como veremos a continuacion este modificador va de la mano con el paquete al cual pertenece la clase.

Escenario – Declaracion en la clase

  1. Pueden existir un sin fin de clases con el declarador de acceso por defecto pero solo una puede existir una clase publica
  2. ClasePublica.java

    package mipaquete;
    
    public class ClasePublica{
    }
    
    class OtraClase{
    }
    
    class OtraClaseNoPublica{
    }
  3. Puede referenciarse desde clases dentro mismo paquete
  4. OtraClasePublica.java

    package mipaquete;
    
    public class OtraClasePublica {
    	public void invocar(){
    		OtraClase clase = new OtraClase();
    	}
    }
  5. Puede heredarse por clases dentro mismo paquete
  6. ClaseHijaPublica.java

    package mipaquete;
    
    public class ClaseHijaPublica extends OtraClase{
    
    }
  7. No puede referenciarse desde clases de distintos paquetes.
  8. OtraClasePublica.java

    package otropaquete;
    
    import mipaquete.ClasePublica;
    
    public class OtraClasePublica {
    	public void invocar(){
    		OtraClase clase = new OtraClase();
    	}
    }

    OtraClasePublica.java:3: mipaquete.OtraClase is not public in mipaquete; cannot
    be accessed from outside package

  9. No puede heredarse por clases de distintos paquetes.
  10. ClaseHijaPublica.java

    package otropaquete;
    
    import mipaquete.OtraClase;
    
    public class ClaseHijaPublica extends OtraClase{
    }
    }

    ClaseHijaPublica.java:3: mipaquete.OtraClase is not public in mipaquete; cannot
    be accessed from outside package

Como resumen cuando omitamos el operador, y sea aplicado el operador por defecto tendremos que siempre mirar al paquete que pertenece la clase.

Modificadores de acceso – Public

Este sera el comienzo de una serie de posts en los cuales tratare de profundizar en el tema, tratando de abarcar la mayoria de los escenarios posibles.

Comenzare con el modificador de acceso Publico, que por ser menor restrictivo puede ser considerado facil de comprender.

Escenario – Declaracion en la clase

  1. Solo puede existir una clase publica por archivo *.java
  2. ClasePublica.java

    package mipaquete;
    
    public class ClasePublica{
    }
    
    class OtraClase{
    }
    
    class OtraClaseNoPublica{
    }
  3. Puede referenciarse desde clases dentro mismo paquete
  4. OtraClasePublica.java

    package mipaquete;
    
    public class OtraClasePublica {
    	public void invocar(){
    		ClasePublica clase = new ClasePublica();
    	}
    }
  5. Puede heredarse por clases dentro mismo paquete
  6. ClaseHijaPublica.java

    package mipaquete;
    
    public class ClaseHijaPublica extends ClasePublica {
    
    }
  7. Puede referenciarse desde clases de distintos paquetes siempre y cuando la clase sea importada
  8. OtraClasePublica.java

    package otropaquete;
    
    import mipaquete.ClasePublica;
    
    public class OtraClasePublica {
    	public void invocar(){
    		ClasePublica clase = new ClasePublica();
    	}
    }
  9. Puede heredarse por clases de distintos paquetes siempre y cuando la clase sea importada
  10. ClaseHijaPublica.java

    package otropaquete;
    
    import mipaquete.ClasePublica;
    
    public class ClaseHijaPublica{
    	public void invocar(){
    		ClasePublica clase = new ClasePublica();
    	}
    }

Con esto creo cubrir la mayoria de las preguntas que pudiesen surgir acerca de este modificador

java.lang.OutOfMemoryError‏

Hace tiempo me tope que esta excepcion y buscando en varios foros sugerian la ejecucion de las clases enviandoles parametros especiales( java -Xmx[memoria]) ya que la maquina virtual de java utiliza 100 Mb para la ejecucion de clases.

Nunca me parecio razonable la solucion, por dos razones la primera, la arquitectura debe de ser dirigida a aprovechar los recursos del sistema, no a malgastarlos;  la segunda, al ser un equipo de desarrollo esta solucion no podria ser aceptable.

Mi solucion:  Subir un servlet que como primera instruccion llamara al recolector de basura

System.gc();

Con esto parece ser que libero la memoria necesaria para que el web server en mi caso iPlanet, respondiera.

System.Attribute vs java.lang.annotation.Annotation

Siempre es necesario contar con informacion adicional sin ser mezclada con las reglas de negocio, esta informacion puede tener distintos propositos, ya sean reglas impuestas por la organizacion o informacion necesaria pero sin afectar las reglas de negocio.

En este post no prentendo crear un debate sobre las distintas tecnologias, mi opinion es neutral y creo que ambas son fabulosas aplicadas correctamente.

En cuanto a esta informacion adicional, ya sean metadatos o atributos, si bien para .Net esta tecnologia lleva varias versiones presente para Java es incoorporada a partir de su version 5.

Para mostrar las diferencias en implementacion entre ambos mostrare un ejemplo que permita agregar datos de autor y version en las clases y metodos declarados. Por cuestiones de antigüedad comenzare con .Net.

[System.AttributeUsage(System.AttributeTargets.Class |
                       System.AttributeTargets.Struct,
                       AllowMultiple = true)]
public class Author : System.Attribute
{
    private string name;
    public double version;
    public Author(string name)
    {
        this.name = name;
        version = 1.0;
    }
}

La explicacion es sencilla, se hereda de la clase Attribute, se pueden agregar atributos a esta clase como pueden ser si la clase es serializable, si es visible en un componente COM, que alcance tiene la clase que en nuestro ejemplo solamente tiene aplicacion en clases y metodos, a continuacion agrego otra clase la cual utilizaria este atributo.

[Author("H. Ackerman", version = 1.1)]
[Author("M. Knott", version = 1.2)]
class SampleClass
{
    // H. Ackerman's code goes here...
    // M. Knott's code goes here...
}

Estos ejemplos fueron tomados de la pagina de msdn

Ahora metadatos con Java

import java.lang.annotation.*;

@Retention(RetentionPolicy.SOURCE)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface Author{
    String name();
    double version() default 1.0;
}

Segun se en java no se permite repetir las anotaciones, por lo que veo una desventaja en su contra, a continuacion el ejemplo. En cuanto a su explicacion, segun he visto se crea a partir de una clase generica, aun cuando esta es una interface, y sus miembros parecen ser funciones.

@Author(name ="H. Ackerman", version = 1.1)
class SampleClass
{
    // H. Ackerman's code goes here...
}


Spring .Net

¿Y porque en .Net no? Los buenos frameworks son para compartirse.

Primero, analicemos un poco de que trata dicho framework y que ventajas nos puede traer para nuestros desarrollos. Comencemos con un poco de historia de los problemas con los cuales nos hemos enfrentado despues de varios cientos de miles de lineas de codigo. Recordemos que las buenas practicas de programacion fueron trasmitidas con base en la experiencia, y su fin es adaptarnos mejor a los cambios, cambios que cada vez son mas continuos y exigentes o caprichosos y cuando una aplicacion llega a ser lo bastante grande y dichas modificaciones pueden llegar a ser grandes dolores de cabeza.

Es aqui cuando entra en juego dos palabras clave desacoplar y centralizar, si buscamos que nuestro codigo se mantenga centralizado y desacoplado o desarticulado, es decir, que este no mantenga fuertes dependecias entre si(hablando de librerias, tecnologias, base de datos, etc.), lograremos que las modificaciones solicitadas podamos realizarlas de manera rapida y confiable.

Y para que volver a inventar la rueda, aqui es donde entra en juego Spring .Net al basarse, en tecnologias maduras y probadas por desarrolladores Java. Dicho framework nos facilita la tarea de centralizar y desacoplar nuestro codigo, apoyandonos de archivos de configuracion. Creo que habra que poner especial atencion, por mencionar unos cuantos, a los provedores de informacion ya que estos suelen cambiar.

Por ultimo, hace falta agregar dos definiciones importantes en este tema, el primero es Inversion of Control(IoC) el cual, implementando en una aplicacion, permite el control configurable del flujo del programa.  El segundo y no menos importante es Dependency Injection(DI), permitiendo el acoplamiento de clases de manera modificable o configurable, en el caso de Spring .Net, se localiza en un archivo xml.

Desarrollo guiado por pruebas

Hace tiempo que no posteo algo y que mejor que regresar con una buena metodologia. Se trata de Test-driven development (TDD) una metodologia agil que se enfoca a satisfacer los casos de prueba del cliente dejando en segundo plano el un profundo diseño y analisis, pero reforzando el vinculo entre desarrollo y pruebas, al estilo de Code and fix V.2.

Los pasos de realizacion de dicha tecnica son sencillos e iterativos.

1. Consiste en identificar claramente los casos de prueba.

2. Mas tarde, se implementan los casos de prueba, al no existir aplicacion o codigo previo dichos casos de prueba fallaran lo cual es el objetivo. Para este punto y verificar de manera adecuada que los casos de prueba fallen, nos apoyamos de herramientas de casos de prueba unitaria como son NUnit (en el caso de .Net) y JUnit (para Java), aunque NUnit se basa en JUnit las diferencias entre ambos puden ser abismales. Al carecer java de atributos en el lenguaje es necesario seguir un estandar para la implementacion de casos de prueba; por otro lado cuenta con un gran soporte dentro de sus IDE para dicho framework.

3. Despues, se implementa el codigo para que dichos casos de prueba sean superados, con lo cual nos apoyaremos de dichas herramientas para lograr nuestro objetivo.

4. Por ultimo, se refactorizara y buscara el performance de nuestro codigo, y se generaran nuevos casos de prueba iterando asi, dicho ciclo.

Dicha metodologia me parecio bastante util en el diseño de librerias y frameworks, aunque apenas voy conociendo su potencial me agrada la idea de no borrar codigo, ni hacer mezclas extrañas, y por supuesto, realizar las pruebas primero. Considero valioso la incorporación de dicha tecnia en futuros proyectos.

Analisis de proceso de construcción de instancias

Creo que este proceso es muy poco conocido a detalle por lo que creo que vale la pena tenerlo presente.

Cuando se crea una instancia de una clase lo primero que se hace inicializar los miembros estaticos de la clase, por lo tanto antes de una construccion  ya existen sus mimbros y funciones para mas tarde se inicialicen los miembros de instancia asignando los valores por defecto de los mismos, mas tarde y en el caso de que estas tengan en su declaracion un valor asignado el CLR asigna estos valores, despues de esto pasa a la llamada del constructor llamando, sea el caso, implicitamente al constructor sin parametros de la clase base o explicitamente al constructor deseado.  Generalmente este proceso es poco conocido debido a que la mayoria de las clases heredan implicitamente de System.Object el cual tiene un constructor sin parametros.

Los problemas comienzan cuando se hereda de una clase que se define un constructor con parametros, provocando que el compilador no tenga la necesidad de crear uno sin parametros;  y por lo tanto al heredar de esta clase sea necesario definir explicitamente que se usara el constructor definido.

Constructores estaticos

Leyendo sobre este tema me puso a pensar que vale la pena escribir un post para tener presente esta posibilidad muy poco conocida y usada. Resulta ser que al igual que tenemos constructores de instancias, existen constructores estaticos que inicializan las variables estaticas, su sintaxis como es de esperarse inicia con la palabra static y el nombre de la clase, solo es posible crear un solo constructor estatico debido a que este no es llamado explicitamente. Pensando en los escenarios en que se podria utilizar son muy limitados, quizas solo en los cuales forzosamente necesitemos un estado inicial de sus miembros estaticos.

Por ultimo hay que remarcar las consecuencias del uso de estos constructores estaticos, reduce velocidad debido a que el CLR no puede asignar memoria a los miembros estaticos cuando crea conveniente, existe un ligero cambio en la cabecera de la clase en el codigo intermedio(beforefieldinit).