您当前的位置: 首页 > 

顧棟

暂无认证

  • 3浏览

    0关注

    227博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

原型模式(Prototype Pattern)

顧棟 发布时间:2021-05-29 01:00:59 ,浏览量:3

文章目录
  • 原型模式(Prototype Pattern)
    • 原型模式的定义
    • 原型模式的优点
    • 原型模式的缺点
    • 原型模式的结构
    • 原型模式的实现
    • 使用场景
    • 注意事项

原型模式(Prototype Pattern) 原型模式的定义

用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

原型模式的优点
  • Java 自带的原型模式基于内存二进制流的复制,在性能上比直接 new 一个对象更加优良。
  • 可以使用深克隆方式保存对象的状态,使用原型模式将对象复制一份,并将其状态保存起来,简化了创建对象的过程,以便在需要的时候使用(例如恢复到历史某一状态),可辅助实现撤销操作。
原型模式的缺点
  • 需要为每一个类都配置一个 clone 方法
  • clone 方法位于类的内部,当对已有类进行改造的时候,需要修改代码,违背了开闭原则。
  • 当实现深克隆时,需要编写较为复杂的代码,而且当对象之间存在多重嵌套引用时,为了实现深克隆,每一层对象对应的类都必须支持深克隆,实现起来会比较麻烦。因此,深克隆、浅克隆需要运用得当。
原型模式的结构

原型模式包含以下主要角色。

  1. 抽象原型类:规定了具体原型对象必须实现的接口。
  2. 具体原型类:实现抽象原型类的 clone() 方法,它是可被复制的对象。
  3. 访问类:使用具体原型类中的 clone() 方法来复制新的对象。
原型模式的实现
package org.donny.design.patterns.prototypePattern;

/**
 * 解答题
 */
public class AnswerQuestion {
    /**
     * 问题
     */
    private String name;

    /**
     * 答案
     */
    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;
    }
}
package org.donny.design.patterns.prototypePattern;

import java.util.Map;

/**
 * 单选题
 */
public class ChoiceQuestion {

    /**
     * 题目
     */
    private String name;
    /**
     * 选项;A、B、C、D
     */
    private Map option;
    /**
     * 答案;B
     */
    private String key;

    public ChoiceQuestion() {
    }

    public ChoiceQuestion(String name, Map 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 getOption() {
        return option;
    }

    public void setOption(Map option) {
        this.option = option;
    }

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }
}
package org.donny.design.patterns.prototypePattern;

import java.util.Map;

public class Topic {
    /**
     * 选项;A、B、C、D
     */
    private Map option;
    /**
     * 答案
     */
    private String key;

    public Topic() {
    }

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

    public Map getOption() {
        return option;
    }

    public void setOption(Map option) {
        this.option = option;
    }

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }
}
package org.donny.design.patterns.prototypePattern;

import java.util.*;

public class TopicRandomUtil {

    /**
     * 乱序Map元素,记录对应答案key
     *
     * @param option 题目
     * @param key    答案
     * @return Topic 乱序后 {A=c., B=d., C=a., D=b.}
     */
    static public Topic random(Map option, String key) {
        Set keySet = option.keySet();
        ArrayList keyList = new ArrayList(keySet);
        Collections.shuffle(keyList);
        HashMap optionNew = new HashMap();
        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);
    }
}

具体原型类问卷实现clone方法

package org.donny.design.patterns.prototypePattern;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Map;

public class QuestionBank implements Cloneable {
    /**
     * 考生
     */
    private String candidate;
    /**
     * 考号
     */
    private String number;

    private ArrayList choiceQuestionList = new ArrayList();
    private ArrayList 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) choiceQuestionList.clone();
        questionBank.answerQuestionList = (ArrayList) answerQuestionList.clone();

        // 题目乱序
        Collections.shuffle(questionBank.choiceQuestionList);
        Collections.shuffle(questionBank.answerQuestionList);
        // 答案乱序
        ArrayList 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             
关注
打赏
1663402667
查看更多评论
0.0405s