Общие указатели объектов, построенных Фабрикой, которые могут исчезнуть
У меня есть ресурс, скажем, последовательный порт.
- Этот ресурс не всегда может присутствовать и может время от времени меняться. (Завод)
- Только один объект может получить доступ к этим ресурсам одновременно (мьютексы)
- Этот ресурс используется разными объектами. (умные указатели)
- Этот ресурс может исчезнуть сам по некоторым причинам, кто-то отключил "ресурс".
Я имею в виду UML-дизайн, который бы выглядел так:
<SingleTone> <Abstract>
+------------------------------+ +-----------+ +-----+
¦ Factory ¦ *m_pRes ¦ Ressource ¦ <¦-------- ¦ ResA¦
+------------------------------+ <o>----------> +-----------+ +-----+
¦ Ressource* createRessource() ¦ ^ ^
+------------------------------+ ¦ ¦
^ ^ ¦ ¦
<uses> ¦ ¦ +---------+ *m_pRes ¦ ¦
¦ +------¦ ObjectA ¦ < >-----------------+ ¦
¦ +---------+ ¦
¦ +---------+ *m_pRes ¦
+--------¦ ObjectB ¦ < >----------------------+
+---------+
Я позволю фабрике отвечать за "новый / удалить". Однако я столкнулся с большой проблемой. Как убедиться, что все объекты больше не будут указывать на этот ресурс, когда я буду вызывать delete из Factory и избегать висящего указателя? Должен ли я также реализовать своего рода "прослушиватель свойств", и когда я хочу "удалить" свой ресурс из моей фабрики, сообщить всем держателям о том, что он исчез, и "освободить" указатель (установить его в ноль)? Это звучит довольно сложно, может быть, есть лучший способ...
Да, я буду использовать C++ программирование...
3 ответа
Вы можете добавить еще один слой косвенности и иметь Resource
объект действует как посредник RealResource
объект. Когда RealResource
экземпляр удален / изменен, только Resource
объект должен быть обновлен. Клиенты всегда имеют действительный указатель на Resource
прокси, который может сказать, находится ли он в работоспособном состоянии или нет.
+----------+ +-----------+ +--------------+ +------+
| ClientA |< >---+----| Resource |<o>------| RealResource |<|----| ResA |
+----------+ | +-----------+ +--------------+ +------+
| | isValid() | | use() |
+----------+ | | use() | +--------------+
| ClientB |< >---' +-----------+
+----------+
Одним из многих решений этой проблемы может быть использование boost slow_ptr.
Когда ресурс уничтожен, экземпляры объектов с членами-данными слабого_предприятия обнаружат, что ресурс пропал. При этом условии они либо не будут выполнять логику, которую они будут иметь, либо запросят новую ссылку из какого-либо источника.
Вы можете использовать какое-то программирование, управляемое событиями, при котором события уничтожения / создания ресурса генерируются фабрикой. Все объекты, заинтересованные в этом событии, будут зарегистрированы на нем. В обработчиках событий они могут получить указатели на новый ресурс.
Вы можете использовать boost:: сигналы для объекта подписчик / издатель.