Are Singletons EVIL in GUI Programming with Qt?

I am just starting my first fairly large Qt project, which will be basically a bunch of screens with buttons, tabs, and Qwt Plots. The panel pattern described in Qt Quarterly 27 seems pretty nice for my application. Each of my screens is a QWidget encapsulated in Panel, which is displayed / hidden by QStackedWidget. However, a singleton pattern is used for each panel, so that they are not all created immediately as the application starts, and therefore not one of each screen is created.

So, I started coding. Got a panel stack. Some code has been added, so the dynamic update of the widget is not constantly dynamically updated. Got my story stack / back button working for panels. Everything seems just wonderful, but I have one exciting concern:

  • My code smells.

I have nowhere to argue with any of the hate posted here and on blogs about the singleton pattern. I think I understand, and the code I wrote makes me feel a little dirty with all the templates and global objects. But I really do not need to worry about the fact that I already created the screen before switching to it, and adding it to my story stack. I'm just talking about switching to this screen, it is added to my story stack, and the magic works.

From what I read, there are also cases where singles can be useful. Is this one of those special occasions? The magic screen shielding / story stack makes me think yes, but the sheer number of different singleton classes that I need to create makes me think NO NO NO NO.

I just want to catch up and figure out how to get the singleton pattern from my code now so I don't have to do it later. But I do not want to get rid of all my singleton classes in order to get rid of my singleton classes because they are EVIL [citation needed].

Any entry is welcome!

+4
source share
1 answer

I really do not hate singles, but it sounds like a case worthless for them. I don’t understand why there are so many singletones in this article.

First off, PanelStack is single. What for? If this is your main widget, then just create it on the stack in main (), which is cleaner and faster. If this is part of a more complex user interface, then put it there as a member of that interface. The regular class here is just good, which makes it singleton only limits its possible applications.

Then is each panel also a single? At this moment, even single lovers should begin to feel that there are already too many of them. This is probably why you are asking this question first. Let's see what the real advantages of the singleton here. Well, the only advantage I can understand from this article is the ability to lazily create panels on the fly, as they are needed. This is actually good, but in fact lazy creation and singletones are different templates, although a different one is often used.

Why not just put all these panels in some kind of common container? In this case, PanelStack looks like the perfect candidate for him. This is where the panels are stored in the end. Instead of many singletones, create a bunch of methods in PanelStack:

class PanelStack : public QWidget { Q_OBJECT public: int addPanel(AbstractPanel *); void showPanel(int); RecordingsPanel *getRecordingsPanel(); ReecrdingDetailsPanel *getRecordingDetailsPanel(); private: ... }; 

And so on. These get*Panel() methods can create panels lazily as needed. Now, in essence, this is the same as having multiple singletones with the addition of some advantages:

  • If we create panels of stack children, they are automatically deleted when the stack is deleted. No need to worry about managing memory, which is always a pain with singles.
  • You can even implement some sort of “garbage collector” in PanelStack, which removes panels that have not been used for some time. Or when a certain limit of "maximum active panels" is reached.

Now the only drawback I can think of is that we now have a dependency between the stack and the panels. But what's worse: store instances in one class, add dependency, or store them around the world? If you think the stack should be independent of the panels, which sounds reasonable, we probably just need another class to fit all of these things. It may be a subclass of QApplication or just some random UI manager class, but it's still better to store everything in one place than to store everything around the world.

Using singletones here only breaks the encapsulation and limits the use of the entire interface. What if we want to have two windows with these panels? Or multiple tabs (think web browser)? Singletones will bite a lot. And they are really only useful when an instance is widely available in many unrelated classes (think of connections to DBs, logs, pools, and other typical singletones). They are mostly useless in the user interface because with the user interface it is almost always obvious that "this thing belongs and probably nowhere else."

+6
source

Source: https://habr.com/ru/post/1340824/


All Articles