gpt4 book ai didi

python - 消除 "Game"单例中的耦合和全局状态

转载 作者:太空狗 更新时间:2023-10-30 01:30:02 25 4
gpt4 key购买 nike

我正在开发一款游戏(编写我自己的物理引擎),并尝试在编写游戏时遵循良好的设计。最近,我遇到了很多难以发现的错误,为了更容易发现这些错误,我一直在尝试编写单元测试。这很难做到,因为我的很多组件都是紧密耦合的,尤其是 game 模块。

在我的 game 模块中,我导出了一个单例类实例,它保存了当前的游戏状态、时间、游戏事件等。但是,在阅读之后 this通过研究如何减少这种耦合,我决定尝试重写类,使其不再是单例。

想法是使用 GameState 类,并在各处传递这些对象,以便单元测试可以为测试创建最小状态。大多数功能然后只是成为游戏状态的功能,并返回一个新的游戏状态。但是,我遇到了一些设计问题:

我的实体对象的位置和速度是根据当前时间计算的 python 属性。这意味着我不能简单地传入一个 GameState 对象而不将其重写为函数(导致语法错误)。代码示例:

class Entity:
@property
def position(self):
"""Interpolate the position from the last known position from that time."""
# Here, the game class instance is referenced directly, creating coupling.
dt = game.game_time - self._last_valid_time
# x_f = x_i + v_i*t + 1/2 at^2
return self._position + self._velocity * dt + .5 * self._acceleration * dt**2

我已经研究了如何解决这个问题,并遇到了 Dependency Injection .本质上,我可以将 GameState“getter”对象传递到每个实体的初始化程序中。所有 GameState 的“getter”对象都会简单地返回当前状态。 GameStateGetter 类示例:

class GameStateGetter:
_CurrentState = None

def update(self, new_state):
GameStateGetter._CurrentState = new_state

def __getattr__(self, name):
# GameState object properties are immutable, so this can't cause issues
return getattr(GameStateGetter._CurrentState, name)

现在回答我的问题。

  • 使用 GameState“getter”对象会是个好主意吗?

一个问题是用于更新当前游戏状态的接口(interface)(我已经定义了一个update 方法,但这似乎是一个奇怪的接口(interface))。此外,鉴于全局变量的问题是不可预测的程序状态,这并不能真正阻止它。

  • 是否有另一种方法可以将 game 依赖项“注入(inject)”到 Entity 类的 position 属性?

理想情况下,我想让事情变得简单。 GameStateGetter 类听起来很抽象(即使实现很简单)。如果我的属性可以隐式传递当前状态就好了。

在此先感谢您提供的任何帮助!

最佳答案

GameStateProvider 注入(inject)到 Entity 构造函数中是一个非常简单的起点,当您的逻辑变得更加复杂时,它会为您留下一些可以重构的东西。

不过,当状态发生变化时,无需为每个Entity 更新一个新状态。如果提供者是一个对象,默认情况下它是可变的。 (为什么你想要一些一直在变化的东西,游戏状态,是不可变的,无论如何?)你可以改变提供者的 current_time 属性,然后任何时候有东西得到 position 它将包含正确的值。

模式看起来像这样:

class Entity(object):

def __init__(self, game_state_provider):
self.provider = game_state_provider

@property
def position(self):
# lazily evaluate position as a function of the current time
if self._last_valid_time == self.provider.current_time:
return self._position
self._last_valid_time = self.provider.current_time
self._position = // insert physics here
return self._position

关于python - 消除 "Game"单例中的耦合和全局状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10555293/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com