Design pattern 5: create prototype pattern

Keywords: Java Design Pattern

Create pattern: prototype pattern

Prototype mode

1. Prototype mode: Introduction

  • Prototype mode
    • Solution: create duplicate objects.
    • The object content itself is complex, and it takes a long time to obtain relevant object data from the database or RPC interface. Therefore, replication is needed to save time.

2. Prototype mode: simulation scene

  • Test paper title disorder scene
    • For the same test paper, the same question and the same answer, mix the questions and answers.

3. Prototype mode: Scene Simulation Engineering

0. Engineering structure

lino-design-7.0
|-src
	|-main
		|--java
			|--com.lino.design
    			|--AnswerQuestion.java
        		|--ChoiceQuestion.java
  • In the simulation project, two types of questions in the test paper are provided:
    • Multiple choice questions: ChoiceQuestion
    • Question and answer class: AnswerQuestion

1. Multiple choice questions

import java.util.Map;

/**
 * @description: Multiple choice questions
 */
public class ChoiceQuestion {

    /**
     * Title
     */
    private String name;

    /**
     * Topic options: A, B, C, D
     */
    private Map<String, String> option;

    /**
     * Answer: B
     */
    private String key;

    public ChoiceQuestion() {
    }

    public ChoiceQuestion(String name, Map<String, String> option, String key) {
        this.name = name;
        this.option = option;
        this.key = key;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Map<String, String> getOption() {
        return option;
    }

    public void setOption(Map<String, String> option) {
        this.option = option;
    }

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }
}

2. Question and answer class

/**
 * @description: Question and answer class
 */
public class AnswerQuestion {

    /**
     * problem
     */
    private String name;

    /**
     * answer
     */
    private String key;

    public AnswerQuestion() {
    }

    public AnswerQuestion(String name, String key) {
        this.name = name;
        this.key = key;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }
}

4. Prototype pattern: code implementation

0. Engineering structure

lino-design-6.0
|-src
	|-main
		|--java
			|--com.lino.prototype
    			|--util
    				|--Topic.java
    				|--TopicRandomUtil.java
    			|--QuestionBank.java
    			|--QuestionBankController.java
	|-test
    	|--java
    		|--com.lino.test
    			|--Test.java

  • The whole engineering structure of the prototype model is not complex
    • The topic class AnswerQuestion and ChoiceQuestion are used in the creation of gallery
    • For each test paper, it will be copied. After copying, mix the questions and corresponding answers of the test paper. The toolkit TopicRandomUtil is provided here
    • The core question bank class, QuestionBank, is mainly responsible for assembling various questions and finally outputting the test paper

1. Topic mix Kit

  • Topic class
import java.util.Map;

/**
 * @description: Topic class
 */
public class Topic {

    /**
     * Options; A,B,C,D
     */
    private Map<String, String> option;

    /**
     * answer; B
     */
    private String key;

    public Topic() {
    }

    public Topic(Map<String, String> option, String key) {
        this.option = option;
        this.key = key;
    }

    public Map<String, String> getOption() {
        return option;
    }

    public void setOption(Map<String, String> option) {
        this.option = option;
    }

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }
}
  • Title mixing tool
import java.util.*;

/**
 * @description: Topic mix Kit
 */
public class TopicRandomUtil {

    /**
     * Disorderly Map elements, record the corresponding answer key
     * @param option subject
     * @param key    answer
     * @return Topic After disorder {A=c., B=d., C=a., D=b.}
     */
    public static Topic random(Map<String, String> option, String key) {
        Set<String> keySet = option.keySet();
        ArrayList<String> keyList = new ArrayList<>(keySet);
        Collections.shuffle(keyList);
        HashMap<String, String> optionNew = new HashMap<>(16);
        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);
    }
}
  • The toolkit for mixed arrangement of test questions and answers provides a random method to realize mixed arrangement.
    • In the shuffle operation method, first use the shuffle method in the Collections toolkit in Java to shuffle the topic options
    • Record the position key, equals(next) of the correct answer after mixed arrangement, and finally return to the new Topic option list Topic
    • The process of mixed arrangement is to give the option content of A to B, the option content of B to C, and mark the position of the correct answer

2. Item bank copy object class

  • The addition of each topic by the two append() is a bit like the way used in the builder mode - adding decoration materials
  • The core operation of clone() is to copy objects, which includes not only the object itself, but also two collections.
    • Only such a copy can ensure that the copied object is operated without affecting the original object
  • For shuffling operation, there is a method in the list collection - Collections.shuffle, which can disrupt the order of the original collection and output a new order.
    • This method is used here to mix and arrange the questions
import com.lino.design.AnswerQuestion;
import com.lino.design.ChoiceQuestion;
import com.lino.prototype.util.Topic;
import com.lino.prototype.util.TopicRandomUtil;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * @description: Item bank copy object class
 */
public class QuestionBank implements Cloneable {
    /**
     * examinee
     */
    private String candidate;
    /**
     * Test number
     */
    private String number;
    /**
     * Multiple choice question bank
     */
    private ArrayList<ChoiceQuestion> choiceQuestionList = new ArrayList<>();
    /**
     * Question bank
     */
    private ArrayList<AnswerQuestion> answerQuestionList = new ArrayList<>();

    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();

        // Topic disorder
        Collections.shuffle(questionBank.choiceQuestionList);
        Collections.shuffle(questionBank.answerQuestionList);
        // The answers are out of order
        List<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 String getCandidate() {
        return candidate;
    }

    public void setCandidate(String candidate) {
        this.candidate = candidate;
    }

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }

    @Override
    public String toString() {
        StringBuilder detail = new StringBuilder("examinee:" + candidate + "\r\n" +
                "Test No.:" + number + "\r\n" +
                "--------------------------------------------\r\n" +
                "1, Multiple choice questions" + "\r\n\n");

        for (int idx = 0; idx < choiceQuestionList.size(); idx++) {
            detail.append("The first").append(idx + 1).append("Question:").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("answer:").append(choiceQuestionList.get(idx).getKey()).append("\r\n\n");
        }

        detail.append("2, Question and answer" + "\r\n\n");

        for (int idx = 0; idx < answerQuestionList.size(); idx++) {
            detail.append("The first").append(idx + 1).append("Question:").append(answerQuestionList.get(idx).getName()).append("\r\n");
            detail.append("answer:").append(answerQuestionList.get(idx).getKey()).append("\r\n\n");
        }

        return detail.toString();
    }
}

3. Initialize test paper data

  • Provide the mode initialization operation for the test paper content: the test papers of all candidates are the same, but the topic order is inconsistent
    • The method of creating test paper is provided to the outside. During the creation process, the copy method (QuestionBank) questionBank.clone() is used, and finally the test paper information is returned.
import com.lino.design.AnswerQuestion;
import com.lino.design.ChoiceQuestion;
import java.util.HashMap;

/**
 * @description: Item bank management
 */
public class QuestionBankController {

    /**
     * Item bank copy object class
     */
    private QuestionBank questionBank = new QuestionBank();

    public QuestionBankController() {
        questionBank.append(new ChoiceQuestion("JAVA Not included in the defined version", new HashMap<String, String>() {{
            put("A", "JAVA2 EE");
            put("B", "JAVA2 Card");
            put("C", "JAVA2 ME");
            put("D", "JAVA2 HE");
            put("E", "JAVA2 SE");
        }}, "D")).append(new ChoiceQuestion("The following statement is correct", new HashMap<String, String>() {{
            put("A", "JAVA programmatic main Methods must be written in classes");
            put("B", "JAVA There can be more than one in the program main method");
            put("C", "JAVA The class name in the program must be the same as the file name");
            put("D", "JAVA programmatic main If there is only one statement in the method, it can be omitted{}(Braces)Enclose");
        }}, "A")).append(new ChoiceQuestion("The variable naming convention is correct", new HashMap<String, String>() {{
            put("A", "Variables consist of letters, underscores, numbers $Symbols are randomly composed;");
            put("B", "Variable cannot start with a number;");
            put("C", "A and a stay java Is the same variable in;");
            put("D", "Different types of variables can have the same name;");
        }}, "B")).append(new ChoiceQuestion("following()Is not a valid identifier", new HashMap<String, String>() {{
            put("A", "STRING");
            put("B", "x3x;");
            put("C", "void");
            put("D", "de$f");
        }}, "C")).append(new ChoiceQuestion("expression(11+3*8)/4%3 The value of is", new HashMap<String, String>() {{
            put("A", "31");
            put("B", "0");
            put("C", "1");
            put("D", "2");
        }}, "D"))
                .append(new AnswerQuestion("How many legs did the little red horse and the little black horse have", "4 Legs"))
                .append(new AnswerQuestion("Iron or wood", "My head hurts the most"))
                .append(new AnswerQuestion("What bed can't sleep", "gums"))
                .append(new AnswerQuestion("Why don't good horses eat back", "The grass behind is gone"));
    }

    public String createPaper(String candidate, String number) throws CloneNotSupportedException {
        QuestionBank questionBankClone = (QuestionBank) questionBank.clone();
        questionBankClone.setCandidate(candidate);
        questionBankClone.setNumber(number);
        return questionBankClone.toString();
    }

}

4. Unit test

import com.lino.prototype.QuestionBankController;

/**
 * @description: Test class
 */
public class Test {

    @org.junit.Test
    public void testQuestionBank() throws Exception {
        // Create question bank
        QuestionBankController questionBankController = new QuestionBankController();
        System.out.println(questionBankController.createPaper("tearful", "1000001921032"));
        System.out.println(questionBankController.createPaper("peas", "1000001921051"));
        System.out.println(questionBankController.createPaper("Dabao", "1000001921987"));
    }
}
  • test result
Examinee: Huahua
 Test No.: 1000001921032
--------------------------------------------
1, Multiple choice questions

Question 1: JAVA Not included in the defined version
A: JAVA2 Card
B: JAVA2 ME
C: JAVA2 EE
D: JAVA2 HE
E: JAVA2 SE
 answer: D

Question 2: what is the correct statement of variable naming specification
A: Different types of variables can have the same name;
B: Variables consist of letters, underscores, numbers $Symbols are randomly composed;
C: Variable cannot start with a number;
D: A and a stay java Is the same variable in;
answer: C

Question 3: is the following statement correct
A: JAVA programmatic main If there is only one statement in the method, it can be omitted{}(Braces)Enclose
B: JAVA The class name in the program must be the same as the file name
C: JAVA programmatic main Methods must be written in classes
D: JAVA There can be more than one in the program main method
 answer: C

Question 4: the following()Is not a valid identifier
A: x3x;
B: de$f
C: void
D: STRING
 answer: C

Question 5: expression(11+3*8)/4%3 The value of is
A: 0
B: 2
C: 31
D: 1
 answer: B

2, Question and answer

Question 1: iron stick or wooden stick
 Answer: headache is the most painful

Question 2: what bed can't sleep
 Answer: gums

Question 3: why don't good horses eat back
 Answer: the grass behind is gone

Question 4: how many legs does the little red horse and the little black horse have
 Answer: 4 legs


Examinee: Doudou
 Test No.: 1000001921051
--------------------------------------------
1, Multiple choice questions

Question 1: the following()Is not a valid identifier
A: void
B: de$f
C: x3x;
D: STRING
 answer: A

Question 2: JAVA Not included in the defined version
A: JAVA2 ME
B: JAVA2 EE
C: JAVA2 HE
D: JAVA2 SE
E: JAVA2 Card
 answer: C

Question 3: expression(11+3*8)/4%3 The value of is
A: 0
B: 31
C: 2
D: 1
 answer: C

Question 4: is the following statement correct
A: JAVA The class name in the program must be the same as the file name
B: JAVA programmatic main Methods must be written in classes
C: JAVA There can be more than one in the program main method
D: JAVA programmatic main If there is only one statement in the method, it can be omitted{}(Braces)Enclose
 answer: B

Question 5: what is the correct statement of variable naming specification
A: Variable cannot start with a number;
B: Variables consist of letters, underscores, numbers $Symbols are randomly composed;
C: A and a stay java Is the same variable in;
D: Different types of variables can have the same name;
answer: A

2, Question and answer

Question 1: what bed can't sleep
 Answer: gums

Question 2: why don't good horses eat back
 Answer: the grass behind is gone

Question 3: how many legs does the little red horse and the little black horse have
 Answer: 4 legs

Question 4: iron stick or wooden stick
 Answer: headache is the most painful


Examinee: Dabao
 Test No.: 10000001921987
--------------------------------------------
1, Multiple choice questions

Question 1: JAVA Not included in the defined version
A: JAVA2 EE
B: JAVA2 Card
C: JAVA2 SE
D: JAVA2 HE
E: JAVA2 ME
 answer: D

Question 2: the following()Is not a valid identifier
A: de$f
B: STRING
C: x3x;
D: void
 answer: D

Question 3: is the following statement correct
A: JAVA programmatic main Methods must be written in classes
B: JAVA The class name in the program must be the same as the file name
C: JAVA programmatic main If there is only one statement in the method, it can be omitted{}(Braces)Enclose
D: JAVA There can be more than one in the program main method
 answer: A

Question 4: expression(11+3*8)/4%3 The value of is
A: 1
B: 31
C: 2
D: 0
 answer: C

Question 5: what is the correct statement of variable naming specification
A: Variable cannot start with a number;
B: Different types of variables can have the same name;
C: A and a stay java Is the same variable in;
D: Variables consist of letters, underscores, numbers $Symbols are randomly composed;
answer: A

2, Question and answer

Question 1: iron stick or wooden stick
 Answer: headache is the most painful

Question 2: why don't good horses eat back
 Answer: the grass behind is gone

Question 3: what bed can't sleep
 Answer: gums

Question 4: how many legs does the little red horse and the little black horse have
 Answer: 4 legs

4. Prototype mode: summary

  • advantage

    • It is convenient to create complex objects by cloning, avoid repeated initialization, and do not need to be coupled with other classes in the class.
  • shortcoming

    • The replication of circular references in objects and the replication of deeply used objects in classes can make this pattern troublesome

Posted by macje on Mon, 11 Oct 2021 17:03:55 -0700