单身人士的替代方案

时间:2012-11-29 15:17:12

标签: c++ oop design-patterns

我有一个非常简单的游戏引擎。它使用了几个单例(我会列举其中的一些)。

Resource Manager
Render Engine
Events Manager
Factory
etc

这些单身人士从一个人到另一个人有很多电话。我将采用事件管理器样本用法:

  1. 从Listener派生的任何对象都可以将itsel添加为某些事件的侦听器,就像这样EventsManager->RegisterListener(this, &SomeClass::SomeMethod);(事件类型由SomeMethod参数推断)
  2. 任何其他对象都可以触发此事件EventsManager->PushEvent(SomeEvent);
  3. 在一些同步之后,事件将到达所有侦听器。当EventsManager是singleton时,这是一个非常简单的用法。

    与其他单身人士类似的行为。我想删除单例,但我的主要问题是我想从现在的“用户观点”保持代码简单易用。我阅读了一些这样做的技巧,但大多数使类的初始化/使用更加复杂。我知道这个主题在SO上被多次讨论,但没有答案适合我的编程理念 - 尽可能保持一切尽可能简单。

    我不希望我的类具有复杂的定义/初始化,如:

    SomeClass<EventManager, RenderEngine,...>
    

    SomeClass::SomeClass(EventsManager, RenderEngine...)
    

    你能就这个话题给我一些建议吗?

3 个答案:

答案 0 :(得分:2)

你可以有一个全局“游戏”对象,它创建当前单身人士的每个类的实例

对于EventManager的具体示例;您的Listener基类可以提供寄存器方法和派生类可以调用的push方法的实现。

骨架定义:

class Listener
{
public:
    virtual void ReceiveMessage( ... ) = 0;

protected:
    void Register()
    {
        GetEventManagerSomehow()->RegisterListener( this, etc );
    }

    void PushEvent( etc )
    {
        GetEventManagerSomehow()->PushEvent( etc );
    }

}

答案 1 :(得分:1)

要解决检测单例中资源泄漏的具体问题,请为每个单例类提供一个销毁实例的关闭方法。

class Singleton
{
    // ...
    static Singleton * GetInstance()
    {
        if (instance == NULL)
            instance = new Singleton;
        return instance;
    }
    static void Shutdown()
    {
        delete instance;
        instance = NULL;
    }
    static Singleton * instance;
};

Singleton * Singleton::instance = NULL;

答案 2 :(得分:0)

不是一个真正的答案,但评论可能太长了。

Dependency injection是单身人士的一个很好的替代方案:你在程序的main函数中创建实例,然后将它们传递给“modules”(它们是主类),这样他们就可以在本地使用它们。这意味着对于这些类,您将拥有您不需要的“复杂”构造函数 但是,复杂性应仅限于某些类,并且传递一些依赖的“模块”在我看来并不复杂。作为奖励,您可以通过查看构造函数或main函数来找出模块之间的依赖关系。

依赖注入被大量使用,因为它确实解决了您所看到的问题(以及更多,例如单元测试),只增加了非常有限的复杂性。