Unsolved Signal-slot-mechanism vs. observer pattern - Good practice
-
Coming from other parts of computer science (say HPC) I have not much knowledge about Qt, nevertheless I am working on some project with a tiny toy-QT Frontend.
Years ago I learnt about the observer pattern, where we usually have some class (the subject) which is observed by some observer. The observers register to the subject, and if the subject does some action, e.g., sets some new value, it notifies the observers.
Mapping this to QT mechanisms, we have slots instead of observers, which create a connection to the signal. When the object with the signal does some action, it emits the signal and the registered slots are notified.
But now my question about what is good practice:
- Assume we have a SpinBox which stores some value with has some meaning. This value is used at various places, but still, the value is only changed by the SpinBox. How would we model this? I would still use some third object (clearly named) which stores the value (and has one signal). The SpinBox and all other objects would need to register to this object.
- Assume we have a SpinBox, a TextBox and probably some programmatically determined way to set some value. So the value is changed and read at various places. We could either define one of them as "the central place of storage", or we could again have some other object with one signal.
- Assume we have three values A, B, and C. All of them are read and written at different places; sometimes I change one, some times I cange all values. When I change some value (or all of them), I start an expensive calculation. We could now use three observers (problem: I restart the expensive calculation too often when all values are changed at once), or we could use one observer for all (problem: I change values which I don't need to), or I have again one central place of storage for all three values A, B, C, and four signals (set A, set B, set C, and set ABC).
In my opinion I would always vote for the independent class with one signal. But when I look through some codes I often see that this is done kind of randomly.
Is there some common sense and some reasoning why to choose one or another approach in both cases?
-
Hi and welcome to devnet,
If usually depends on how you want to separate your GUI from your core logic.
Having one class per value however is an overkill.
One pattern you could use is a controller that will have the properties you want to share between different objects.
Another one is MVC if for example you have a structure that would be best represented by e.g. a table or a list of element.
There's also the publish-subscribe pattern that could be of interest.Note that in the case of signals and slots, the emitters don't care about what is connected to the signals they provide, it's not their responsibility.
-
@lukasm said in Signal-slot-mechanism vs. observer pattern - Good practice:
Years ago I learnt about the observer pattern, where we usually have some class (the subject) which is observed by some observer. The observers register to the subject, and if the subject does some action, e.g., sets some new value, it notifies the observers.
Hi,
The "problem" with that is that you create an object for each event you're handling, and you can imagine how this goes out of proportion if your view class has 10-15 different events only for retrieving and fine-tuning data display. Not that it's impossible, or wrong, it might get cumbersome. By the way, when you make a connect you get aQMetaObject::Connection
object, which is pretty much what you described.As @SGaist said in Signal-slot-mechanism vs. observer pattern - Good practice:
Note that in the case of signals and slots, the emitters don't care about what is connected to the signals they provide, it's not their responsibility.
That's the beauty of it, you continue to be flexible, without losing anything.
@lukasm said in Signal-slot-mechanism vs. observer pattern - Good practice:
Is there some common sense and some reasoning why to choose one or another approach in both cases?
I personally prefer MVC (although Qt uses Views as controllers in the docs), because this way I don't mix up the logic for viewing things with the controller logic (connecting things, creating objects). Basically I put the controller code either in
main()
for simpler stuff, or in a dedicated object (QObject
) and don't derive fromQWidget
(or friends) unless I'm making a custom one.Kind regards.