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).

Agregar cabeceras SOAP entre mensajes

Para enviar informacion adicional al mensaje enviado entre servicios web existe una tecnica muy elegante que vale la pena mencionar;  esta tecnica consiste en enviar datos adicionales entre mensajes.  Para poder llevarlo es necesario que los datos a enviar sean enviados mediante una clase que herede de SoapHeader que se encuentra en System.Web.Services.Protocols, exponiendo sus metodos como publicos. Para completar la definicion del servicio web hay que agregar algun objeto en el servicio que la cabecera y ademas del atributo WebMethod es necesario agregar SoapHeader y como parametro del constructor del atributo el nombre del objeto que hereda de SoapHeader.

Ahora por la parte del cliente es muy sencillo pues el wsdl.exe expone la clase que hereda de SoapHeader entonces solo es necesario crear un objeto y configurar los miembros de la misma.

Reflexión

Los problemas siempre seran tan complejos como quieras verlos, aunque sus soluciones siempre resulten sencillas

Envio de correos mediante un servidor SMTP

Antes que nada hay que saber que version del framework se esta utilizando, la clase MailMessage ha sido considerada obsoleta y migrada para nuevas versiones, si se utilizan vesiones 1.x sera necesario utilizar el namespace System.Web.Mail y los valores del destinatario, remitente, asunto y cuerpo del mensaje seran configurados mediante sus propiedades, en cambio si se usan versiones 2.0 o posteriores la clase se localiza en el namespace System.Net.Mail y los valores antes mencionados seran configurados en el constructor de la clase.

Ahora pasando a la forma en la que este mensaje sera enviado por nuestro servidor que nuestro caso lo enviaremos mediante un servidor smtp, tendremos en mismo problema, para versiones 1.x se usara el namespace mencionado y la clase que se utilizara sera SmtpMail y para configurar el host de la clase lo haremos mediante la propiedad SmtpServer,  para las versiones actuales sera mediante la clase SmtpClient ubicada en el namespace mencionado y el host sera configurado mediante el constructor.  Cabe mencionar que es recomendable usar un canal seguro lo cual podemos configurarlo mediante la propiedad EnableSsl, y por supuesto enviarle las credenciales del usuario remitente asignado una instancia de System.Net.NetworkCredential en la propiedad Credentials de la clase.

Por ultimo, ambas clases contienen un metodo Send en el cual se le pasa como parametro el mensaje a enviar.

Conceptos basicos acerca de .Net Remoting

Tratare de englobar a grandes razgos lo que he captado acerca de este tema.  Para mi .Net remoting implica conocer tecnologias cliente-servidor, donde el servidor ofrece la creacion de objetos que pueden ser referenciados o serializados por los clientes.

Comencemos con el diseño de las clases que queremos exponer, para comenzar tenemos que elegir entre si el objeto sera serializado y enviado al cliente o simplemente se enviara la referencia del objeto en el servidor, en caso de ser el primer caso debemos implementar la interfaz ISerializable o el atributo Serializable y tener el cuidado de que los miembros de la clase sean serializables o que hereden de la clase System.MarshalByRefObject, para el segundo caso solo sera necesario heredar de System.MarshalByRefObject.

Una vez definido este punto sera necesario definir la forma en la que seran activados estos objetos, activados por el servidor y activados por el cliente.

Para ser activados por el cliente solo es necesario definirlo por el metodo estatico  RegisterActivatedClientType() de la clase RemotingConfiguration del espacio de nombres System.Runtime.Remoting, quizas los escenarios en los que recomiendan este tipo de activacion son en los que necesitemos que los objetos sean manejados en un diferente dominio de la aplicacion.

La activacion por parte del servidor es muy similar a los servicios web, para este tipo de activacion existen dos formas distintas de administrar las instancias: Singleton y Single Call.

Por singleton el servidor mantiene solo un objeto creado que atiende a las llamadas de los clientes, puede ser util cuando querramos compartir informacion o estados entre clientes.  La forma de hacerlo es usando el metodo estatico RegisterWellKnownServiceType de la clase  RemotingConfiguration del espacio de nombres System.Runtime.Remoting y en el segundo parametro definir con el enumerador WellKnownObjectMode.Singleton.

Para las activaciones por servidor de Single Call donde querremos que cada cliente tenga un objeto nuevo, utilizaremos el mismo metodo que Singleton pero con la diferencia de que usaremos el enumerador WellKnownObjectMode.SingleCall .