Как реализовать общий класс для синглтона? - PullRequest
0 голосов
/ 02 августа 2020

Я пытался реализовать проект управления состоянием для своего курса шаблонов проектирования. Я реализовал синглтон, потому что знаю, что это важно для сохранения состояния класса. Я хотел бы сделать следующее: создать общий класс, чтобы другие могли использовать его в своих проектах. Как я могу это сделать? Мой код на данный момент:

class StateManager{
  static final StateManager _instance = StateManager._singleton();

  StateManager._singleton();

  factory StateManager(){
    return _instance;
  }

}

Мое другое решение, чтобы попытаться сделать его общим:

class AppProvider extends StateManager<AppProvider>{

  int i = 10;
  String data = "adas";

  


}

class StateManager<T extends AppProvider>{
  static final StateManager _instance = StateManager._singleton();

  StateManager._singleton();

  factory StateManager(){
    return _instance;
  }


}

Я хочу, чтобы класс AppProvider был классом клиента, и я хочу, чтобы StateManager автоматически обрабатывать тот факт, что AppProvider должен быть одноэлементным, и поддерживать состояние AppProvider .. Я действительно не знаю, как это сделать.

1 Ответ

0 голосов
/ 03 августа 2020

Принуждение класса быть одиночным только через наследование не сработает. Это не то, что поддерживает язык. Конструкторы не наследуются, как и члены 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. Я считаю это более читаемым, чем создание экземпляров, казалось бы, несвязанных классов.

...