原型模式(上机考试抽题)

发布于:2024-04-27 ⋅ 阅读:(26) ⋅ 点赞:(0)

定义

原型模式主要解决的问题就是创建复对象,⽽这部分 对象 内容本身⽐较复杂,⽣成过程可能从库或者RPC接⼝中获取数据的耗时较⻓,因此采⽤克隆的⽅式节省时间。

上机考试抽题

从⼀部分可以上机考试的内容开始,在保证⼤家的公平性⼀样的题⽬下,开始出现试题混排更有做的好的答案选项也混排。这样⼤⼤的增加了抄的成本,也更好的做到了考试的公平性。因为需要实现⼀个上机考试抽题的服务,因此在这⾥建造⼀个题库题⽬的场景类信息,⽤于创建; 选择题 、 问答题 。

选择题

public class ChoiceQuestion {
    private String name; // 题⽬
    private Map<String, String> option; // 选项;A、B、C、D
    private String key; // 答案;B
    
    public ChoiceQuestion() {}
    
    public ChoiceQuestion(String name, Map<String, String> option, String key) {
        this.name = name;
        this.option = option;
        this.key = key;
    }
    
    // ...get/set
}

问答题

public class AnswerQuestion {
    private String name; // 问题
    private String key; // 答案
    
    public AnswerQuestion() {}
    
    public AnswerQuestion(String name, String key) {
        this.name = name;
        this.key = key;
    }
    
    // ...get/set
}

代码实现

题⽬选项乱序操作⼯具包

/**
* 乱序Map元素,记录对应答案key
* @param option 题⽬
* @param key 答案
* @return Topic 乱序后 {A=c., B=d., C=a., D=b.}
*/
static public Topic random(Map<String, String> option, String key) {
    Set<String> keySet = option.keySet();
    ArrayList<String> keyList = new ArrayList<String>(keySet);
    Collections.shuffle(keyList);
    HashMap<String, String> optionNew = new HashMap<String, String>();
    int idx = 0;
    String keyNew = "";
    for (String next : keySet) {
        String randomKey = keyList.get(idx++);
        if (key.equals(next)) {
            keyNew = randomKey;
        }
        optionNew.put(randomKey, option.get(next));
    }
    return new Topic(optionNew, keyNew);
}

克隆对象处理类

public class QuestionBank implements Cloneable {
    private String candidate; // 考⽣
    private String number; // 考号
    private ArrayList<ChoiceQuestion> choiceQuestionList = new ArrayList<ChoiceQuestion>();
    private ArrayList<AnswerQuestion> answerQuestionList = new ArrayList<AnswerQuestion>();
 
    public QuestionBank append(ChoiceQuestion choiceQuestion) {
        choiceQuestionList.add(choiceQuestion);
        return this;
    }
    
    public QuestionBank append(AnswerQuestion answerQuestion) {
        answerQuestionList.add(answerQuestion);
        return this;
    }
    
    @Override
    public Object clone() throws CloneNotSupportedException {
        QuestionBank questionBank = (QuestionBank) super.clone();
        questionBank.choiceQuestionList = (ArrayList<ChoiceQuestion>) choiceQuestionList.clone();
        questionBank.answerQuestionList = (ArrayList<AnswerQuestion>) answerQuestionList.clone();
        // 题⽬乱序
        Collections.shuffle(questionBank.choiceQuestionList);
        Collections.shuffle(questionBank.answerQuestionList);
        // 答案乱序
        ArrayList<ChoiceQuestion> choiceQuestionList = questionBank.choiceQuestionList;
        for (ChoiceQuestion question : choiceQuestionList) {
            Topic random = TopicRandomUtil.random(question.getOption(), question.getKey());
            question.setOption(random.getOption());
            question.setKey(random.getKey());
        }
        return questionBank;
    }
    
    public void setCandidate(String candidate) {
        this.candidate = candidate;
    }
    
    public void setNumber(String number) {
        this.number = number;
    }
    
    @Override
    public String toString() {
        StringBuilder detail = new StringBuilder("考⽣:" + candidate + "\r\n" +
        "考号:" + number + "\r\n" +
        "--------------------------------------------\r\n" +
        "⼀、选择题" + "\r\n\n");
        
        for (int idx = 0; idx < choiceQuestionList.size(); idx++) {
            detail.append("第").append(idx + 1).append("题:").append(choiceQuestionList.get(idx).getName()).append("\r\n");
            Map<String, String> option = choiceQuestionList.get(idx).getOption();
            for (String key : option.keySet()) {
                detail.append(key).append(":").append(option.get(key)).append("\r\n");
            }
            detail.append("答案:").append(choiceQuestionList.get(idx).getKey()).append("\r\n\n");
        }
        
        detail.append("⼆、问答题" + "\r\n\n");
        for (int idx = 0; idx < answerQuestionList.size(); idx++) {
            detail.append("第").append(idx + 1).append("题:").append(answerQuestionList.get(idx).getName()).append("\r\n");
            detail.append("答案:").append(answerQuestionList.get(idx).getKey()).append("\r\n\n");
        }
        return detail.toString();
    }
}

初始化试卷数据

public class QuestionBankController {
    private QuestionBank questionBank = new QuestionBank();
    
    public QuestionBankController() {
        Map<String, String> map01 = new HashMap<String, String>();
        map01.put("A", "JAVA2 EE");
        map01.put("B", "JAVA2 Card");
        map01.put("C", "JAVA2 ME");
        map01.put("D", "JAVA2 HE");
        map01.put("E", "JAVA2 SE");
        
        Map<String, String> map02 = new HashMap<String, String>();
        map02.put("A", "JAVA程序的main⽅法必须写在类⾥⾯");
        map02.put("B", "JAVA程序中可以有多个main⽅法");
        map02.put("C", "JAVA程序中类名必须与⽂件名⼀样");
        map02.put("D", "JAVA程序的main⽅法中如果只有⼀条语句,可以不⽤{}(⼤括号)括起来");
 
        Map<String, String> map03 = new HashMap<String, String>();
        map03.put("A", "变量由字⺟、下划线、数字、$符号随意组成;");
        map03.put("B", "变量不能以数字作为开头;");
        map03.put("C", "A和a在java中是同⼀个变量;");
        map03.put("D", "不同类型的变量,可以起相同的名字;");
        
        Map<String, String> map04 = new HashMap<String, String>();
        map04.put("A", "STRING");
        map04.put("B", "x3x;");
        map04.put("C", "void");
        map04.put("D", "de$f");

        Map<String, String> map05 = new HashMap<String, String>();
        map05.put("A", "31");
        map05.put("B", "0");
        map05.put("C", "1");
        map05.put("D", "2");
 
        questionBank.append(new ChoiceQuestion("JAVA所定义的版本中不包括", map01, "D"))
        .append(new ChoiceQuestion("下列说法正确的是", map02, "A"))
        .append(new ChoiceQuestion("变量命名规范说法正确的是", map03, "B"))
        .append(new ChoiceQuestion("以下()不是合法的标识符",map04, "C"))
        .append(new ChoiceQuestion("表达式(11+3*8)/4%3的值是", map05, "D"))
        .append(new AnswerQuestion("⼩红⻢和⼩⿊⻢⽣的⼩⻢⼏条腿", "4条腿"))
        .append(new AnswerQuestion("铁棒打头疼还是⽊棒打头疼", "头最疼"))
        .append(new AnswerQuestion("什么床不能睡觉", "⽛床"))
        .append(new AnswerQuestion("为什么好⻢不吃回头草", "后⾯的草没了"));
    }
    
    public String createPaper(String candidate, String number) throws CloneNotSupportedException {
        QuestionBank questionBankClone = (QuestionBank) questionBank.clone();
        questionBankClone.setCandidate(candidate);
        questionBankClone.setNumber(number);
        return questionBankClone.toString();
    }
}

测试验证

@Test
public void test_QuestionBank() throws CloneNotSupportedException {
    QuestionBankController questionBankController = new QuestionBankController();
    System.out.println(questionBankController.createPaper("花花", "1000001921032"));
    System.out.println(questionBankController.createPaper("⾖⾖", "1000001921051"));
    System.out.println(questionBankController.createPaper("⼤宝", "1000001921987"));
}