Continuing the discussion from New application note for using the singleton pattern:
Brief: This is a fantastic guide... but I'm wondering when the Singleton pattern is best used. In particular, is what I'm doing the intended use of Singleton or if I'm over applying it. I also wanted to get feedback on using #define to make the code more readable while using Singleton based on the Application Note.
Background: So I'm finally biting off some over due code refactoring work. After a few years of development/building I had a big monolithic 1800+ lines long .INO file that contained everything. It was still broken down into Setup(), Loop(), finite state machine and then various functions the FSM would call. So it had some organization but was all contained in the same INO file making it daunting at times. In comparing notes with @chipmc in his code structure and also trying to "level up" my C++ knowledge, I am wanting to break out the code based on it's core functionality into several .CPP/.H files including. Each one containing the data, methods/functions associated with that type.
- Pinout (Defines GPIO pins and initializes all pins with pinMode())
- Config (Handles reading device configuration data from EEPROM and a structure to store config data) centrally.
- Sensors (Handles reading data from any sensor and initializing sensor config)
- Actuators (Handles the control of any actuator/relay etc.)
- LoRa (Handles all things LoRa radio)
- Timing (Handles all things regarding setting time, calculating time to next report window)
- etc.
I started breaking it out in various .cpp/.h files and a few different data structs just for improved management and organization of the code. As I played with a few libraries and learned a bit about classes, I thought, that was a really nice way to have a structured organization of the data and various functions/methods. So I went ahead and created a class for pinout, class for sensors, class for actuators, class for LoRa, class for timing, etc. I then read about Singleton per this earlier blog post and realized that's effectively what I'm trying to do. So I then updated it all to use the near exact format using the code generator (a great feature/tool).
So my first question... is this the intended use of Singletons one for each: pinout, config, sensors, actuators, lora, timing, etc. or am I over applying it?
Second question... is this an OK method to make the code more readable:
The only part I didn’t like was requiring “ClassName::instance().method()” and/or “ClassName::instance().variable” anytime you used a variable or method from the singleton class. This made the code a little less readable. As a way around this, I ended up using some macros/#define to swap out and preserve the 2-4 letter acronym I had prior. I.e. I use this:
#define sns sensors::instance()
Pure singleton on the left, less readable. After using #define on the right... more readable/quicker to code. Is this OK or is there another work around: