如何告诉我的类用户我的构造函数期望的有效值

时间:2014-03-29 14:23:47

标签: c# oop design-patterns

这是一个设计问题。

我正在构建一个控制台记忆游戏作为一项任务。 我们被告知我们应该将UI与业务逻辑类分开,这样当我们需要使用Windows GUI实现游戏时,我们可以尽可能地重用它。

在我的设计中,我来创建以下类:ConsoleUI,GameManager,MemoryGameBoard。

我的问题与MemoryGameBoard(高度,宽度)的有效性检查有关。 作为一个MemoryGameBoard我已经决定它应该通过确保元素的数量是偶数来检查合法性(因为我们正在处理对),并且GameManager应该检查他强加的规则(即最大行和列)尺寸必须是4/5/6)。

ConsoleUI要求用户输入此高度和宽度。并且应该继续重新询问,直到根据GameManager或MemoryGameBoard给出有效数据。

测试高度/宽度有效性的方法应该在哪里?

感谢。

3 个答案:

答案 0 :(得分:1)

我通常会尝试避免构造函数中的有效性检查。我会使用GameBoardBuilder类和构造函数GameBoardBuilder(int width, int height)以及方法IsValid()MakeGameBoard()。所以你会写:

while (true) {
   ... get input ...    
   var builder = new GameBoardBuilder(width, height);
   if (builder.IsValid()) break;
   ... report error ...
}
var gameBoard = builder.MakeGameBoard();

或使用来自用户界面的GameManager

while (true) {
    .... get input ...
    gameManager.SetBoardSize(width, height);
    if (gameManager.IsBoardValid()) break;
    ... report error ...
}
gameManager.StartGame();

其中GameManager有方法:

public void SetBoardSize(int width, int height) {
    builder = new GameBoardBuilder(width, height);
}

public bool IsBoardValid() { return builder != null && builder.IsValid(); }

public void StartGame() {
    var gameBoard = builder.MakeGameBoard();
    ...
}

答案 1 :(得分:0)

创建一个类似

的方法
public void setHeight(int height)
{
    while(height%2!=0)
    {
       Ask user
    }
    class_instancevariable_height = height;
}

public void setWidth(int width)
{
same as height
}

然后从构造函数中调用

public MemoryGameBoard(int width, int height)
{
setWidth(width); setHeight(height);
}

答案 2 :(得分:0)

我建议将验证逻辑与构造函数分开。在构造函数中,您应该强制执行验证以防止构造无效对象(这使得其余代码更容易编写)。

以下是一个例子:

class GameBoard
{
    public static bool IsValid(int width, int height, out List<string> errorMessages)
    {
        // validation logic here, e. g.
        errorMessages = new List<string>();
        if (width < 1) { errorMessages.Add("width must be a positive number");

        return errorMessages.Count == 0;   
    }

    public GameBoard(int width, int height)
    {
        var errorMessages;
        var isValid = IsValid(width, height, out errorMessages);
        // fail hard if given invalid input here
        Throw<ArgumentException>.If(
            !isValid, 
            string.Join(", ", errorMessages ?? new List<string>())
        );

        this.Width = width;
        this.Height = height;
    }
}

// in the gui code

// read input
List<sting> errorMessages;
while (!IsValid(width, height, out errorMessages))
{
    // display errorMessages
    // read input
}

Throw.If来自http://www.codeducky.org/10-utilities-c-developers-should-know-part-one/