Что такое горячая папка?
Горячая папка — это такая же папка, как и любая другая. Горячей она становится, когда программа (которую мы будем кодировать на C++) отслеживает изменения.
Кто ее использует?
Программным входом может быть файл. Источником файла может быть оборудование, например, камера, генерирующая изображения, или стороннее программное обеспечение. Модуль следит за изменениями в папке и потребляет входные данные.
Как спроектировать?
Давайте подумаем! О том, что нам нужно:
Возможно, мы слышали о паттерне проектирования наблюдателя. Наблюдатели получают уведомления, когда Объект обновляется. Модель проектирования наблюдателя хорошо подходит для этой ситуации.
-
Наблюдатель — объект, отвечающий за получение событий от ОС об изменении папки. Скажем, наблюдающий за папкой. Наблюдатель является субъектом, потому что наблюдатель ведет себя как субъект, который получает обновления и уведомляет наблюдателей.
-
Слушатель обновлений — объект, хранящий список изменений, полученных от Субъекта. Слушатель обновлений является Наблюдателем. Модуль слушает субъекта и добавляет предстоящие изменения в потокобезопасную коллекцию. Это необходимо, почему? Потому что предположим сценарий, когда производитель производит N файлов в секунду, но когда у вас нет никакого слушателя, как модуль, то вы можете пропустить события при обработке предыдущих.
-
Handler — Object инстанцирует объект приемника и слушателя соответственно.
Давайте начнем!
Сначала мы определим два основных интерфейса ‘ISubject’ и ‘IObject’.
template <typename T>
class ISubject
{
public:
ISubject() = default;
virtual ~ISubject() = default;
virtual AddObserver(const IObserver<T>* pObserver) = 0;
virtual RemoveObserver(const IObserver<T>* pObserver) = 0;
virtual NotifyObservers(const T& data) = 0;
};
template <typename T>
class IObserver
{
public:
IObserver() = default;
virtual ~IObserver() = default;
virtual Uptdate(const T& data) = 0;
};
class DirectoryWatcher : public ISubject
{
protected:
std::string _strDirectory;
HANDLE _pChangeHandle;
bool IsHandleValid();
void Reset(const std::string& strDirectory);
public:
DirectoryWatcher();
~DirectoryWatcher();
bool Start(const std::string& strDirectory);
void Stop();
void AddObserver(const IObserver<std::string>* pObserver);
void RemoveObserver(const IObserver<std::string>* pObserver);
void NotifyObservers(const T& data);
};
class UpdateListener : public IObserver
{
protected:
code_machina::BlockingCollection<std::string> _changeCollection;
public:
UpdateListener();
~UpdateListener();
bool Start(const std::string& strDirectory);
void Stop();
void AddObserver(const IObserver<std::string>* pObserver);
void RemoveObserver(const IObserver<std::string>* pObserver);
void NotifyObservers(const T& data);
};
Пожалуйста, прокомментируйте для получения дополнительной информации!