所以我想把所有重要变量外包给一个新类。 展示我正在尝试做的一个非工作的例子是:

public class GameState{
    public bool ToggleA{ get; set; }
    public bool ToggleB{ get; set; }
    public int a{ get; set; }
    public int b{ get; set; }
}

一旦设置了值并使所有内容都引用同一个实例,我怎么能“保持这个类活着”? 我的谷歌搜索引发了我的单一模式( 链接 ,然而这并没有带给我更多,要么我不明白如何正确地实现我想要做的事情,在这种情况下,一个深入的例子将是整洁的,或者我需要使用别的东西?

===============>>#1 票数:2

使它成为一个静态类。

public static class GameState ...

静态类只有一个实例。 你没有new 您可以通过类名访问它们:

GameState.ToggleA = true;
DoStuff(GameState.b);

等等

您的每个属性也必须是静态的:

public static bool ToggleA {get;set;} ...

在这种情况下,静态类基本上等同于Singleton模式。

===============>>#2 票数:1 已采纳

实现这一点的最佳方法是使用单例设计模式。 它将允许您的代码保持可测试性。

给出以下界面:

public interface IGameState
{
  bool ToggleA { get; set; }
  bool ToggleB { get; set; }
  int A { get; set; }
  int B { get; set; }
}

以下是它的单例实现:

public class GameState : IGameState
{
  // This instance variable will only ever have one copy instantiated
  private static GameState _instance = new GameState();

  // Private constructor so the class cannot be instantiated outside of the class.
  // This ensures that no other class can create an instance of the class.
  private GameState() { }

  public static GameState Instance { get { return _instance; } }

  public bool ToggleA { get; set; }
  public bool ToggleB { get; set; }
  public int A { get; set; }
  public int A { get; set; }
}

您现在可以在需要的地方注入此单例,这将保持代码的测试能力。

public class SomeObject
{
  private IGameState _gameState;
  public SomeObject(IGameState gameState)
  {
    _gameState = gameState;
  }

  public void SomeOperationOnGameState()
  {
    _gameState.ToggleA = true;
  }
}

编辑:更新以解释测试相关的评论

想象一下,您的GameState对象演变有一个复杂的方法来执行计算,并且您希望确保在必要时调用此方法。 如果您使用的是全局静态类,则无法验证此行为。 如果您正在编程接口,但是您可以使用模拟框架模拟这种依赖关系,并验证确实调用了复杂方法。

例如,我们将IGameState接口扩展为以下内容:

public interface IGameState
{
  bool ToggleA { get; set; }
  bool ToggleB { get; set; }
  int A { get; set; }
  int B { get; set; }

  int ComplexStateAlteringMethod();
}

现在假设您有某种Controller类,它管理按键操作:

public class Controller
{
  private IGameState _gameState;
  public Controller(IGameState gameState)
  {
    _gameState = gameState;
  }

  public void KeyPressed(string key)
  {
    // Implementation details go here, say you want to call the complex method when the 'A' key is pressed
    if (key == "A")
    {
      _gameState.ComplexStateAlteringMethod();
    }
  }
}

您希望确保在按下“A”键时调用IGameState.ComplexStateAlteringMethod()

在不解释IGameState ,我将创建一个Stub IGameState

public class StubGameState : IGameState
{   
  public bool ToggleA { get; set; }
  public bool ToggleB { get; set; }
  public int A { get; set; }
  public int B { get; set; }

  public bool WasStateAlteringMethodCalled { get; private set; }
  public void ComplexStateAlteringMethod()
  {
    WasStateAltermingMethodCalled = true;
  }
}

现在你可以使用这个存根类来验证你正在寻找的行为(假设NUnit是测试框架):

[TestFixture]
public class ControllerTests
{
  [Test]
  public void KeyPressed_WhenAIsPressed_ShouldCallStateAlteringMethod()
  {
    // Arrange
    var stub = new StubGameState();
    var controller = new Controller(stub);

    // Act
    controller.KeyPressed("A");

    // Assert
    Assert.IsTrue(stub.WasStateAlteringMethodCalled);
  }

  [Test]
  public void KeyPressed_WhenBIsPressed_ShouldNotCallStateAlteringMethod()
  {
    // Arrange
    var stub = new StubGameState();
    var controller = new Controller(stub);

    // Act
    controller.KeyPressed("B");

    // Assert
    Assert.IsFalse(stub.WasStateAlteringMethodCalled); 
  }
}

  ask by user3488765 translate from so

未解决问题?本站智能推荐: