导航菜单

原型设计模式

原型设计模式1、实现机制2、使用场景3、使用案例3.1、案例说明3.2、代码结构3.3、案例实现3.3.1、实体类3.3.2、工具类3.3.3、实现类3.3.4、测试类3.3.5、测试结果

1、实现机制

 

实现机制:

         通过实现 Cloneable接口,再重写 clone()方法返回想要的对象。原型模式实现clone接口的时候必须使用深拷贝。          原型模式实际上就是从一个对象再创建另外一个可定制的对象,且无需知道任何创建的细节。在初始化的信息不发生变化的情况下,克隆是最好的办法,既隐藏了对象创建的细节,又大大提高了性能。因为如果不用 clone,每次 new 都需要执行一次构造函数,如果构造函数的执行时间很长,那么多次的执行初始化操作就太低效了。  

优点: 使用原型模式创建对象比直接new一个对象,在性能上优势明显。因为 Object 类的 clone() 方法是一个本地方法,直接操作内存中的二进制流,特别是复制大对象时,性能的差别非常明显。使用原型模式可以简化对象的创建,使得创建对象很简单。逃避构造函数的约束。使用原型模式复制对象不会调用类的构造方法。因为对象的复制是通过调用Object类的clone方法来完成的,它直接在内存中复制数据,因此不会调用到类的构造方法。不但构造方法中的代码不会执行,甚至连访问权限都对原型模式无效。缺点: 必须实现Cloneable接口。

 

2、使用场景

 

希望以一个对象为原型,创建其他近似的对象的时候。代码优化场景,该场景在业务中用的比较少。一般结合工厂方法模式使用。多个调用者使用时,并且需要修改对象中的值,可以考虑原型模式来提供对象。

 

3、使用案例

 

3.1、案例说明

 

以下案例,实现场景为,一个试题库中含选择题和简答题,要求根据每个考生将考题顺序打乱,同时将选择题的选项顺序打乱。

 

3.2、代码结构

在这里插入图片描述

3.3、案例实现

 

3.3.1、实体类 简答题实体类 (EssayQuestion) import lombok.AllArgsConstructor;import lombok.Builder;import lombok.Data;import lombok.NoArgsConstructor;/** * 简答题 */@Data@Builder@NoArgsConstructor@AllArgsConstructorpublic class EssayQuestion {/** * 题干 */private String questionStem;/** * 答案 */private String answer;} 选择题实体类(ChoiceQuestion) import lombok.AllArgsConstructor;import lombok.Builder;import lombok.Data;import lombok.NoArgsConstructor;import java.util.HashMap;/** * 选择题 */@Data@Builder@NoArgsConstructor@AllArgsConstructorpublic class ChoiceQuestion {/** * 题干 */private String questionStem;/** * 选项 */private HashMap option;/** * 答案 */private String key;}

 

3.3.2、工具类 OutOfOrderHelper 类 import lombok.AllArgsConstructor;import lombok.Builder;import lombok.Data;import lombok.NoArgsConstructor;import java.util.HashMap;@Data@Builder@NoArgsConstructor@AllArgsConstructorpublic class OutOfOrderHelper {/** * 选项 */private HashMap option;/** * 答案 */private String key;} 选择题选项乱序工具类(OutOfOrderUtil ) import java.util.*;/** * 乱序工具类 */public class OutOfOrderUtil {/** * 乱序Map元素,记录对应答案key * @param option 选项 * @param key答案 * @return OutOfOrderHelper 选项乱序后的对象 */public static OutOfOrderHelper random(Map option, String key) {// 获取所有选项的key值:(例:A、B、C、D)Set keySet = option.keySet();ArrayList keyList = new ArrayList(keySet);// 使用默认随机源对列表进行置换,所有key置换发生的可能性都是大致相等的。Collections.shuffle(keyList);HashMap newOption = new HashMap();int idx = 0;String newKey = "";for (String next : keySet) {String randomKey = keyList.get(idx++);if (key.equals(next)) {newKey = randomKey;}newOption.put(randomKey, option.get(next));}return new OutOfOrderHelper(newOption, newKey);}}

 

3.3.3、实现类 实现类(ExamHelper),实现 Cloneable类,重写 clone() 方法 import com.prototype.util.OutOfOrderHelper;import com.prototype.util.OutOfOrderUtil;import lombok.AllArgsConstructor;import lombok.Builder;import lombok.Data;import lombok.NoArgsConstructor;import java.util.ArrayList;import java.util.Collections;import java.util.Map;@Data@Builder@NoArgsConstructor@AllArgsConstructorpublic class ExamHelper implements Cloneable {/** * 考生姓名 */private String candidate;/** * 考号 */private String candidateNumber;/** * 简答题集合 */private ArrayList essayQuestions = new ArrayList();/** * 问答题集合 */private ArrayList choiceQuestions = new ArrayList();public ExamHelper append(EssayQuestion essayQuestion) {this.essayQuestions.add(essayQuestion);return this;}public ExamHelper append(ChoiceQuestion choiceQuestion) {this.choiceQuestions.add(choiceQuestion);return this;}/** * 复制对象 * * @return * @throws CloneNotSupportedException */@Overridepublic Object clone() throws CloneNotSupportedException {ExamHelper examHelper = (ExamHelper) super.clone();examHelper.choiceQuestions = (ArrayList) this.choiceQuestions.clone();examHelper.essayQuestions = (ArrayList) this.essayQuestions.clone();// 对题目进行乱序处理Collections.shuffle(examHelper.essayQuestions);Collections.shuffle(examHelper.choiceQuestions);// 对每个选择题的选项进行乱序处理ArrayList choiceQuestionList = examHelper.choiceQuestions;choiceQuestionList.forEach(t -> {OutOfOrderHelper outOfOrderHelper = OutOfOrderUtil.random(t.getOption(), t.getKey());t.setOption(outOfOrderHelper.getOption());t.setKey(outOfOrderHelper.getKey());});return examHelper;}@Overridepublic String toString() {StringBuilder detail = new StringBuilder("考生:" + candidate + "\r\n" +"考号:" + candidateNumber + "\r\n" +"--------------------------------------------\r\n" +"一、选择题" + "\r\n\n");for (int idx = 0; idx

相关推荐: