Список анонимных функций или тысячи классов

Я хочу создать онлайн-викторину, которая может задать любой вопрос из тысяч запрограммированных вопросов. Каждый вопрос создается с помощью функции, которой присваивается массив 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.

Таким образом, вам необходимо нормализовать ваши данные, чтобы в итоге получить около десятка или нескольких десятков различных четко определенных вычислений в базе данных четко определенных данных, а затем записать около десятка или нескольких десятков классов, по одному для каждого вида. расчет только.

Вы можете подумать, что это слишком сложно, и вы можете подумать, что написание тысяч классов (или делегатов, это не имеет большого значения) может быть большой работой, но каждая часть небольшая и простая, но, поверьте мне, вы будете горько сожалеть делать это таким образом, как только что-то должно измениться в интерфейсе или реализации всех этих классов, и, скорее всего, что-то должно будет измениться в какой-то момент времени.

Другие вопросы по тегам