我正在尝试创建各种性能监视器以在刨花板(基于STM32)上运行。我习惯于用c编程,因此OOP方法有点新,但我认为它很适合这里。
出于这个问题的目的,我们假设我有两种类型的监视器:
我想做的是在我的整个应用程序中创建这些监视器的实例,并能够从主模块中报告所有类型的所有监视器的统计信息。
我已经阅读了单例设计模式,这似乎是我所需要的,但是我不确定,我也对此感到担忧。
我在想创建一个“ StatMonitor”类以及一个派生类“ FrequencyMonitor”和“ PeriodMonitor”。 Monitor将是一个单例,并且在任何我想创建一个新Monitor的地方,我都将请求“ Monitor”的实例并按如下方式使用它:
freqMonitor * task1FreqMonitor = StatMonitor::GetInstance()->Add_Freq_Monitor("Task1");
StatMonitor将跟踪我添加的所有监视器,并且当我想打印统计信息时,我可以调用printAll方法,该方法将迭代它的监视器数组并按以下方式请求其结果:
StatMonitor::GetInstance()->PrintAllStats();
我要走正确的路吗?
答案 0 :(得分:2)
您的路径听起来不错,除了FrequencyMonitor
和PeriodMonitor
不应从“管理”所有这些监视器的类派生而来(我们称之为MonitorPrinter
)。
MonitorPrinter
应该是一个单例,可能看起来像这样:
class MonitorPrinter
{
public:
static MonitorPrinter& getInstance()
{
static MonitorPrinter monitorPrinter;
return monitorPrinter;
}
void printAllStats()
{
for (const auto& [_, frequencyMonitor] : _frequencyMonitors)
frequencyMonitor.print();
for (const auto& [_, periodMonitor] : _periodMonitors)
periodMonitor.print();
}
FrequencyMonitor& getFrequencyMonitor(std::string name)
{ return _frequencyMonitors[name]; }
PeriodMonitor& getPeriodMonitor(std::string name)
{ return _periodMonitors[name]; }
private:
MonitorPrinter() = default;
std::map<std::string, FrequencyMonitor> _frequencyMonitors;
std::map<std::string, PeriodMonitor> _periodMonitors;
};
(const auto& [_, frequencyMonitor]
是structured binding)。
FrequencyMonitor
和PeriodMonitor
不应与单例有关,从您的描述来看,它们也不必成为类层次结构的一部分(因为它们具有不同的接口)。如果需要,可以防止用户(除MonitorPrinter
之外的用户使用其他技术来实例化这些类,但在此不再赘述。
简而言之,这里不需要使用OOP。使用单例提供(并跟踪)监视器,并根据自己的喜好实现监视器。如果有必要,请警惕线程安全(以上内容不是线程安全的!)。