I'm trying to solve the best architecture for a survey system and which design patterns to use. We have the following type of questions:
- One correct answer is possible - dropdown or radio buttons
- Multiple choice - checkboxes
- Yes/No - radio buttons with Yes/No
- Short Text
- Long Text
- Number - e.g. When was ...?
- Correct order - e.g. order the answers in the correct order
I'd like to have Drawing API and Validating API So I came up with "Bridge Pattern" which is mostly used for drawing. But there's something I'm missing.
What I tried is this:
public abstract class Question : IDrawable, IValidatable
{
protected readonly IQuestionFormatter questionFormatter;
protected readonly IQuestionValidator validator;
public string Title { get; set; }
public Question(IQuestionFormatter questionFormatter, IQuestionValidator validator)
{
this.questionFormatter = questionFormatter;
this.validator = validator;
}
public abstract void Draw();
public abstract bool Validate();
}
public interface IQuestionValidator
{
bool ValidateQuestion(IEnumerable<string> userInput,
IEnumerable<string> questionAnswers);
}
public interface IQuestionFormatter
{
string FormatQuestion(string title, IEnumerable<string> options);
}
Then I create RefinedAbstractions for MultipleChoiceQuestion, OnePossibleAnswerQuestion and ShortAnswer. The problem is that MultipleChoiceQuestion can have many correct Answers and many UserInput.
public class MultipleChoiceQuestion : Question
{
public List<string> Options { get; set; } = new List<string>();
public List<string> Answers { get; set; } = new List<string>();
public List<string> UserInput { get; set; } = new List<string>();
public MultipleChoiceQuestion(IQuestionFormatter questionFormatter, IQuestionValidator validator) : base(questionFormatter, validator)
{
}
public override void Draw()
{
var result = questionFormatter.FormatQuestion(Title, Options);
Console.WriteLine(result);
}
public override bool Validate()
{
return validator.ValidateQuestion(UserInput, Answers);
}
}
OnePossibleAnswerQuestion has many Answers but One UserInput.
public class OnePossibleAnswerQuestion : Question
{
public string UserInput { get; set; }
public string Answer { get; set; }
public List<string> Options { get; set; } = new List<string>();
public OnePossibleAnswerQuestion(IQuestionFormatter questionFormatter, IQuestionValidator validator) : base(questionFormatter, validator)
{
}
public override void Draw()
{
var result = questionFormatter.FormatQuestion(Title, Options);
Console.WriteLine(result);
}
public override bool Validate()
{
return validator.ValidateQuestion(new List<string> { UserInput }, new List<string> { Answer });
}
}
ShortAnswer has one Answer and one UserInput. I'm not sure how to create the design. public class ShortAnswer : Question { public string UserInput { get; set; } public string Answer { get; set; }
public ShortAnswer(IQuestionFormatter questionFormatter, IQuestionValidator validator) : base(questionFormatter, validator)
{
}
public override void Draw()
{
var result = questionFormatter.FormatQuestion(Title, new List<string> { "" });
Console.WriteLine(result);
}
public override bool Validate()
{
return validator.ValidateQuestion(new List<string> { UserInput }, new List<string> { Answer });
}
}
But when I got to the OnePossibleAnswerQuestion or ShortAnswer the .Validate() .Draw() started smelling. Probably I have defined wrong interfaces?
My goal is to have something like this:
List<Question> questions = new List<Question>();
// ... add some questions using Builder or Factory Design Pattern
// draw the questions
foreach (var question in questions)
{
question.Draw();
}
// validate the questions
foreach (var question in questions)
{
question.Validate();
}
Could you please help me what I miss and how to composite the classes? Am I using the wrong design pattern?
Thanks in advance!
Aucun commentaire:
Enregistrer un commentaire