c++ - 共享对象工厂的设计模式

标签 c++ design-patterns

我有一个系统,其中一个单例对象负责在其他非单例类之间创建和共享对象。例如:

// 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;
};

这是我目前所拥有的要点。 Controller 所做的是创建一个新的租约,如果给定 ID 的映射中不存在的话。如果确实存在,则返回现有的共享对象。

我有一个计时器,它定期检查 m_leases 映射中是否存在“过期”的弱指针,如果是,将删除它们。这意味着在某个时候,多个小部件被销毁,随后也释放了它们的租约。

现在您已经了解了一些背景知识,我想我这里有一个比普通工厂更智能的工厂( Controller ):它会跟踪创建的实例,并且只根据特定的业务规则创建新的实例(具体来说,如果在 map 中找到匹配的 ID)。我不确定这是否是我正在尝试做的事情的最佳设计(即:一些在 Widget 的唯一实例之间共享 Lease 实例的机制)。这个解决方案有几点我不喜欢:

  1. 需要一个单例作为 Widget 实例获取 Lease 的联系点
  2. 计时器用于管理 map :我没有想到基于事件的方法来管理从 map 中删除过期租约。
  3. 继续 #2:因为我使用定时器来管理 map 中的租约到期,所以总是有一个小窗口,租约即使在到期后仍保留在 map 中,这意味着 CreateLease() 还必须检查 weak_ptr 是否过期,如果找到现有的 ID 映射,则返回它。

我觉得这个逻辑不对。我需要更多的关注这个想法,最好是推荐更好的模式来解决这个问题。

最佳答案

我会在析构函数中广播租约 - 观察者模式。

这将允许 Controller 注册一个观察者以删除租约并将其删除。这消除了您对计时器的需要,并引入了事件的概念;满足 2 和 3。

至于 Controller 是单例的,从你发布的内容来看,它可以嵌套到Widget中并设为私有(private)(或移动到Widget的cpp文件中)。虽然这最终仍将是一个单例,但由于它的范围有限,它是一个更受控制并且以后可以轻松替换的单例。

如何将其组合在一起的示例:

class Lease {
public:
    struct listener {
        virtual void leaseGone(int id) = 0;
    }

    void addListener(listener* l) {
        listeners.push_back(l);
    }

    ~Lease() {
        for (auto x&: listeners)
            x->leaseGone(myId);
    }
 }


class Controller : Lease::listener {
    void leaseGone(int id) {
        m_leases.erase(id);
    }
}

关于c++ - 共享对象工厂的设计模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48079956/

相关文章:

user-interface - UI 代码级别模式?

c++ - 找不到我的着色器(Obj-C++、ios、opengles2.0)

c++ - C++中的对象大小是不可预测的

c++ - void()是有效的C++表达式吗?

java - 我可以像这样实现单例模式吗?

android - 为什么官方 Google IO 应用程序只有支持 hdpi 的可绘制对象,但在我的小型 ldpi 设备上看起来还不错?

design-patterns - 是否有针对具有指定要运行的任务类型的字段的对象的设计模式?

android - AVD 安卓 4 : support to OpenGL ES 2. 0

C++对删除错误

oop - 哪种设计模式最适合用于控制一系列步骤?