ООП для глобального класса мониторинга системы / задачи - PullRequest
0 голосов
/ 07 июня 2019

Я пытаюсь создать своего рода монитор производительности для работы на плате частиц (на основе STM32). Я привык к программированию на c, поэтому подход ООП немного нов, но я думаю, что он хорошо подошел бы здесь.

Для целей этого вопроса давайте предположим, что у меня есть два типа мониторов:

  1. Частота. Приложение может вызвать «тиковый» метод монитора, чтобы вычислить время с момента его последнего запуска и сохранить его.
  2. Период - вызовите метод «Пуск» и «Стоп» монитора, чтобы рассчитать, сколько времени потребуется процессу для его запуска и сохранения.

То, что я хотел бы сделать, - это создавать экземпляры этих мониторов в моем приложении и иметь возможность сообщать статистику всех мониторов всех типов из основного модуля.

Я читал о шаблоне проектирования синглтона, который, кажется, может быть тем, что мне нужно, но я не уверен, и я также обеспокоен безопасностью потоков с этим.

Я думаю, что создам класс "StatMonitor" и производные классы "FrequencyMonitor" и "PeriodMonitor". Монитор был бы единичным, и везде, где я хотел создать новый монитор, я запрашивал экземпляр «Монитора» и использовал его следующим образом:

freqMonitor * task1FreqMonitor = StatMonitor::GetInstance()->Add_Freq_Monitor("Task1");

StatMonitor будет отслеживать все добавленные мной мониторы, и когда я захочу распечатать статистику, я могу просто вызвать метод printAll, который будет выполнять итерацию массива мониторов и запрашивать их результаты следующим образом:

StatMonitor::GetInstance()->PrintAllStats();

Я иду по правильному пути?

1 Ответ

2 голосов
/ 07 июня 2019

Ваш путь звучит хорошо, за исключением того, что 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] - это структурированное связывание ).

FrequencyMonitor и PeriodMonitor не должны иметь ничего общего с синглетами, и, согласно вашему описанию, они также не должны быть частью иерархии классов (поскольку они имеют разные интерфейсы). Если вы хотите, вы можете запретить пользователям (за исключением MonitorPrinter) создавать экземпляры этих классов, используя другие методы, но я не буду подробно останавливаться на этом здесь.

Короче говоря, здесь нет необходимости использовать ООП. Используйте одноэлементную систему для предоставления (и отслеживания) мониторов и применяйте их по своему вкусу. Будьте осторожны с безопасностью нитей, если это актуально (вышеизложенное не безопасно для нитей!).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...