Design patterns
Monostate
Поиск…
замечания
В качестве побочного примечания несколько преимуществ шаблона Monostate
над Singleton
:
- Метод экземпляра не имеет возможности получить доступ к экземпляру класса.
-
Singleton
не соответствует нотации Java beans, но делаетMonostate
. - Время жизни экземпляров можно контролировать.
- Пользователи
Monostate
не знают, что они используютMonostate
. - Полиморфизм возможен.
Моностатный шаблон
Шаблон Monostate
обычно называют синтаксическим сахаром по шаблону Singleton
или как концептуальный Singleton
.
Он избегает всех осложнений наличия одного экземпляра класса, но все экземпляры используют одни и те же данные.
Это достигается главным образом использованием static
элементов данных.
Одной из наиболее важных особенностей является то, что она абсолютно прозрачна для пользователей, которые совершенно не знают, что они работают с Monostate
. Пользователи могут создавать столько экземпляров Monostate
сколько захотят, и любой экземпляр хорош как другой для доступа к данным.
Класс Monostate
обычно встречается со спутником, который используется для обновления настроек, если это необходимо.
Он следует за минимальным примером Monostate
в 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; }
};
Ниже приведен пример простой реализации Monostate
в 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;
}
}
Инициалы на основе моностата
В отличие от Singleton
, Monostate
подходит для унаследования для расширения его функциональных возможностей, если методы-члены не являются static
.
Он следует за минимальным примером в 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; }
};