Список анонимных функций или тысячи классов
Я хочу создать онлайн-викторину, которая может задать любой вопрос из тысяч запрограммированных вопросов. Каждый вопрос создается с помощью функции, которой присваивается массив int, значения которого определяют точный отображаемый вопрос. У меня есть каждый вопрос как класс:
public class AddingTwoDigitNumbers : IQuestion
{
public string QName() { return "Adding Two-Digit Numbers" };
public int[] QParams() { return int[]() {Random(10, 99), Random(10, 99) };
public void Question(int[] values) {
Console.WriteLine(string.Format("What is {1} + {2}?", values[0], values[1]);
}
public void Answer(int[] values) {
Console.WriteLine(values[0] + values[1]).ToString());
}
}
QParams
создает массив int (чтобы точно определить созданный вопрос), который задается обоим Question
а также Answer
создать вопрос и ответ.
я хочу List
вопросов для поиска по QName
но не стоит создавать (и называть) тысячи классов, все IQuestion
,
Итак, вот мое второе решение:
public class Question
{
public string QName { get; set; }
public Func<int[]> QParams { get; set; }
public Action<int[]> Question { get; set; }
public Action<int[]> Answer { get; set; }
}
public class QuestionRepository
{
public static Dictionary<string, Question> Questions = new Dictionary<string, Question>();
public static void AddQuestions(Question[] qs) {
foreach (Question q in qs) Questions.Add(q.QName, q);
}
}
public class FirstSetOfQuestions
{
static void AddQuestions()
{
QuestionRepository.AddQuestions(new Question[]
{
new Question()
{
QName = "Adding Two-Digit Numbers",
QParams = () => int[]() {Random(10, 99), Random(10, 99) },
Question = (v) => {Console.WriteLine(string.Format("What is {1} + {2}?", v[0], v[1]);},
Answer = (v) => {Console.WriteLine(values[0] + values[1]).ToString());}
},
new Question()
{
QName = "Subtracting Three-Digit Numbers",
QParams = () => int[]() {Random(100, 999), Random(100, 999) },
Question = (v) => {Console.WriteLine(string.Format("What is {1} - {2}?", v[0], v[1]);},
Answer = (v) => {Console.WriteLine(values[0] - values[1]).ToString());}
}
}
}
}
Итак, мой вопрос: что лучше? Должен ли я создавать тысячи классов, предоставляя имя для каждого, или я создаю тысячи анонимных функций и класс, который хранит их с использованием (я полагаю) делегатов? Есть ли проблема со вторым решением, если у меня есть тысячи вопросов, или даже лучший способ сделать это?
(Очевидно, что вопросы, которые я хочу создать, гораздо сложнее, чем показано здесь, и включают дроби, алгебру и т. Д.)
2 ответа
Просто, чтобы вы начали с свободного синтаксиса, добавив некоторые заглушки и идеи там.
class Question
{
public string Name { get; set; }
public string QuestionFormat { get; set; }
public List<Range> Args { get; set; }
public Expression<Func<int[], int>> ValExp { get; set; }
public Question(string name, string questionFormat)
{
this.Name = name;
this.QuestionFormat = questionFormat;
this.Args = new List<Range>();
}
public Question Rand(int min, int max)
{
this.Args.Add(new Range(min, max));
return this;
}
public void Val(Expression<Func<int[], int>> exp)
{
this.ValExp = exp;
}
public CompiledQuestion Compile()
{
// Generate args in the appropriate ranges
// Evaluate the result with the ValExp
// Return a new CompiledQuestion with the information -
// basically just replacing Args, ValExp with RealArgs, Val
}
public ICoolDataObject Save()
{
}
public static Question Load(ICoolDataObject hmm)
{
}
}
class Range
{
public int Min { get; set; }
public int Max { get; set; }
public Range(int min, int max)
{
this.Min = min;
this.Max = max;
}
}
Это почти весело, создавать вопросы сейчас:
new Question("simple addition",
"whats {0} + {1}?")
.Rand(10, 99)
.Rand(10, 99)
.Val(v => v[0] + v[1]);
Очевидно, что вы можете добавить некоторые проверки правильности, чтобы избежать неправильного количества аргументов из-за поздней работы, и использовать double
или же decimal
вместо int
где бы.
Оба подхода неверны. I presume you are not going to have thousands of different types of calculations. You are only going to have a dozen or a few dozen different types of calculations, operating on a huge variety of data.
Таким образом, вам необходимо нормализовать ваши данные, чтобы в итоге получить около десятка или нескольких десятков различных четко определенных вычислений в базе данных четко определенных данных, а затем записать около десятка или нескольких десятков классов, по одному для каждого вида. расчет только.
Вы можете подумать, что это слишком сложно, и вы можете подумать, что написание тысяч классов (или делегатов, это не имеет большого значения) может быть большой работой, но каждая часть небольшая и простая, но, поверьте мне, вы будете горько сожалеть делать это таким образом, как только что-то должно измениться в интерфейсе или реализации всех этих классов, и, скорее всего, что-то должно будет измениться в какой-то момент времени.