Принуждение класса быть одиночным только через наследование не сработает. Это не то, что поддерживает язык. Конструкторы не наследуются, как и члены stati c, и они нужны вам для доступа к синглтону.
Чтобы иметь возможность вообще создать экземпляр класса, классу нужен генеративный конструктор. Этот генеративный конструктор будет создавать новый экземпляр каждый раз, когда он вызывается, потому что это то, что делают генеративные конструкторы. Чтобы подкласс мог расширять класс, суперкласс также должен иметь доступный генеративный конструктор, но, по крайней мере, суперкласс можно сделать abstract
.
Чтобы заставить класс быть одноэлементным ( если вы действительно этого хотите, потому что синглтон действительно является чем-то вроде анти-паттерна; он заставляет класс действовать так, как будто это просто набор глобальных переменных, и это усложняет тестирование), каждый такой класс должен есть способ publi c stati c для доступа к экземпляру или его создания, а также частный генеративный конструктор.
Итак, в основном ваш первый подход делает то, что необходимо, а поскольку конструкторы не наследуются, вам нужно сделать это для каждого одноэлементного класса, и нет ничего полезного для наследования. Итак, вы ничего не можете сделать с наследованием, чтобы наследовать синглтон, и вы даже не можете help , потому что все, что нужно синглтону, - это stati c.
Другой подход состоит в том, чтобы сделать классы состояния полностью закрытыми, чтобы вам не приходилось беспокоиться о том, что кто-то другой создает экземпляры, и предоставьте им генеративный конструктор константу каждому, а затем только ссылаться на их, используя const _ThisState()
или const _ThatState()
. Это возлагает ответственность на пользователя (вас!) За создание только одного экземпляра каждого объекта состояния, но также дает очень простой способ сделать это, потому что const _ThisState()
будет предоставлять один и тот же экземпляр каждый раз. .
Или используйте шаблон перечисления и укажите:
abstract class State {
static const State thisState = const _ThisState();
static const State thatState = const _ThatState();
const State._();
void handle(Context context, Object argument);
}
class _ThisState implements State {
const _ThisState();
void handle(Context context, Object argument) { ... }
}
class _ThatState implements State {
const _ThatState();
void handle(Context context, Object argument) { ... }
}
, а затем просто ссылайтесь на экземпляры состояния как State.thisState
. Я считаю это более читаемым, чем создание экземпляров, казалось бы, несвязанных классов.