有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

状态模式中字段注入的java替代方案

我正在开发一个游戏,游戏由介绍、菜单、加载、游戏等状态组成。。。这些状态由状态管理器交换(或置于彼此之上),状态管理器在状态本身内调用,因为每个状态对管理器的引用如下:

class IntroState extends State {
    //....
    void update() {
        showIntro();
        if(done) {
            stateManager.swapState(new MenuState())
        }
    }
    //....
}

我相信这是“状态模式”,但如果我错了,请纠正我

某些状态对设置和输入配置等有一定的依赖性,这些设置和输入配置从平台特定模块发送到游戏核心模块(例如,PC平台有键盘控制,而手机有触摸控制),因此它们不是也不应该是静态的

最初,我将这些依赖项作为构造函数参数传递,但后来我遇到了某些情况,例如我的加载状态(在加载资源时只呈现典型的加载屏幕)需要有它们不使用的依赖项,以便可以将它们传递给确实依赖它们的状态。然后我添加的特性越多,依赖项列表就越大

这看起来很糟糕,所以我使用反射创建了一个简单/幼稚的字段注入器,它可以工作,但是反射在安卓上非常慢,我不太喜欢反射

我曾经简要地考虑过Dagger2DI框架,它不使用反射,并且保证了可靠的性能,但是注释生成的代码和繁重的汇编样板很快就让我放弃了它

因此,我正在寻找关于如何在没有构造函数混乱或基于反射的字段注入的情况下发送/请求状态的某些依赖项的建议


共 (1) 个答案

  1. # 1 楼答案

    我也遇到过这个问题,发现最简单的解决方案是最好的:将所有游戏服务收集到一个类中

    与其说是这样,不如说:

    State mainMenuState = new MainMenuState(inputService, renderingService, gameStateService);
    State loadingState = new MainMenuState(renderingService, gameStateService);
    // etc...
    

    这样做:

    State gameServices = new GameServices(inputService, renderingService, gameStateService);
    
    State mainMenuState = new MainMenuState(gameServices);
    State loadingState = new MainMenuState(gameServices);
    // etc...
    

    而且GameServices看起来像这样:

    public final class GameServices {
    
        public final InputService inputService;
        public final RenderingService renderingService;
        public final GameStateService gameStateService;
    
        public GameServices(final InputService inputService, 
            final RenderingService renderingService, 
            final GameStateService gameStateService) {
    
            this.inputService = inputService;
            this.renderingService = renderingService;
            this.gameStateService = gameStateService;
        }
    }
    

    我最初担心的是,现在每种状态都可以访问每种游戏服务。然而,这在实践中从未被证明是一个问题;您的IDE可以在进行重大更改之前检查类的使用情况

    至于跨平台逻辑,只需将其抽象到接口后面即可。例如,“InputService”可以在每个平台上有不同的实现

    游戏编程最难的部分之一是知道何时停止工程。请记住,您提供的是一个游戏,而不是一个库。:)