“¿Amigo o enemigo? El patrón Singleton en tus proyectos”

En el universo de la programación de software existe un conjunto de conceptos que por su sencillez podrían parecer trivialidades, pero que marcan la frontera entre el software bien diseñado y aquel que resulta un verdadero quebradero de cabeza. Uno de los más conocidos es el patrón Singleton. En términos simples, un patrón Singleton es comparable a una oficina de atención única: tan solo hay una existente dentro del sistema y todo el mundo tiene que ir a la misma. Es decir, en un sistema informático debería existir únicamente una instancia de una clase que, por lo que sea, controle algo importante, puesto que una vez que exista más de una instancia la vida puede complicarse.

Sep 29, 2025 - 08:54
 0  10
“¿Amigo o enemigo? El patrón Singleton en tus proyectos”
“¿Amigo o enemigo? El patrón Singleton en tus proyectos”

Cuándo sí usarlo:

Imagina estas situaciones:

  • Gestión de configuración: como el “panel de control” de una casa inteligente. No quieres tener diez controles distintos para la luz, la temperatura o la alarma; basta con uno que centralice todo.

  • Registro de actividad (logs): como el libro de visitas de un edificio. No tendría sentido tener varios cuadernos repartidos; necesitas uno que concentre cada entrada y salida.

  • Recursos compartidos: como la única impresora de una oficina. Todos la usan, pero no tendría sentido que cada empleado tratara de crear su propia versión de la impresora.

En estos casos, el Singleton ayuda a mantener el orden y la coherencia.

Ejemplo en código (Java):

public final class LoggerSingleton {
    private static final LoggerSingleton INSTANCE = new LoggerSingleton();
    private LoggerSingleton() { }

    public static LoggerSingleton getInstance() {
        return INSTANCE;
    }

    public void log(String message) {
        System.out.println("[LOG] " + message);
    }
}

// Uso
LoggerSingleton.getInstance().log("Aplicación iniciada");

Aquí aseguramos que solo exista un “cuaderno de registro” para toda la aplicación.

Cuándo evitarlo:

El Singleton, mal usado, puede convertirse en un problema:

  • Dificultad en pruebas: es como tener un jefe al que no puedes reemplazar en un simulacro. Si siempre hay “uno y solo uno”, se complica crear entornos de prueba flexibles.

  • Cuellos de botella: recuerda esa impresora única en la oficina… si todos quieren imprimir al mismo tiempo, el recurso centralizado se convierte en obstáculo.

  • Acoplamiento excesivo: si todo depende del Singleton, el sistema se vuelve rígido, como una mesa con una sola pata: quítala y todo se derrumba.

Ejemplo en código (problema en tests):

public class GlobalConfig {
    private static final GlobalConfig INSTANCE = new GlobalConfig();
    private boolean featureXEnabled = false;

    private GlobalConfig() { }
    public static GlobalConfig getInstance() { return INSTANCE; }

    public boolean isFeatureXEnabled() { return featureXEnabled; }
    public void enableFeatureX() { featureXEnabled = true; }
}

En este caso, si un test activa featureX, todos los demás lo heredan, incluso los que esperan lo contrario. Resultado: tests contaminados.

Alternativa: inyección de dependencias

Para evitar el problema, en lugar de depender directamente del Singleton, podemos inyectar la dependencia en nuestras clases. Esto nos da flexibilidad y facilita las pruebas.

// Interfaz
public interface FeatureToggle {
    boolean isEnabled(String feature);
}

// Implementación Singleton real
public class GlobalFeatureToggle implements FeatureToggle {
    private static final GlobalFeatureToggle INSTANCE = new GlobalFeatureToggle();
    private final Set<String> enabled = new HashSet<>();

    private GlobalFeatureToggle() {}
    public static GlobalFeatureToggle getInstance() { return INSTANCE; }

    public boolean isEnabled(String feature) { return enabled.contains(feature); }
    public void enable(String feature) { enabled.add(feature); }
}

// Clase que recibe la dependencia por constructor
public class MyService {
    private final FeatureToggle toggles;
    public MyService(FeatureToggle toggles) { this.toggles = toggles; }

    public void perform() {
        if (toggles.isEnabled("new-ui")) {
            System.out.println("Ejecutando nueva interfaz");
        } else {
            System.out.println("Ejecutando interfaz clásica");
        }
    }
}

En un entorno real, usamos el Singleton GlobalFeatureToggle.getInstance().
En pruebas, podemos pasar una versión “mock” que controle el estado sin afectar otros tests.

Grafico de uso según el leguage:

lenguajes de programación suelen usar más el patrón Singleton.

En este ejemplo:

  • Java y C# lideran su uso (son lenguajes muy orientados a objetos y con frameworks que lo aplican mucho).

  • Python y JavaScript lo usan menos, porque ya cuentan con módulos y estructuras más flexibles.

  • C++ mantiene cierta presencia, pero menor en comparación.

Claves para recordar:

El patrón Singleton no es ni un héroe ni un villano. Es una herramienta útil cuando queremos controlar un recurso único, pero peligrosa si se convierte en la salida rápida para todo.

Antes de aplicarlo, pregúntate:
➔ ¿Necesito realmente un único punto de control?
➔ ¿O estoy usando Singleton solo por costumbre?

“El patrón Singleton no es magia, es estrategia: úsalo bien y tendrás orden; úsalo mal y crearás caos. La clave está en saber cuándo decir sí y cuándo decir no.”

¿Cuál es su reacción?

like

dislike

love

funny

angry

sad

wow