我一直在学习C#,我做了一个简单的数学测验程序。
我的计划是否合理,还是有什么需要改进的地方?
class Program
{
static void Main(string[] args)
{
Console.WriteLine("============== Math Game ===================");
double num1, num2;
double userInput;
int randomIndex;
double sum = 0;
string operation;
// [2]
//int lives = 0;
// Console.Write("How many lives do you want?\t");
// lives = Convert.ToInt32(Console.ReadLine());
// Console.WriteLine("You have {0} Lives", lives);
bool isPlaying = true;
do
{
// 1 generate randon#
Random rnd = new Random();
randomIndex = rnd.Next(1, 4);
num1 = rnd.Next(1, 11);
num2 = rnd.Next(1, 11);
// 2 cal sum && operation && Display
sum = Cal(num1, num2, randomIndex);
operation = Operation(randomIndex);
// DisplayProblem(num1, num2, operation);
// 3 request input
userInput = RequestInput(num1,num2,operation);
// 4 check answer
CheckAnswer(userInput, sum);
} while (isPlaying);
}
private static double Cal(double num1, double num2, int randomIndex)
{
double sum = 0;
switch (randomIndex)
{
case 1:
sum = num1 + num2;
break;
case 2:
sum = num1 - num2;
break;
case 3:
sum = num1 * num2;
break;
case 4:
sum = num1 / num2;
break;
default:
Console.WriteLine("Error");
break;
}
return sum;
}
private static string Operation(int randomIndex)
{
string operation = "";
switch (randomIndex)
{
case 1:
operation = "+";
break;
case 2:
operation = "-";
break;
case 3:
operation = "*";
break;
case 4:
operation = "/";
break;
default:
Console.WriteLine("error");
break;
}
return operation;
}
private static void DisplayProblem(double num1, double num2, string operation)
{
Console.Write($"{num1} {operation} {num2} = ");
}
private static double RequestInput(double num1, double num2, string operation)
{
DisplayProblem(num1, num2, operation);
double userInput;
while (!Double.TryParse(Console.ReadLine(),out userInput))
{
Console.WriteLine("Invalid input. Please type a whole num");
DisplayProblem(num1, num2, operation);
}
return userInput;
}
private static void CheckAnswer(double userInput, double sum)
{
if (userInput == sum)
{
Console.WriteLine("Correct Answer.");
}
else if(userInput != sum)
{
Console.WriteLine("Wrong Answer.");
}
}
}发布于 2018-10-04 19:10:22
也许我每天看到的最糟糕的编码恐怖是在简单或简短的代码方面缺乏良好的实践。我们都是通过简单的例子来学习的,所以感觉太过分了。我们理直气壮地说:“这是一次性的”,“这太简单了,麻烦不了”,“我只是在试验。”
专注于好的基础,不要太担心坚实,模式等本身。
永远不要忘记,您是为读者和代码可维护性编写的。
static void Main(string[] args)Main应该只驱动你的程序,而不应该是程序。这使得类(Es)可移植,可重用。如下所示:
class Program {
public MathQuiz testMe = new MathQuiz();
testMe.Play(); // you'll need an entry point
} // Program
public class MathQuiz {
// all the code
} // MathQuiz方法名的一般起始位置是actionVerb-名词。和And。本身并不坏,但不能牺牲理解。Cal -可以是Calvin的缩写,也可以是日历的缩写,也可以是加利福尼亚的缩写,或者是?因此,Calc更好,但仍然不好。Calculate更好,但不多。DoTheMath很吸引人!这个方法是做什么的?这就是它的名字。
private static double Cal(double num1, double num2, **int randomIndex**)
它不是一个randomIndex,它是一个算术运算符。为它们在“问题领域”中的内容命名,在本例中是一个数学测试。我可以读取代码,但是如果所有的变量名称只是重复实现细节,我就不明白了。
Operation(int randomIndex),DecodeOperatorCode(int opCode)怎么样?只要继续倾向于描述性命名,代码就会更好。
// 3 request input userInput = RequestInput(num1,num2,operation);
我可以想象,用评论勾勒出一个大纲,但在这一点上,留下这样的评论只是普通的业余时间。这显然是多余的。它没有增加任何理解。好的结构和好的命名是值得一千评论的。
做{.}时间(IsPlaying)
我必须阅读所有的代码才能发现isPlaying从未改变过。在这里,如果能让读者知道循环不会终止,那就太好了。哦,我有没有说过我必须读所有的代码?
// [2]
//int lives = 0;
// Console.Write("How many lives do you want?\t");
// lives = Convert.ToInt32(Console.ReadLine());
// Console.WriteLine("You have {0} Lives", lives);永远不要把死代码到处乱丢。如果您想知道前面的代码状态是什么,那么使用版本控制;这就是您应该做的事情。
操作就是所做的,运算符就是它的本质。加号是运算符。添加东西是一种操作。
和按定义是加法的结果,但对于所有运算的结果(使用各种运算符)则普遍使用。但它是经常使用的(见下文),这确实减少了潜在的误解。
string.Empty更好。有时,字体和/或其大小会使您很难识别其中的任何空白。
该程序同时使用operatorCode和运算符(+,-,/,*)。保持一致,使用一个或另一个。“翻译”前面的opCode并在整个过程中使用它,反之亦然。但不是两者都是。在上下文中,使用一种或另一种可能更有意义,但一致性使代码具有更多的可读性和可理解性。
我在任何地方都能找到这些代码,而这些代码被分散在和/或复制和/或成为“繁忙”代码。这个程序中的操作符可以是一个单独的类。如果你认为这门课太小,不需要重读这篇文章的开场白。
public class MathOperators {
protected Array operators = ["x", "/", "+", "-"];
protected Random randomOpCode = new Random();
public int OperatorToOpCode(string operator) { ... }
public string OpCodeToOperator(int opCode) { ... }
public int randomOpCode(){ ... }
}
- It's re-usable and reliable (assuming it's been tested!)
- The user doesn't know or care how the operators are stored or how to retrieve them
- Easier to test
- This class has a single, focused purpose
- Functionality encapsulation is a very good thing. You'll understand more deeply as you gain experience.
- Changes are a low risk for the using (client) code. All the client code cares about is the interface - that is, all the public class members' signatures. AKA, the API.
- The Invisible Hand of good design and coding
- Classes and methods tend to be smaller and simpler.
- Complexity stays under control as code is added.发布于 2018-10-04 14:50:45
在Operation方法中
private static string Operation(int randomIndex)
{
string operation = "";
switch (randomIndex)
{
case 1:
operation = "+";
break;
case 2:
operation = "-";
break;
case 3:
operation = "*";
break;
case 4:
operation = "/";
break;
default:
Console.WriteLine("error");
break;
}
return operation;
}而不是执行operation = ...,然后返回操作,您可以只返回
例子:
case 1:
return "+";在Cal方法中也是一样的。
在CheckAnswer方法中,应该只使用else而不是else if(userInput != sum)
同样在Main中,您的Random rnd = new Random();应该不在do while循环之外。
https://codereview.stackexchange.com/questions/204921
复制相似问题