我目前正在尝试学习 SOLID 设计原则以及行为驱动开发,但我很难理解单一责任原则。我试图为使用测试驱动开发的 c# 找到一个很好的教程,但在这方面找不到任何有价值的东西。无论如何,在花了几天时间阅读之后,我决定最好的学习方式是通过经验,所以我开始尽我所能使用这些原则创建一个小应用程序。
这是一个简单的保龄球得分计算器。我认为最好的方法是从最简单的部分开始,所以我从球(或投掷)层面开始。现在我已经创建了测试以及处理球(投掷)分数的接口和类,以确保它们不是无效的,即。<10
或>0
。在实现这个之后,我意识到球类基本上只是一个可以为空的整数,所以也许我什至不需要它......但现在它就在那里。
继球之后,我决定添加的下一个合乎逻辑的东西是框架接口和类。这就是我卡住的地方。这是我所在的位置:
namespace BowlingCalc.Frames
{
public interface IFrame : BowlingCalc.Generic.ICheckValid
{
void AddThrow(int? score);
int? GetThrow(int throw_number);
}
}
namespace BowlingCalc.Frames
{
public class Frame : IFrame
{
private List<Balls.IBall> balls;
private Balls.IBall ball;
private int frame_number;
public Frame(Balls.IBall ball, int frame_number)
{
this.ball = ball;
this.frame_number = frame_number;
balls = new List<Balls.IBall>();
check_valid();
}
public void AddThrow(int? score)
{
var current_ball = ball;
current_ball.Score = score;
balls.Add(current_ball);
}
public int? GetThrow(int throw_number)
{
return balls[throw_number].Score;
}
public void check_valid()
{
if (frame_number < 0 || frame_number > 10)
{
throw (new Exception("InvalidFrameNumberException"));
}
}
}
}
框架使用我之前实现的球类通过依赖注入将球得分添加到框架中。它还实现了一种方法来返回帧中任何给定球的得分。
我想要做的,以及我被困的地方,是我想添加一种方法来确保帧分数是有效的。(目前只是第 1-9 帧的简单情况,其中两个球的总分必须为 10 或更少。稍后我将继续讨论更复杂的第 10 帧情况。)
问题是我不知道如何以可靠的方式实现这一点。我正在考虑将逻辑添加到类中,但这似乎违背了单一责任原则。然后我想将它添加为一个单独的接口/类,然后在其分数更新时在每一帧上调用该类。我还想过创建一个单独的接口IValidator
或类似的东西,并在 Frame 类中实现它。不幸的是,我不知道其中哪一种(如果有的话)是最好的/可靠的做事方式。
那么,什么是一个好的、可靠的方法来实现一个验证帧分数的方法呢?
注意:非常欢迎对我的代码提出任何批评。我很高兴学习创建更好的代码,并且很高兴收到任何帮助。