目录
一、概念:
二、代码示例
一、概念:
原型模式主要解决的是创建重复对象的问题,用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和实例原型相同或相似的新对象。在这里,原型实例指定了要创建的对象的种类。该模式最显著的一个特征就是对象的克隆;
模式的结构特点:
1.抽象原型类:具体原型对象继承后必须要实现的接口;
2.具体原型类:实现抽象原型类的clone()方法,它是可以被复制的对象,即原型模式中的那个原型对象;
3.访问类:使用具体原型类中的clone()方法来复制新的对象;
优点:
- 性能提高,java自带的原型模式基于内存二进制流的复制,在性能上比直接 new 一个对象更加优良。
- 逃避构造函数的约束,可以直接克隆已有的实例对象。
缺点:
- 要为每一个类都配置一个 clone 方法
- clone 方法位于类的内部,当对已有类进行改造的时候,需要修改代码,违背了开闭原则。
二、代码示例
下面我们就建一个模拟工程,示例的大体业务场景是为学生创建一套试卷,试卷由选择题组成,创建试卷的时候,每个学生的选择题顺序不一致,同时每个选择的选项顺序也不一致;下面我们就一起通过代码来看看实现的过程是什么样的;
1.选择题类
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
import java.util.Map;
/**
* @Description: 选择题类
* @Author: yangshilei
*/
@Data
public class ChoiceQuestion {
/**
* 题目名称
*/
private String name;
/**
* 题目选项:A/B/C/D等
*/
private Map<String,String> option;
/**
* 答案
*/
private String key;
public ChoiceQuestion(){}
public ChoiceQuestion(String name, Map<String, String> option, String key) {
this.name = name;
this.option = option;
this.key = key;
}
@Override
public String toString () {
return JSONObject.toJSONString(this);
}
}
2.考生试卷类:(抽象原型类)
import lombok.Data;
import java.util.ArrayList;
import java.util.Collections;
/**
* @Description: 试卷的选择题复制对象类
* @Author: yangshilei
*/
@Data
public class QuestionBank implements Cloneable {
/**
* 考生
*/
private String candidate;
/**
* 学号
*/
private String number;
/**
* 选择题集合
*/
private ArrayList<ChoiceQuestion> choiceQuestionList = new ArrayList<ChoiceQuestion>();
/**
* 此处类似建造者方法
*/
public QuestionBank append(ChoiceQuestion choiceQuestion) {
choiceQuestionList.add(choiceQuestion);
return this;
}
@Override
public Object clone() throws CloneNotSupportedException {
QuestionBank questionBank = (QuestionBank) super.clone();
questionBank.choiceQuestionList = (ArrayList<ChoiceQuestion>) choiceQuestionList.clone();
// 题目混排
Collections.shuffle(questionBank.choiceQuestionList);
// 题目的选项及答案混排
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;
}
}
3.选择题组成类,用于给选择题混排;
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
import java.util.Map;
/**
* 题目选项单及答案组成类
*/
@Data
public class Topic {
/**
* 题目选项:A/B/C/D等
*/
private Map<String,String> option;
/**
* 答案
*/
private String key;
public Topic(Map<String,String> option,String key){
this.option = option;
this.key = key;
}
@Override
public String toString () {
return JSONObject.toJSONString(this);
}
}
4.选择题混排工具类
import java.util.*;
/**
* 选择题选项即题目混排的工具类
*/
public class TopicRandomUtil {
/**
* 混排Map元素,记录对应的答案key
* @param option 选项
* @param key 答案
* @return
*/
public static Topic random(Map<String,String> option,String key) {
Set<String> keySet = option.keySet();
List<String> keyList = new ArrayList<>(keySet);
Collections.shuffle(keyList);
Map<String,String> optionNew = new HashMap<>();
int idx = 0;
String newKey = "";
for(String next : keySet){
String randomKey = keyList.get(idx++);
if(key.equals(next)){
newKey = randomKey;
}
optionNew.put(randomKey,option.get(next));
}
return new Topic(optionNew,newKey);
}
}
5.数据初始化(访问类:使用考卷实例questionBank进行复制克隆新的对象方法)
及main方法测试
import com.alibaba.fastjson.JSON;
import java.util.HashMap;
import java.util.Map;
/**
* 初始化学生试卷数据
*/
public class QuestionBankInit {
private QuestionBank questionBank = new QuestionBank();
public QuestionBankInit(){
Map<String,String> map1 = new HashMap<>();
map1.put("A","Java");
map1.put("B","python");
map1.put("C","C++");
map1.put("D","php");
Map<String,String> map2 = new HashMap<>();
map2.put("A","狗");
map2.put("B","猫");
map2.put("C","老鼠");
map2.put("D","青蛙");
Map<String,String> map3 = new HashMap<>();
map3.put("A","乒乓球");
map3.put("B","男足");
map3.put("C","排球");
map3.put("D","篮球");
questionBank.append(new ChoiceQuestion("最好的开发语言是?",map1,"A"))
.append(new ChoiceQuestion("什么动物爱吃老鼠?",map2,"B"))
.append(new ChoiceQuestion("什么体育运动最伤中国人的心?",map3,"B"));
}
/**
* 访问类:使用考卷实例questionBank进行复制克隆新的对象方法;
*/
public String createPaper(String candidate,String number) throws CloneNotSupportedException{
QuestionBank questionBankClone = (QuestionBank)questionBank.clone();
questionBankClone.setCandidate(candidate);
questionBankClone.setNumber(number);
return JSON.toJSONString(questionBankClone);
}
public static void main(String[] args) throws CloneNotSupportedException {
QuestionBankInit questionBankInit = new QuestionBankInit();
System.out.println(questionBankInit.createPaper("小明","001"));
System.out.println(questionBankInit.createPaper("小张","002"));
System.out.println(questionBankInit.createPaper("小杨","003"));
}
}
查看执行结果:从结果中我们看到,不同学生的选择题及选项的顺序都是不一样的,达到了混排的目的,到此就演示结束了;
?
版权声明:以上代码示例参考《重学JAVA设计模式》一书。
|