我有一个简单的小游戏,用户可以给出简单的答案简单的问题和程序将给出一个结果。拜托,伙计们,做个代码复习,如果有可能的话,回答我的问题放在最下面。
Model类如下所示:
public class Answer
{
public Answer(int id, int questionId, string content)
{
Id = id;
Content = content;
QuestionId = questionId;
}
public int Id { get; private set; }
public int QuestionId { get; private set; }
public string Content { get; private set; }
}
public class Question
{
public Question(int id, string content, char answer)
{
Id = id;
Content = content;
Answer = answer;
}
public int Id { get; private set; }
public string Content { get; private set; }
public char Answer { get; private set; }
}摘要:
interface IAnswerService
{
List> GetAnswers();
}
interface IQuestionService
{
IList GetQuestions();
}
public interface ICalculationService
{
int CalculatePoints(Dictionary userAnswers);
}常数:
public static class Constants
{
public static class Answers
{
public const char A = 'a';
public const char B = 'b';
public const char C = 'c';
public const char D = 'd';
}
}Core服务:
static class Factory
{
public static T CreateInstance() where T : new()
{
return new T();
}
}服务:
public class AnswerService : IAnswerService
{
public List> GetAnswers()
{
return new List>() {
new List() { new Answer(11, 3, "Sequoia"), new Answer(12, 3,
"Berch"), new Answer(13, 3, "Lindens"), new Answer(14, 3, "Alder") },
new List() { new Answer(1, 1, "1"), new Answer(2, 1, "2"),
new Answer(3, 1, "5"), new Answer(4, 1, "6") },
new List() { new Answer(7, 2, "More than 1"), new Answer(
8, 2, "More than 2"), new Answer(9, 2, "More than 5"),
new Answer(10, 2, "More than 6") },
new List() { new Answer(15, 4, "yes, I do!"), new
Answer(16, 4, "Sure!"), new Answer(17, 4, "Exactly"), new
Answer(18, 4, "Yeap!") }
};
}
}CalculationAnswerByAdding服务类别:
class CalculationAnswerByAdding : ICalculationService
{
public int CalculatePoints(Dictionary userAnswers)
{
var sum = 0;
foreach (var question in userAnswers)
{
if (question.Key.Answer == question.Value)
sum += 1;
}
return sum;
}
}服务CalculationAnswerBySubtracting:
class CalculationAnswerBySubtracting : ICalculationService
{
public int CalculatePoints(Dictionary userAnswers)
{
var sum = 10;
foreach (var question in userAnswers)
{
if (question.Key.Answer == question.Value)
sum -= 1;
}
return sum;
}
}
public class QuestionService : IQuestionService
{
public IList GetQuestions()
{
return new List() {
new Question(1, "How many are there contintents?",
Constants.Constants.Answers.A),
new Question(2, "How many are there colours?", Constants.Constants.Answers.B),
new Question(3, "What is the tallest tree?", Constants.Constants.Answers.C),
new Question(4, "Do you like dolphins?", Constants.Constants.Answers.D),
};
}
}And Program.cs:
Main()方法Program.cs:
static void Main(string[] args)
{
IQuestionService questionService = Factory.CreateInstance();
var questions = questionService.GetQuestions();
IAnswerService answerService = Factory.CreateInstance();
var answers = answerService.GetAnswers();
var questionAnswers = questions.ToDictionary(q => q,
q => answers
.SelectMany(a => a)
.Where(b => b.QuestionId == q.Id)
.ToList());
var userAnswers = new Dictionary();
GetAsnwers(questionAnswers, userAnswers);
ICalculationService calculationService = Factory
.CreateInstance();
var userSum = calculationService.CalculatePoints(userAnswers);
Console.WriteLine(userSum > 3 ? $"Yeah, it is great. Your points are {userSum}."
: $"Hey, it is great. Your points are {userSum}");
}GetAsnwers()方法Program.cs:
private static void GetAsnwers(Dictionary>
questionAnswers, Dictionary userAnswers )
{
foreach (var questionAnsw in questionAnswers)
{
AskQuestion(questionAnsw);
List allowedAnswers = new List()
{
Constants.Constants.Answers.A,
Constants.Constants.Answers.B,
Constants.Constants.Answers.C,
Constants.Constants.Answers.D,
};
while (true)
{
var userKey = Console.ReadKey().KeyChar;
Console.WriteLine();
if (!allowedAnswers.Contains(userKey))
{
AskQuestion(questionAnsw, true);
}
else
{
userAnswers.Add(questionAnsw.Key, userKey);
break;
}
}
}
}AskQuestion()方法Program.cs:
private static void AskQuestion(KeyValuePair> questionAnswer,
bool showPossibleKeys = false)
{
if (showPossibleKeys) {
Console.WriteLine();
Console.WriteLine("Possible keys are A, B, C or D");
}
Console.WriteLine(questionAnswer.Key.Content);
questionAnswer.Value
.ForEach(a => Console.WriteLine(a.Content));
}伙计们,请看我的密码。我的代码可靠吗?我是否正确地使用策略和工厂模式?如有任何改进和评论,我们将不胜感激。
另外,我的课程组织得好吗?特别是,我把Factory移到CoreServices文件夹中可以吗?还是有更好的方法来组织课程?

发布于 2018-12-28 18:41:03
我不会问‘我使用模式X正确吗?’,我会问‘模式X为我的问题提供了一个很好的解决方案吗?’要回答这个问题,你需要考虑你的程序的要求。你为什么认为这个计划需要战略、服务和工厂?
Main必须做额外的工作来匹配问题的答案。{ get; }现在已经足够了。我会选择以下内容(为了简洁起见,我省略了构造函数,而I,因为它们似乎不是必要的):
public class Question
{
public string Content { get; }
public IReadOnlyCollection AvailableAnswers { get; }
public Answer CorrectAnswer { get; }
}
public class Answer
{
public string Content { get; }
}请注意,Answer类现在只包含一个字符串,因此您可以删除它,直接将应答字符串的集合存储在Question中,以及正确答案的索引。
Result类,它可以用来跟踪用户正确回答和错误回答了多少问题。这将为这些计算算法提供更高层次的概述,并减少代码重复。CalculationAnswerBySubtracting中的硬编码10看起来确实有问题--当然,这应该是可配置的吗?new来增加任何价值。如果它的目的是模拟DI容器:通常您要求容器提供“抽象”接口的具体实现,而不是反过来。Answers.A和'A'都是引用答案的同样模糊的方式。给这样的问题贴上标签是一个UI细节,不应该泄露到程序的其他部分。此外,使用这些常量,您可以对每个问题的4个答案进行硬编码,这似乎是一个不必要的限制。AskQuestion不使用这些常量,因为它们的值是小写的,而不是大写的,这可能导致拒绝似乎有效的输入(尝试按shift +A键而不是只按A键)。Service和Factory后缀。我会使用像IQuestionRepository和IScoreCalculator这样的名字--更多的描述性,更少的混乱。foreach (var question in userAnswers)中,question实际上不是一个Question,而是一个键值对,所以这个名称有点误导。无论如何,字典可能不是传递这些信息的最好方法--它不会保留顺序,而且您不需要它的查找功能,您只需要一组问答对。GetAsnwers‘返回’结果通过修改它的一个参数..。为什么它不返回其结果,这也是大多数程序员期望的结果?Question作为键,而不覆盖Equals和GetHashCode,可能会导致问题。因为现在您没有使用不同(但相同)的Question实例进行任何键查找(实际上根本没有键查找),所以当前的代码工作正常,但这很容易导致将来的问题。https://codereview.stackexchange.com/questions/210472
复制相似问题