It's a pretty good instinct to balk at creating one hundred very similar classes. That's generally a sign those should be instances instead. You might try something like:
monitors.createIntMonitor("Floor", "DM141")
monitors.createBoolMonitor("Front door open", "DM142")
monitors.createEnumMonitor("Direction", "DM140", ["Up", "Down", "None"])
// or alternately
monitors.createEnumMonitor<ElevatorDirection>("Direction", "DM140")
monitors.getMonitor("Front door open").addObserver(observer)
This design can easily be initialized dynamically, such as from a configuration file or database, including adding new fields, without requiring your app to be recompiled. These kinds of changes often end up being the biggest maintenance cost if you do it statically. It also requires a lot less copy/paste/minor changes, which is a big source of errors.
The disadvantage is you no longer get compile errors when you put a RearDoorMonitor
into a variable expecting a FrontDoorMonitor
. It's also somewhat more problematic to cram multiple observers into one class, but that usually isn't the best idea anyway.
Your subscribers for a templatized enum monitor could look like this:
// Common interface
template <typename T>
class Subscriber
{
public:
virtual void receiveEvent(T t) = 0;
};
// Individual subscriber instance
class ElevatorSubscriber : public Subscriber<ElevatorDirection>
{
public:
void receiveEvent (ElevatorDirection direction);
};