我正在使用WinForms构建具有2种模式的简单测验程序:
1)编辑模式:用户可以在其中创建自己的问题
2)测验模式:用户需要回答问题的地方
当前有两种类型的问题:开放(问题和自由文本框)和多项选择(问题和4个可能的答案)。
我为一个问题创建了一个抽象类:
insert into animal_in_zoo (zooid, animalid)
select z.id, a.id
from zoos z cross join
animals a;
还有2个继承该类的子类:
public abstract class Question
{
public string QuestionString { get; private set; }
public Question(string q)
{
QuestionString = q;
}
}
我将所有创建的问题保存在public class OpenQuestion : Question
{
public string CorrectAnswer { get; private set; }
public OpenQuestion(string q, string a) : base(q)
{
CorrectAnswer = a;
}
}
public class MultipleChoiceQuestion : Question
{
public string[] Answers { get; private set; }
public MultipleChoiceQuestion(string q, string[] ans) : base(q)
{
Answers = ans;
}
}
中,最终保存为JSON文本文件。
我的问题是加载问题,如何加载正确的UI?
对于未解决的问题,将有一个带有问题和文本字段的标签来写出答案, 对于选择题,将有问题标签和4个单选按钮。
目前这是我要做的:
List<Question>
是否有避免这种类型检查的方法?因为在我看来这是不对的,所以如果我要添加另一种类型的问题,则需要回到该方法并为该类型添加另一种条件。
编辑对于UI,我使用保存UI的面板,例如:
public void LoadNextQuestion()
{
Question q = GetCurrentQuestion(); // Just returning the current question to show
if(q is OpenQuestion) // And here is the problematic part.
{
ShowOpenQuestion(q as OpenQuestion); // Load UI for open question
}
else if(q is MultipleChoiceQuestion)
{
ShowMultipleChoiceQuestion(q as MultipleChoiceQuestion); // Load UI for Multiple choice question
}
}
预先感谢
答案 0 :(得分:1)
类型检查是您的朋友。请勿进行类型检查。甚至还有向add/use more of it的转移。充其量您可以得到别人的代码为您做类型检查(例如Function调用解析)。
但是,在您给出的示例中,我看不到很多问题。如果有的话,如果您继续自己这样做,将是有益的,因为这样可以避免出现问题。我什至都不会想到六种“问题类型”-因此,从任何角度看,这份清单都不是很长。
您可以做的第一件事是用开关/保护套代替那些if / eles。他们最近被赋予了模式匹配能力。实际上,基于类型的转换和处理是first thing added之一。该示例代码就在您现在所做的事情附近。如果使用switch,则应使用默认值来显示一些错误消息,甚至引发异常。这样可以避免将来发生问题(忘记为新类提供适当的代码。其他人通过不提供绘画功能来弄乱继承)。
当然,通常可以使用集合来替换开关/外壳。 Dictionary<type, DelegateThatTakesAnyQuestionInstance>
。您必须在Delegate中进行手动转换(除非这里有共同或冲突帮助?),但是您知道它匹配。使用Lambdas而不是Delegate的命名函数,您甚至可以将整个代码隐藏在定义的其他大型集合中。同样,没有匹配项可以通知您,但例外情况除外。
在我撰写本文时,您没有指定编程环境。但是值得指出的是,如果您使用WPF / UWP并遵循MVVM,则可以为您提供一个很好的帮助:我称它们为“ Type Targeting Data Tempaltes”。如果您在View上抛出一些随机类,但没有更高阶的东西适用,它将尝试找到匹配的Template来显示它。使用TargetType property。
答案 1 :(得分:0)
总的来说,答案是通过以下方法应用信息隐藏和封装的面向对象设计原则:
Question
类指定一种抽象方法,该方法为特定类型的问题呈现UI,并且OpenQuestion
和MultipleChoiceQuestion
中覆盖该方法。更具体地讲,有关这些方法应如何呈现UI的“确切”答案取决于您所使用的UI范例和框架。