I am writing an audio processing standalone application. I have an AudioManager
object that wraps things to do with the engine (such as I/O device management, signal processing routing, running state). I am writing a GUI to control the AudioManager
running in the background. Currently, every component that needs to message the AudioManager
needs a pointer to it.
This starts to get crazy when a deeply nested object needs a pointer to the AudioManager
, as it means that I need to pass the pointer through the constructors of GUI objects that don't directly care about AudioManager
(only some subcomponents need to know).
I could just make AudioManager
a singleton to avoid the boilerplate, but the information flow from the class is bidirectional, so this is probably a bad idea. I does also feel a little fishy wrapping everything into a big class, but it makes it a little easier to pass about. Is there a common pattern to avoid the mindless pointer passing?
Below is a bit of pseudocode showing some constructors highlighting the basic type of problem. I've tagged this C++11 to see if that gives any unique solutions.
MainWindow()
{
am = new AudioManager();
someWidget = new SomeWidget(am);
}
SomeWidget(AudioManager* am_) //SomeWidget does not really care about am
{
someSubComponent = new SubThingy(am_);
}
SubThingy(AudioManager* am_) : subThingyLocalAudioManagerPtr(am_)
{
subThingyLocalAudioManagerPtr->registerSomethingOrOther(this);
}
The simplest way to avoid globals all together is to simply pass your variables using function arguments. As you can see, the $productData array from the controller (via HTTP request) goes through different layer: The controller receives the HTTP request. The parameters are passed to the model.
If 'global' means, that the variable needs to be shared between callbacks of a figure only, use either set/getappdata, guidata or the 'UserData' of the corrsponding GUI element. This allows e.g. to run two instances of the same GUI without conflicts.
The primary advantage of passing a parameter is that, unless it is passed by reference, no values in the main program can be accidentally modified by any use of the parameter variable in the function.
To declare a structure globally, place it BEFORE int main(void). The structure variables can then be defined locally in main, for example.
In your example, "SomeWidget" should take its actual dependency, "SomeThingy," not an AudioManager.
Usually when you see the whole world referencing a class it means that the class does too much. The name "XyzManager" usually indicates a problem for the same reason. (Classes should be named after what they do, and if the most specific name available that describes what it does is "Manage", then it should be separate classes)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With