在线考试系统提供了根据教师制定的出题策略随机生成试卷的功能。下面看看出题策略部分的详细类图4-15
图4-15 出题策略模块类图
可以看出该部分和试卷部分的类图有些相似。这里PaperStrategy和Paper类对应。PaperStrategy(出题策略)是用来生成Paper的。StrategyContainer是用来生成QuestionContainer的。而StrategyItem(策略项)是用来生成试题Question的。下面先从整体上介绍出题策略的概念。出题策略就是一个生成试卷的模板。这个模板制定了要出几个大题。每个大题包含了那些小题。出几个大题比较简单想要出几个大题就给一个出题策略PaperStrategy对象创建几个StrategyContainer子对象就可以了。关键是每个大题包含那些小题比较复杂。这里引入策略项的概念(StrategyItem)。每个大题可以有多个策略项。每个策略项有个QuestionContent集合和分值(ScoreValue),出题数(Count)属性。策略项的GetQuesitons方法会从引用的QuestionContent对象中随机挑出Count个,并根据ScoreValue属性生成Count个分值为ScoreValue的Question对象。每个策略项引用的多个QuestionContent对象代表了老师想出的一个知识点中的备选题。下面代码是PaperStrategy类的 GetPaper
方法。该方法创建一个新的Paper对象并遍历每个StrategyContainer子对象。然后将每个StrategyContainer生成的大题QuestionContainer对象加入到新建的Paper对象中。














下面再看看每个StrategyContainer是如何生成QuestionContainer对象的。下面是StrategyContainer类的GetQuestionContainer方法
















上面方法创建并返回了一个新的QuestionContainer对象,并遍历自己的StrategyItem子对象。将每个StrategyItem生成的试题Question对象全部加入到新建的QuestionContainer对象。
最后再来看下StrategyItem是如何随机地从指定的出题范围返回指定数量的Question对象的。下面是StrategyItem的GetQuestions方法。


















该方法根据RandomNumberHelper.RandomSelect来随机的从StrategyItem的QuestionContents集合属性中随机的选择指定数目的QuestionContents集合的一个子集。并根据子集来生成一个Question对象的集合并返回。这样就完成了根据出题策略生成试卷的功能。下面介绍下随机出题的算法。即从QuestionContents集合中随机选取指定数目的QuestionContent对象。该集合的定义如下。
IList<QuestionContent> QuestionContents = new List<QuestionContent>();
因为是用List来存储的。所以抽取题目的方法是。随机的选取QuestionContents集合的几个下标。比如QuestionContents有5个题目想选两个, 可以从0~4五个数字中选择两个不同的数字.比如选择了1、3。然后就可以通过QuestionContents[1],QuestionContents[3]取出要的两个题目。下面给出如何从一个下标的范围中随机选取指定数目下标的算法。























RandomSelect方法从给定下标集合sourceList中随机的选取selectCount个并将选取结果放到resultList中返回。该算法比网上用递归的方式实现算法效率要高。因为该算法在从sourceList中选出一个下标后就将该下标从sourceList中删除。所以下次在从sourceList中选的时候就不可能再重复挑出已经挑选过的下标。这样就避免了因为随机数不确定性带来的重复筛选的问题。