【问题标题】:C++ proper singleton use caseC++ 正确的单例用例
【发布时间】:2019-06-17 02:01:11
【问题描述】:

我正在制作一款游戏来练习良好的设计/架构,并且我认为我将自己编程为检查。我不确定我的架构现在是否干净,一些建议会很重要。

我有一个class Game,其中包含class GraphicsManager class InputManagerclass StateManager 的实例

图形管理器与输入管理器一样处理 sdl 内容。状态管理器是抽象类型的堆栈class GameState

每一帧,游戏都会在状态堆栈顶部的 GameState 上调用 update 并将状态管理器指针传递给该状态,以便 GameState 可以推送新状态或从堆栈中弹出自身。

GameState* currentState = stateManager.getState() //return top currentState.update(&stateManager) // state might change here

问题是当我介绍我的class Screen 时。 Screen 应该归 GameState 的各种实现所有,所以如果我有 OpeningState,我希望它拥有 OpeningScreen。 问题是,Screen 需要访问 Graphics 实例以获取指向 SDL_Renderer 的指针,而我看不到向下传递该指针的好地方。从 Game --> GameState --> Screen 传递指针感觉有点时髦。

我觉得我需要将每个“经理”变成一个单身人士,但如果有更优雅的东西我很想学习

这是我的 ref https://github.com/MicahMartin/FightingGame/tree/master/src 的意大利面条代码

【问题讨论】:

    标签: c++ oop architecture stl singleton


    【解决方案1】:

    您可以使用单例而不是显式注入依赖项,但请注意,这种设计会导致代码的可测试性降低和组件之间的高功能耦合。其他生态系统已经解决了这个问题,引入了以声明方式注入依赖项的方法,这要归功于提供用“测试替身”替换实际依赖项的机制的框架。查看 Spring MVC 如何与 Java 应用程序一起工作。

    如果您确定这是您所需要的,您可以使用类似(但仍然不太灵活)的方法来实现“服务定位器”模式,该模式包含一个单点,该点包含指向“可注入”对象实例的指针

    ServiceLocator::inject<Screen*>(new Screen () , "screen1")
    
    //
    
    ...
    
    //
    Screen* s = ServiceLocator::getInstance<Screen*>("screen1")
    

    通过这种方式,您可以避免传递指针,同时更加解耦。现在假设您有一个从 Screen 继承的 MockScreen。还假设您要测试方法 int MyClass::workWithScreen(),它依赖于使用标签“screen1”引用的 Screen 实例。你可以写你的测试像

    Myclass unitUnderTest;
    ServiceLocator::inject<Screen*>(new MockScreen () , "screen1");
    
    int result = unitUnderTest.workWithScreen()
    
    assert ....
    

    我将把你作为练习来实现服务定位器!

    请记住,通过这种方式,您在代码中也引入了依赖注入的缺点:最糟糕的是您失去了对组件布局设计的控制,每个对象都可以访问每个对象。当您开发一些基于可靠且众所周知的架构模式(控制器 -> 服务 -> 存储库 -> db 然后返回)的 REST api 处理程序时,这不是一个大问题,但在其他情况下您必须小心!

    【讨论】:

    • 非常感谢您的建议!每个人都告诉我只带一个单身人士,但这很漂亮,你是最好的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-04
    • 1970-01-01
    • 1970-01-01
    • 2011-09-23
    • 2013-11-07
    • 1970-01-01
    相关资源
    最近更新 更多