【发布时间】:2018-01-03 15:02:24
【问题描述】:
我有一个系统,其中单例对象负责在其他非单例类之间创建和共享对象。例如:
// One instance is shared between multiple instances
// of Widget that have the same ID.
class Lease {};
// For each unique Widget instance that has the same
// value for `m_id`, the Controller will either
// create a new Lease (if one has not already been
// created) or it will return an existing one.
class Widget
{
private:
unsigned m_id{};
std::shared_ptr<Lease> m_lease;
};
// Singleton object that is used by all instances of
// Widget to obtain shared instances to Lease
class Controller
{
public:
std::shared_ptr<Lease> CreateLease(unsigned id);
private:
std::map<unsigned, std::weak_ptr<Lease>> m_leases;
};
这是我目前所拥有的要点。如果地图中不存在给定 ID 的新租约,Controller 所做的是创建一个新租约。如果确实存在,则返回现有的共享对象。
我有一个计时器,它会定期检查 m_leases 映射中的“过期”弱指针,如果是,将删除它们。这意味着在某些时候,多个小部件被销毁,随后也释放了它们的租约。
现在您已经有了一些背景知识,我想我在这里拥有的是一个比普通工厂更智能的工厂(控制器):它跟踪实例的创建,并且仅根据某些业务规则创建新实例(具体来说,如果在地图中找到匹配的 ID)。我不确定这是否是我正在尝试做的最佳设计(即:在 Widget 的唯一实例之间共享 Lease 实例的某种机制)。我不喜欢这个解决方案的几点:
- 需要单例作为 Widget 实例获取租约的联系点
- 使用计时器来管理地图:没有我能想到的基于事件的方法来管理从地图中删除过期租约。
- 继续 #2:因为我使用计时器来管理地图中的租约到期,所以即使租约到期,地图中也始终存在一个小窗口,这意味着
CreateLease()也必须检查如果weak_ptr已过期,如果找到现有 ID 映射,则在返回之前。
我觉得这个逻辑是错误的。我需要对这个想法有更多的关注,最好是推荐更好的模式来解决这个问题。
【问题讨论】:
-
“我有一个计时器,它会定期检查 m_leases 映射中的“过期”弱指针,如果是,则将其删除。这意味着在某些时候,多个 Widget 被销毁了” i>:当您将
weak_ptr存储在map中时,您的地图清理(删除nullptrweak_ptr)不会释放小部件。这只是对map的优化。
标签: c++ design-patterns