У меня есть одноэлементный класс для ведения журнала в моем проекте Qt. В каждом классе, кроме одноэлементного, есть указательный пункт для объекта singleton и сигнал, подключенный к слоту записи в одноэлементном объекте. Какой бы класс не захотел написать информацию о журнале, просто испустите этот сигнал. Сигналы помещаются в очередь, поэтому они потокобезопасны.Singleton класс по всему проекту подход
Пожалуйста, критикуйте этот подход с точки зрения ООП, спасибо.
=============================================================================================================================================== =========================================== Редактировать 1 : Спасибо вам всем, что вам нравится, прислушиваясь к противоположным мнениям, это всегда большое обучение.
Позвольте мне подробнее рассказать о моем подходе и о том, что я сделал в своем коде: Точно так же, как указатель MikeMB, у singleton-класса есть статическая функция, такая как get_instance(), которая возвращает ссылку на этот синглтон. Я сохранил его в локальном указателе в конструкторе каждого класса, поэтому он будет уничтожен после возвращения конструктора. Это удобно для проверки того, получил ли я нулевой указатель и делает код более читаемым. Мне не нравится то, как это:
if(mySingletonClass::gerInstance() == NULL) { ... }
connect(gerInstance(), SIGNAL(write(QString)), this, SLOT(write(QString)));
, потому что это дороже, чем это:
QPointer<mySingletonClass> singletonInstance = mySingletonClass::getInstance();
if(singletonInstance.isNull) { ... }
connect(singletonInstance, SIGNAL(write(QString)), this, SLOT(write(QString)));
Вызов функции в два раза дороже, чем создание локальной переменной с точки ASM зрения из-за толчок, выбор адреса и возврата адреса.
Вот мой синглтон класс:
class CSuperLog : public QObject
{
Q_OBJECT
public:
// This static function creates its instance on the first call
// and returns it's own instance just created
// It only returns its own instance on the later calls
static QPointer<CSuperLog> getInstance(void); //
~CSuperLog();
public slots:
void writingLog(QString aline);
private:
static bool ready;
static bool instanceFlag;
static bool initSuccess;
static QPointer<CSuperLog> ptrInstance;
QTextStream * stream;
QFile * oFile;
QString logFile;
explicit CSuperLog(QObject *parent = 0);
};
Я называю GetInstance() в начале основной(), так что убедитесь, что он сразу же прочитать для каждого другого класса, когда они должны войти важную информацию.
MikeMB:
Your approach is making a middle man sitting in between, it makes the path of the logging info much longer because the signals in Qt are always queued except you make direct connection. The reason why I can't make direct connection here is it make the class non-thread-safe since I use threads in each other classes. Yes, someone will say you can use Mutex, but mutex also creates a queue when more than one thread competing on the same resource. Why don't you use the existing mechanism in Qt instead of making your own?
Спасибо все ваши посты!
=============================================================================================================================================== ===========
Edit 2:
Марселю Blanck:
- Мне нравится ваш подход, а потому, что вы считали конкурс ресурсов.
- Практически в каждом классе мне нужны сигналы и слоты, поэтому мне нужен QObject, и именно поэтому я выбираю Qt.
- Должен быть только один экземпляр для одного статического объекта, если я не ошибаюсь.
- Использование семафоров такое же, как использование сигналов/слотов в Qt, оба генерируют очередь сообщений.
- Всегда есть плюсы и минусы относительно шаблона проектирования программного обеспечения и производительности приложения. Добавление большего количества слоев между ними делает ваш код более гибким, но значительно снижает производительность на тех устройствах с более низким уровнем настройки, что делает ваше приложение зависящим от одного из самых мощных аппаратных средств, и именно поэтому большинство современных ОС написаны в чистых C и ASM. Как сбалансировать их - действительно большая проблема.
Не могли бы вы объяснить немного больше о вашем статическом заводе-изготовителе Logger? Благодарю.
Для чего нужен указатель на синглтон? – MikeMB
Чтобы подключить сигнал в другом объекте к слоту записи в этом одноэлементном объекте. – QtFan
[Почему одиночные игры плохие] (http://stackoverflow.com/a/138012/2642204) – BartoszKP