Singleton

Singleton jest jednym z najprostszych wzorców projektowych. Zalicza się do grupy wzorców kreacyjnych.

Zapewnia, że ​​klasa może mieć tylko jedną instancję w całej aplikacji i zapewnia globalny punkt dostępu do niej. Wzorzec ten jest idealny dla scenariuszy wymagających scentralizowanej kontroli, takich jak zarządzanie połączeniami z bazą danych lub ustawieniami konfiguracji.

Implementacja wzorca projektowego singleton jest bardzo prosta i składa się z pojedynczej klasy. Aby zapewnić unikalność instancji singleton, wszystkie konstruktory singleton powinny być prywatne. Globalny dostęp odbywa się za pośrednictwem metody statycznej, do której można uzyskać globalny dostęp do pojedynczej instancji.

Wzorzec Singleton w Javie

class Singleton {
    private static Singleton instance;

    // prywatny konstruktor wymuszający użycie metody
    // getInstance() aby stworzyć obiekt Singleton
    private Singleton() {}

    public static Singleton getInstance() {
        if (instance == null)
            instance = new Singleton();
        return obj;
    }

    public void doSomething() {
        System.out.println("...");
    }
}

Wzorzec Singleton w Pythonie

class Singleton:
    # atrybut przechowujący instancję klasy Singleton
    _instance = None

    def __new__(cls):
        if not cls._instance:
            cls._instance = super(Singleton, cls).__new__(cls)
        return cls._instance

# Usage
s1 = Singleton()
s2 = Singleton()
print(s1 is s2)  # Output: True

Przykład wykorzystania wzorca Singleton razem z wzorcem fabryki:

class Singleton:
    _instances = {}

    def __new__(cls, class_name):
        if class_name not in cls._instances:
            cls._instances[class_name] = super(Singleton, cls).__new__(cls)
        return cls._instances[class_name]

class Car:
    pass

class Truck:
    pass

# funkcja produkująca włąsciwe obiekty Singleton
def vehicle_factory(vehicle_type):
    return Singleton(vehicle_type)

# Użycie
car1 = vehicle_factory(Car)
car2 = vehicle_factory(Car)
truck1 = vehicle_factory(Truck)

print(car1 is car2)  # Wynik: True
print(car1 is truck1)  # Wynik: False

Różnica pomiędzy __new__ oraz __init__ w Pythonie

  • __new__ jest metodą statyczną odpowiedzialną za tworzenie nowej instancji klasy. Jest wywoływana przed __init__ i jest odpowiedzialna za zwrócenie nowego wystąpienia klasy. W scenariuszach tworzenia obiektów niestandardowych, takich jak singletony, można __new__ zastąpić, aby kontrolować sposób tworzenia instancji.
  • __init__ jest metodą konstruktora klasy i jest wywoływana po __new__ w celu zainicjowania nowej instancji. __init__ niczego nie zwraca; Inicjuje obiekt dopiero po jego utworzeniu.

Poniższy kod pokazuje różnicę działania obu metod. Najpierw stworzona zostanie instacnja, potem zainicjalizowana.

class MyClass:
    def __new__(cls):
        print("Tworzenie instancji")
        instance = super(MyClass, cls).__new__(cls)
        return instance

    def __init__(self):
        print("Inicjalizowanie instancji")

obj = MyClass()

Dodaj komentarz