Dios no juega a los dados
Albert Einstein

Archivos en la categoría Software

Patrones de Diseño - Singleton

El Patrón de Diseño Singleton (en español, Instancia Única) se utiliza para garantizar que una clase sólo tenga una única instancia y para facilitar un punto de acceso global a la misma.

Se utiliza cuando se necesita :

  • que sea un único objeto el que coordine acciones a lo largo de todo el sistema
  • que el objeto posea estado
  • variables globales en el sistema (es más limpio y eficiente utilizar Singleton)

La propia clase es única responsable de crear la única instancia (ocultando al constructor) y de facilitar el acceso global a la instancia. Un ejemplo de implementación en Java :

public class Singleton {

      //Instancia como variable estática

    private static Singleton instanciaUnica;

    //Constructor privado : no se puede acceder desde fuera

    private Singleton() {}

    //Método para obetener una instancia

    public static Singleton getInstancia() {

      synchronized(Singleton.class) {

              if (instanciaUnica == null) {

                  instanciaUnica = new Singleton();

              }

      }

      return instanciaUnica;

    }

}

Es delicado en sistemas multihilo, ya que si dos hilos de ejecución intentarán crear una instancia al mismo tiempo y ésta no existiese todavía, sólo uno de los dos debería de lograrlo. La solución clásica para este problema es utilizar exclusión mutua en el método de creación de la clase que implementa el patrón.

En algunas ocasiones se aplica este patrón de una forma menos restrictiva, permitiendo que exista un número máximo de instancias en lugar de una única.

Cómo hacerse rico

El azar o el destino me han llevado al blog de Mark Cuban, propietario de los Dallas Mavericks (una franquicia de la NBA). Y releyendo sus entradas encontré ésta entrada en la que explica cómo hacerse rico.

Yo no aspiro a ser rico sino a ser feliz (curiosamente cuando he sido más feliz ha sido cuando no tenía dinero), y esta no es la temática de esta bitácora, pero en estos tiempos de crisis deberíamos de recordar cuatro cosillas :

No hay atajos

Si alguien es tan listo y tiene una fórmula mágica (una inversión garantizada de alta rentabilidad sin ningún riesgo) nadie la va a compartir contigo, la utilizará él mismo.

Ahorra dinero

Ahorra cada céntimo que puedas, aplicándote disciplina para comprar lo que necesites de una forma inteligente y no utilizar tarjeta de crédito. Todo lo que ahorres lo puedes poner a depósitos de 6 meses.

If you use a credit card, you dont want to be rich

Esto te permitirá disponer de efectivo disponible para cuando lo necesites.

Aprende

Invertir tiempo en tí es la mejor inversión, aprendiendo un negocio que realmente te guste consiguiendo un trabajo en él (desde un curso o máster pagas por aprender; trabajando te pagan por aprender), no importa en que escalón : como dependiente, comercial … Aprende todo lo que puedas del negocio, leyendo, asistiendo a actos, hablando con la gente…

Espera tu oportunidad

La oportunidad llegará, tardará años, o décadas, todos los negocios son cíclicos con sus tiempos de expansión y contracción.

Estarás listo entonces ?

Patrones de Diseño - Façade

El Patrón de Diseño Façade (o Facade, o en español Fachada) es en mi opinión uno de los más básicos y simples, que todos hemos implementado alguna vez aún sin conocerlo.

Una fachada no se trata más que de un objeto que ofrezca una sencilla interfaz que ocultará uno o varios sistemas más complejos y sus interacciones.

Con este patrón ofrecemos un acceso sencillo y desacoplamos al máximo nuestro sistema cliente (el que accede a la fachada) de los sistemas ocultos.

Típicamente se utiliza en librerías o en sistemas diseñados en capas. Desde luego si estás construyendo un sistema que van a utilizar otros 20 sistemas de tu empresa, implementa una fachada.

Algunas ventajas que disfrutaremos en el propio desarrollo son :

  • Facilitamos la utilización y comprensión (acompañando la interfaz con una documentación mínima) de los sistemas ocultados
  • Los clientes se olvidan de toda la complejidad del negocio, sólo les importa los resultados obtenidos.

Y a la larga, el mantenimiento será más fácil

  • En los clientes reducimos las dependencias del código externo.
  • Aislamos a los clientes de cambios sustanciales en los sistemas ocultos, ya sea un cambio de requisitos, de diseño de base de datos, de tecnología utilizada…
  • Hace el código cliente más legible

Este patrón de diseño se puede implementar como una interfaz o como una clase abstracta, sin detallar los detalles de implementación (es justo lo que queremos ocultar).

Es habitual que se implemente la fachada utilizando también el patrón Singleton (sólo se necesita una fachada).

Como vemos es un patrón de diseño muy simple e intuitivo, que nace del sentido común y experiencia. Los beneficios que nos ofrece son enormes en comparación con su coste de implementación.

Pero ojo, su no utilización nos provocará enormes problemas tanto a la hora de desarrollar como sobre todo en el mantenimiento. Podemos ver algo parecido a lo que te sucederá si no lo utilizas en la viñeta siguiente… Así que no te dejes de utilizarlo !

Manejo de Excepciones y Errores en una arquitectura Java

Podemos considerar que una Excepción en programación es una situación poco habitual que provoca resultados inesperados o incoherentes en nuestros métodos, pero que es contemplada en el análisis, diseño y construcción de nuestro sistema : el sistema se puede recuperar de estas situaciones.

Como ejemplos podemos citar envíos duplicados de información, una caída de nuestra base de datos, información inválida o incosistente como un número de teléfono con un formato incorrecto…

Para mantener códigos robustos que manejen estas situaciones, los lenguajes de programación incorporan mecanismos para el manejo de excepciones como parte de sus estructuras de control.

Y las situaciones poco habituales que provocan resultados inesperados o incoherentes y que no controlamos ? Eso es un error en tiempo de ejecución en nuestro sistema, que puede desembocar en una inconsistencia de datos en nuestra base de datos o en la finalización inesperada de nuestro sistema.

Un buen indicador de la calidad de un sistema software es comprobar cómo responde cuando se producen fallos, ya sean esperados y controlados (excepciones) o inesperados e incontrolados (errores).

Excepciones en Java

En el caso de Java se utilizan bloques try - catch - finally, throw y throws, y las subclases de java.lang.Exception. Un método lanzarán (mediante un throw) una excepción (una clase que hereda java.lang.Exception) provocando que se abandone el flujo de ejecución normal y cediendo el control al bloque en el que se capturará (en un bloque try - catch - finally). En la declaración del método se incluye throws para avisar de que puede lanzar una excepción.

Existen muchas excepciones predefinidas en Java, pero también nosotros podemos crear excepciones particulares a nuestros sistemas : basta crear una clase que extienda de java.lang.Exception.

Existen dos grandes tipos de excepciones en Java :

  • Checked Exceptions (excepciones controladas). Se corresponden a errores previstos, controlados en el codigo y por tanto permite al sistema recuperarse. Son lo que hemos definido anteriormente como excepciones. El compilador Java es una gran ayuda ya que te obliga a capturarlas en un bloque try - catch - finally o a declarar que el método puede devolver una excepción (declarando un throws).
  • Unchecked Exceptions (excepciones no controladas). Son excepciones no previstas ni controladas, y por tanto puede provocar inconsistencia de datos y la finalización inesperada del sistema : lo que hemos definido anteriormente como errores en tiempo de ejecución. En Java se implementan como subclases de java.lang.RuntimeException (que a su vez hereda de java.lang.Exception) y el compilador no nos obliga a capturarlas ni a declarar que nuestros métodos pueden lanzarlas. NullPointerException o IllegalArgumentException son dos ejemplos de estas excepciones.

No olvides utilizar la parte finally de los bloques try - catch - finally para liberar recursos como conexiones o archivos.

Manejo de Excepciones en una arquitectura Java

Al invocar un método deberíamos obtener como resultado o bien el resultado normal de la ejecución o bien no hacer absolutamente nada. Las excepciones nos servirán para comunicar a las capas superiores información sobre por qué no se ha hecho nada si fuese necesario.

La utilización de bloques try - catch - finally es más costoso en términos de tiempo de ejecución y recursos que la utilización de bloques if - else.

  • Por tanto es recomendable utilizar excepciones para controlar el flujo, es mejor utilizar los mecanismos de control de flujo ya existentes que consumen menos y son más fácilmente mantenibles.
  • Tampoco es recomendable capturar una excepción en un bloque catch y no hacer nada, o no hacer nada más que lanzarla nuevamente.

Es aconsejable que las excepciones no rompan la encapsulación. Por ejemplo si en una capa inferior se produce una excepción (por ejemplo una SQLException en la capa de persistencia), a la capa superior no le interesa conocer los detalles de implementación, sino:

  • si se puede recuperar del error, es aconsejable transformar la excepción original en otra excepción controlada o checked con la información necesaria para recuperar que la capa superiro se pueda recuperar.
  • o si no puede recuperarse del error pasamos a la capa superior una excepción no controlada o unchecked si no se debe continuar el flujo normal, o bien un resultado nulo si no se quiere hacer nada especial.

Sólo deberíamos de crear excepciones propias cuando aporten algo útil como información extra cuando sean capturadas o comportamientos propios (como un tratamiento especial en un log).

Al capturar excepciones también capturamos las que heredan de ésta. Por tanto al capturar una excepción del tipo java.lang.Exception también estamos capturando todas las unchecked (ya que heredan de java.lang.RuntimeException y ésta hereda de java.lang.Exception). Hay que tener cuidado de si esto es realmente lo que queremos.

Por todo lo dicho anteriormente, la gestión de las excepciones nos debería de servir para recuperarnos ante errores esperados. Pero deberíamos tener en cuenta que pueden existir errores no controlados. Podríamos gestionar estos errores en un único punto, desviando todas las excepciones no capturadas a un action donde se tratarán (típicamente presentación de una página de error con un mensaje y las acciones permitidas para el usuario, así como la auditoría del error). Podemos indicar en el web.xml esta redirección :

<error-page>

      <exception-type>java.lang.Throwable</exception-type>

      <location>/gestionErrores.do</location>

</error-page>

Enlaces recomendados

El Lenguaje de Programación Java

Java es un Lenguaje de Programación de Alto Nivel diseñado por Sun Microsystems a primeros de los años 90, en plena transición desde la Programación Estructurada, en la que el lenguaje C copaba el mercado, hacia la emergente Programación Orientada a Objetos (POO en español, OOP en inglés), en la que competiría con C++.

Sus características fueron la base de su éxito  :

  • Al ser un lenguaje de más alto nivel es más fácil de aprender y se reduce el tiempo y coste de los desarrollos y de las pruebas (se simplifica la programación, se eliminan los punteros, la gestión de la memoria ya no la hace el programador…).
  • Implementa el paradigma de programación POO : Jerarquía de Clases, Herencia, Polimorfismo, Encapsulación y ocultamiento de la información.
  • Hacía especial énfasis en la Modularidad y Reutilización de los componentes, es la base para la aparición de APIs (Application Programming Interface). Todo esto facilita enormemente el desarrollo, el trabajo en paralelo entre equipos y disminuía enormemente el tiempo de desarrollo y pruebas.
  • Es un lenguaje Multiplataforma, es decir es independiente de la platarforma (máquina + sistema operativo) en la que se ejecute, con lo cual obtenemos programas Portables, gracias a la Máquina Virtual Java (JVM).
  • Es gratuito !
  • La irrupción poco después de Internet supondría el éxito definitivo de este lenguaje.

Qué necesitamos para comenzar a programar con este lenguaje ?

  • Documentación, un montón de documentación. Creo que es lo primero en que pensar.
  • Después necesitaremos las herramientas para desarrollar en Java que podemos descargarnos gratuitamente de Sun : el Java Development Kit o JDK, que básicamente nos proporciona un compilador java y un entorno para ejecutar programas java. Podemos encontrar sus diferentes versiones en el sitio web de Sun. Podemos utilizar Java 2 Standard Edition (J2SE), Java 2 Enterprise Edition (J2EE) o Java 2 Mobile Edition (J2ME).
  • No confundir con el Java Runtime Environment o JRE que son las herramientas imprescindibles que necesitan los programas basados en Java para poder ejecutarse (la JVM es una instancia del JRE).
  • Ahora nos basta con cualquier editor de texto, pero es altamente recomendable (imprescindible profesionalmente) utilizar software que nos ayude, un IDE (Integrated Development Kit) que nos proporciona editores de texto más potentes y otras herramientas que nos ayudan al desarrollo y pruebas. Eclipse es el más extendido entre los gratuitos, pero también Intelli J Idea es útil y potente entre los gratuitos.