Design patterns
Monostat
Szukaj…
Uwagi
Na marginesie, kilka zalet wzoru Monostate
porównaniu z Singleton
:
- Nie ma metody „instance” umożliwiającej dostęp do wystąpienia klasy.
-
Singleton
nie jest zgodny z notacją Java Bean, aleMonostate
. - Żywotność instancji może być kontrolowana.
- Użytkownicy
Monostate
nie wiedzą, że używająMonostate
. - Polimorfizm jest możliwy.
Wzór monostatu
Wzór Monostate
jest zwykle określany jako cukier syntaktyczny nad wzorem Singleton
lub jako konceptualny Singleton
.
Pozwala to uniknąć wszystkich komplikacji związanych z posiadaniem pojedynczej instancji klasy, ale wszystkie instancje używają tych samych danych.
Odbywa się to głównie za pomocą static
elementów danych.
Jedną z najważniejszych cech jest to, że jest całkowicie przejrzysty dla użytkowników, którzy są całkowicie nieświadomi, że pracują z Monostate
. Użytkownicy mogą utworzyć tyle instancji Monostate
ile chcą, a każda instancja ma dobry dostęp do danych.
Klasa Monostate
zazwyczaj zawiera klasę towarzyszącą, która służy do aktualizacji ustawień w razie potrzeby.
Podąża za minimalnym przykładem Monostate
w 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; }
};
Oto przykład prostej implementacji Monostate
w Javie:
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;
}
}
Hierarchie oparte na monostacie
W przeciwieństwie do Singleton
, Monostate
nadaje się do dziedziczenia w celu rozszerzenia jego funkcjonalności, o ile metody static
nie są static
.
Podąża za minimalnym przykładem w 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; }
};