Я не очень ненавижу синглтоны, но это звучит как случай, который бесполезен для них.Я не понимаю, почему в этой статье так много синглетонов.
Во-первых, PanelStack сам по себе является синглтоном.Зачем?Если это ваш главный виджет, просто создайте его в стеке в main (), который будет чище и быстрее.Если он является частью более сложного пользовательского интерфейса, поместите его в качестве члена этого пользовательского интерфейса.С обычным классом здесь все в порядке, делая его синглтоном, только ограничивая его возможное использование.
Тогда каждая панель тоже синглтон?В этот момент даже любители одиноких игр должны начать чувствовать, что их уже слишком много.Возможно, именно поэтому вы задаете этот вопрос в первую очередь.Посмотрим, какие реальные преимущества дают синглтоны здесь.Ну, единственное преимущество, которое я могу понять из этой статьи, - это возможность лениво создавать панели на лету, когда они необходимы.Это на самом деле хорошо, но на самом деле ленивое создание и синглтоны - это разные шаблоны, хотя один часто использует другой.
Почему бы просто не поместить все эти панели в какой-то общий контейнер?В этом случае PanelStack выглядит как идеальный кандидат для этого.Это то самое место, где хранятся панели.Вместо группы синглетонов, давайте создадим группу методов в PanelStack:
class PanelStack : public QWidget
{
Q_OBJECT
public:
int addPanel(AbstractPanel *);
void showPanel(int);
RecordingsPanel *getRecordingsPanel();
ReecrdingDetailsPanel *getRecordingDetailsPanel();
private:
...
};
и так далее.Эти get*Panel()
методы все еще могут создавать панели лениво по мере необходимости.Теперь это, по сути, то же самое, что и связка синглетонов с некоторыми дополнительными преимуществами:
- Если мы сделаем панели дочерними по стеку, они будут автоматически удалены при удалении стека.Не нужно беспокоиться об управлении памятью, которое всегда является проблемой с одиночками.
- Вы можете даже реализовать своего рода «сборщик мусора» в PanelStack, который удаляет панели, которые не использовались в течение некоторого времени.Или когда достигается какое-то ограничение на «максимальное количество активных панелей».
Теперь единственный недостаток, о котором я могу думать, это то, что у нас теперь есть зависимость между стеком и панелями.Но что хуже: хранить экземпляры в одном классе, вводить зависимости или хранить их глобально?Если вы думаете, что стек должен быть независимым от панелей, что звучит разумно, то нам, вероятно, просто нужен другой класс, чтобы поместить все эти вещи. Это может быть подкласс QApplication или просто некоторый случайный класс «UI manager», новсе же лучше хранить все в одном месте, чем хранить все глобально.
Использование синглетонов здесь только нарушает инкапсуляцию и ограничивает возможное использование всего пользовательского интерфейса.Что если мы хотим иметь два окна с этими панелями?Или несколько вкладок (например, веб-браузер)?Синглтоны будут сильно кусаться.И они действительно полезны только тогда, когда к экземпляру обращаются широко во многих не связанных между собой классах (например, соединения с БД, регистраторы, пулы и другие типичные синглтоны).Они в основном бесполезны в пользовательском интерфейсе, потому что в пользовательском интерфейсе почти всегда очевидно, что «эта вещь принадлежит там, и, вероятно, больше нигде».