viernes, 2 de mayo de 2025

Singleton

Hace mucho que no bloggeo, pero bueno, estoy todavía con el proyecto y con varios problemas en el backend de eso, en fin, hoy quería escribir sobre un concepto (y más que nada, patrón de diseño) que investigué y de hecho implemento en mi proyecto para realizar la conexión de mi aplicación con la BD (aun que tranquilamente puede ser aplicado a otro aspecto, pero por el momento solo lo utilicé en una parte que es la que comentaba más atrás).

El patrón "singleton" es, hasta lo que entiendo, un patrón de diseño pensado para escenarios donde se necesita que cierto elemento de nuestro código pueda ser accedido desde cualquier otra parte del proyecto y que este solo se pueda, o se deba, instanciar 1 única vez en toda la vida o tiempo de ejecución de nuestro código. El concepto en sí no es más que una clase que se instancia a sí misma una única vez (como mencioné anteriormente) y que en base a esa instanciacion podamos realizar alguna tarea sin tener que estar instanciando varias veces la misma clase. Esta clase además verífica que con anterioridad no exista una instanciación, solamente en caso de no existir una, realiza una nueva instanciacion de sí misma, de lo contrario, retorna la misma referencia hacia sí misma (xd). Respecto a esto último, realmente hay 2 formas de definir un singleton dependiendo de que y como lo queramos hacer, la primera sería que la misma instanciacion a la clase sea almacenada en un atributo estático de esta y que sea retornado en uno de sus métodos, también estático; la otra, es que el atributo que almacena la instancia, se declare nulo, y en el método que retorna la instanciacion a la misma clase, solo almacene la instanciacion (o que simplemente instancie la clase, en otras palabras) si el atributo es nulo (o sea que no tiene una instancia previa, por lo que nunca se instancio la clase), posterior a eso, que lo retorne. Normalmente la segunda opción es usada cuando necesitamos que la instanciacion de la clase se produzca solamente en un determinado momento de la ejecución del código y no necesariamente al inicio de este.

Una de las cosas importantes a tener en cuenta en este patrón es que el constructor de la clase nunca debe ser expuesto (porque nunca será, y no debe, ser usado), las instanciaciones siempre se crearan (o retornarán más bien) desde un método estático definido para usar sin instanciar a la clase. Habitualmente el constructor siempre debe tener la directiva de acceso privado, cosa de que se impida su acceso desde fuera.

Dentro de mi proyecto tengo una clase singleton definida específicamente para la conexión de mi aplicación y la BD, como estoy usando JPA, los recursos que se usan para esto es la clase "Persistence" y "EntityMangerFactory", el primero te permite crear un objeto a partir de un fichero xml que define como se debe realizar la conexión con la BD, y el segundo es básicamente el tipo de objeto que retorna la primera clase (xd). Para la agilización y optimización de este proceso (porque es un proceso pesado de hacer, ya que establece y organiza todo para realizar la conexión a BD y además es la encargada de crear otro recurso llamada "EntityManager" que como su nombre indica, administra las entidades de la BD) es altamente recomendable instanciarlo una única vez, por ende, es mejor crearle un Singleton...

Este es el singleton que cree para poder instanciar un "EntityManager" único para todo el tiempo de ejecución de mi aplicación, este singleton además puede ser accedido a todas las entidades (que lo requieran y que tengan un contexto para requerirlo) sin problema y sin necesidad de instanciarlo en cada una:

```

/*
 * CLASE SINGLETON EMPLEADA PARA CONECTAR A LA BD (UNA SOLA INSTANCIACION DEL ENTITY MANAGER FACTORY)
 */

package utilidades;

import jakarta.persistence.Persistence;
import jakarta.persistence.EntityManagerFactory;


/*
 *
 * NOTA:
 *
 * SI, YA SE QUE ES RARO Y MEDIO SIN SENTIDO EL METODO INICIAR(), SI YA EL RETORNO DEL ATRIBUTO CREA LA CONEXION DEL
 * EMF, PENSE QUE PARA QUE TENGA MAS CONTEXTO EL CODIGO, SERÍA BUENA IDEA EL METODO INICIAR, SI A FUTURO DA PROBLEMAS,
 * LO PLANTEO DE OTRA MANERA.
 *
 * NO HAY PROBLEMA CON DEFINIR LA INSTANCIACION DE LA CLASE SI PREVIAMENTE NO HABÍA UNA, POR QUE EN ESTE CASO QUEREMOS
 * QUE LA CLASE SE INSTANCIE APENAS SE INICIE LA APLICACION, NO NECESARIAMENTE EN ALGUN PUNTO ESPECIFICIO.
 *
 */


/**
*
* @Autor: BBKMG
*/
public class EMFSingleton {
    // ATRIBUTOS
    private static final EMFSingleton instancia = new EMFSingleton(); // INSTANCIA DE ESTA MISMA CLASE
//    private static EMFSingleton instancia = null; // NO HACE FALTA, BORRAR DESPUES
    private EntityManagerFactory emf = null;
    private final String UNIDADPERSISTENCIA = "persistencia";
    
    // CONSTRUCTOR
    // CONSTRUCTOR PRIVADO PARA EVITAR INSTANCIACION DESDE AFUERA
    private EMFSingleton() {}
    
    // SET
    //...
    
    // GET
    public static EMFSingleton getInstancia() {
        return instancia;
    }
    
    // NO HACE FALTA DEFINIR ESTO, BORRAR DESPUES
//    public static EMFSingleton getInstancia() {
//        if (instancia == null) {
//            instancia = new EMFSingleton();
//        }
//        
//        return instancia;
//    }
    
    // INSTANCIA EL OBJETO SOLO SI EL ATRIBUTO EMF ES NULO
    public EntityManagerFactory getEMF() {
        // BORRAR DESPUES
//        if (this.emf == null) {
//            try {
//                this.emf = Persistence.createEntityManagerFactory("persistencia");                
//                System.out.println("[ EXITO ] > EMF iniciado correctamente!");
//            } catch (Exception e) {
//                System.out.println(e);
//            }
//        }
        
        return this.emf;
    }
    
    // METODOS
    // SOLAMENTE INSTANCIA 1 SOLA VEZ EL EMF (O DIGAMOS QUE ESTABLECE LA CONEXION A BD 1 SOLA VEZ)
    public void iniciarEMF() {
        if (this.emf != null) {
            System.out.println("[ EXITO ] > El EMF ya fué iniciado!");
            return;
        }
        
        try {
            this.emf = Persistence.createEntityManagerFactory(UNIDADPERSISTENCIA);
            System.out.println("[ EXITO ] > EMF iniciado correctamente!");            
        } catch (Exception e) {
            System.out.println(e);
        }
    }
    
    // OBVIAMENTE ESTO MATA LA CONEXION A BD
    public void cerrarEMF() {
        if (this.emf != null && this.emf.isOpen()) {
            this.emf.close();
            System.out.println("[ EXITO ] > EMF finalizado correctamente!");
        }
    }
}

```

(Es parte del código de mi aplicación, y si, no me lo deja poner como código, pero bueno)

Y hasta el momento esto funciona de forma correcta, leí que el patrón singleton es medio propenso a joderse si se utilizan hilos múltiples (ya que por A o por B si ambos hilos instancian a la clase al mismo tiempo pueden pasar 2 cosas, romperse el patrón por haber más de una instanciacion, o que todo falle al carajo), yo hasta el momento no hago uso de hilos, así que no me preocupo por eso.

sábado, 19 de abril de 2025

DevStyle

Como mencioné en blogs anteriores, me encuentro usando el IDE Eclipse para programar en java, pero últimamente me dejó de gustar el tema por defecto con el que viene (hasta el ahora venía usando el tema oscuro por defecto que viene con la IDE), así que con ganas de renovar un poco el aspecto visual con que el que vengo trabajando desde hace un tiempo ya, busque como se podría agregar más aspectos visuales o como podía modificar a mi gusto este apartado, indagando encontré una forma la cual es instalándolas de forma automática desde un repo de github llamado "eclipsecolorthemes" (https://eclipsecolorthemes.org/), esto se hace mediante la opción de instalar software de terceros en eclipse que está en el apartado "Help" > "Install new software", y agregando una fuente (o sea el link del repo), se puede establecer como repositorio de instalación de software de terceros (en resumen, descargarías desde ahí los temas, se instalarían y actualizarían automáticamente), el problema, el repo aparentemente está caído y ya no funciona bien. :'(

Así que, continuando mi búsqueda sobre como cambiar el tema de eclipse, me tope con "DevStyle", un plug-in que se encuentra en el marketplace oficial de eclipse, que te permite modificar no solo el tema del editor del IDE, sino más bien, casi todo el aspecto visual del IDE. Como era un plug-in propio del marketplace y como su instalación era un simple click, lo instalé y hasta el momento viene siendo el mejor plug-in que instalé. Mi IDE se ve así ahora:

 

(Tá re lindo xd)

Se me hace muy interesante porque una vez que lo instalas, hasta una ventana de bienvenida y configuración inicial (que aparece 1 sola vez) tiene, donde te permite de una vez modificar el tema y otros aspectos. También lo más curiosos es que te permite modificar los iconos, cosa que hasta el momento o no encontré, o no se podía, así que nice!

Y eso básicamente, por lo demás, tengo que seguir con mi proyecto que voy bien, pero tengo algunas complicaciones en el backend con algunas relaciones, así que manos a la obra.