Buscar..


Observaciones

Como nota al margen, algunas ventajas del patrón de Monostate sobre el Singleton :

  • No hay un método de 'instancia' para poder acceder a una instancia de la clase.
  • Un Singleton no se ajusta a la notación de los beans de Java, pero un Monostate sí lo hace.
  • La vida de las instancias puede ser controlada.
  • Los usuarios de Monostate no saben que están usando un Monostate .
  • El polimorfismo es posible.

El Patrón de Monostato

El patrón de Monostate se suele denominar azúcar sintáctico sobre el patrón de Singleton o como un Singleton conceptual .

Evita todas las complicaciones de tener una sola instancia de una clase, pero todas las instancias usan los mismos datos.
Esto se logra principalmente mediante el uso de miembros de datos static .
Una de las características más importantes es que es absolutamente transparente para los usuarios, que desconocen por completo que están trabajando con un Monostate . Los usuarios pueden crear tantas instancias de Monostate como deseen y cualquier instancia es tan buena como otra para acceder a los datos.

La clase Monostate generalmente viene con una clase complementaria que se usa para actualizar la configuración si es necesario.

Sigue un ejemplo mínimo de un Monostate en C ++:

struct Settings {
    Settings() {
        if(!initialized) {
            initialized = true;
            // load from file or db or whatever
            // otherwise, use the SettingsEditor to initialize settings
            Settings::width_ = 42;
            Settings::height_ = 128;
        }
    }

    std::size_t width() const noexcept { return width_; }
    std::size_t height() const noexcept { return height_; }

private:
    friend class SettingsEditor;

    static bool initialized;
    static std::size_t width_;
    static std::size_t height_;
};

bool Settings::initialized = false;
std::size_t Settings::width_;
std::size_t Settings::height_;

struct SettingsEditor {
    void width(std::size_t value) noexcept { Settings::width_ = value; }
    void height(std::size_t value) noexcept { Settings::height_ = value; }
};

Aquí hay un ejemplo de una implementación simple de un Monostate en Java:

public class Monostate {
    private static int width;
    private static int height;

    public int getWidth() {
        return Monostate.width;
    }

    public int getHeight() {
        return Monostate.height;
    }

    public void setWidth(int value) {
        Monostate.width = value;
    }

    public void setHeight(int value) {
        Monostate.height = value;
    }

    static {
        width = 42;
        height = 128;
    }
}

Jerarquías basadas en el monstruo

En contraste con el Singleton , el Monostate es adecuado para ser heredado para extender sus funcionalidades, siempre que los métodos de los miembros no sean static .
Sigue un ejemplo mínimo en C ++:

struct Settings {
    virtual std::size_t width() const noexcept { return width_; }
    virtual std::size_t height() const noexcept { return height_; }

private:
    static std::size_t width_;
    static std::size_t height_;
};

std::size_t Settings::width_{0};
std::size_t Settings::height_{0};

struct EnlargedSettings: Settings {
    std::size_t width() const noexcept override { return Settings::height() + 1; }
    std::size_t height() const noexcept override { return Settings::width()  + 1; }
};


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow