浅谈利用原型模式进行代码重构

原代码:(将一个对象中的值赋到另一个对象中)

public void setParam(ExamPaperVo vo){ 
	ExamPaper examPaper = new ExamPaper(); //试卷主键 		
    examPaper.setExaminationPaperId(vo.getExaminationPaperId()); //剩余时间 
	curForm.setLeavTime(examPaper.getLeavTime()); //单位主键  
	curForm.setOrganizationId(examPaper.getOrganizationId()); //考试主键 
	curForm.setId(examPaper.getId()); //考场主键 
	curForm.setExamroomId(examPaper.getExamroomId()); //用户主键 
	curForm.setUserId(examPaper.getUserId()); //专业 
	curForm.setSpecialtyCode(examPaper.getSpecialtyCode()); //岗位 
	curForm.setPostionCode(examPaper.getPostionCode()); //等级 
	curForm.setGradeCode(examPaper.getGradeCode()); //考试开始时间 
	curForm.setExamStartTime(examPaper.getExamStartTime()); //考试结束时间
    curForm.setExamEndTime(examPaper.getExamEndTime()); //单选题重要数量    
    curForm.setSingleSelectionImpCount(examPaper.getSingleSelectionImpCount()); //多选题重要数量 
    curForm.setMultiSelectionImpCount(examPaper.getMultiSelectionImpCount()); //判断题重要数量
    curForm.setJudgementImpCount(examPaper.getJudgementImpCount()); //考试时间 
    curForm.setExamTime(examPaper.getExamTime()); //总分 
    curForm.setFullScore(examPaper.getFullScore()); //及格分 
    curForm.setPassScore(examPaper.getPassScore()); //学员姓名 
    curForm.setUserName(examPaper.getUserName()); //分数 
    curForm.setScore(examPaper.getScore()); //是否及格 
    curForm.setResult(examPaper.getResult()); 
    curForm.setIsPassed(examPaper.getIsPassed()); //单选答对数量 
    curForm.setSingleOkCount(examPaper.getSingleOkCount()); //多选答对数量 
    curForm.setMultiOkCount(examPaper.getMultiOkCount()); //判断答对数量 
    curForm.setJudgementOkCount(examPaper.getJudgementOkCount()); //提交试卷 
    service.submit(examPaper);
     }

原型模式是指创建对象的种类,并且通过拷贝这些原型创建新的对象。
原型模式主要适用于以下场景:
1.类初始化消耗资源较多。
2.new产生的一个对象需要非常繁琐的过程(数据准备,访问权限等)
3.构造函数比较复杂。
4.循环体中产生大量对象

下面是进行浅克隆的代码:

先是创建原型Prototype接口:

package prototype;

/**
 * Created by Lenovo on 2019-7-1.
 */
public interface Prototype {
    Prototype clone();
}

创建具体需要克隆的对象ConcretePrototype

package prototype;

import java.util.List;

/**浅克隆
 * Created by Lenovo on 2019-7-1.
 */
public class ConcreatePrototype implements Prototype{
    private int age;
    private String name;
    private List hobbies;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public List getHobbies() {
        return hobbies;
    }

    public void setHobbies(List hobbies) {
        this.hobbies = hobbies;
    }

    public String getName() {
        return name;
    }

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

    @Override
    public ConcreatePrototype clone() {
        ConcreatePrototype concreatePrototype=new ConcreatePrototype();
        concreatePrototype.setAge(this.age);
        concreatePrototype.setName(this.name);
        concreatePrototype.setHobbies(this.hobbies);
        return concreatePrototype;
    }
}

相关的客户端:

package prototype;

/**
 * Created by Lenovo on 2019-7-1.
 */
public class Client {
    private Prototype prototype;
    public Client(Prototype prototype){
        this.prototype=prototype;
    }
    public Prototype startClone(Prototype concretePrototype){
        return (Prototype)concretePrototype.clone();
    }
}

相关的测试代码

package prototype;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by Lenovo on 2019-7-1.
 */
public class PrototypeTest {
    public static void main(String [] args){
        ConcreatePrototype concreatePrototype=new ConcreatePrototype();
        concreatePrototype.setAge(18);
        concreatePrototype.setName("prototype");
        List hobbis=new ArrayList();
        concreatePrototype.setHobbies(hobbis);
        System.out.println(concreatePrototype);
//      创建Client对象,开始克隆
        Client client=new Client(concreatePrototype);
        ConcreatePrototype concreateProtoClone=(ConcreatePrototype)client.startClone(concreatePrototype);
        System.out.println(concreateProtoClone);
        System.out.println("yuan"+concreatePrototype.getHobbies());
        System.out.println("xian" + concreateProtoClone.getHobbies());
        System.out.println(concreatePrototype.getHobbies()==concreateProtoClone.getHobbies());
    }
}

从测试结果可以看出hobbies的引用地址是相同的,意味着复制的不是值,而是引用的
地址,这样的话,如果我们修改任意一个对象中的属性值,concretePrototype和
concretePrototypeClone的hobbies值都会变。这就是浅克隆的特点。只是完整
复制了值类型数据,没有赋值引用对象。换言之,所有的引用对象仍然指向原来
的对象。

深度克隆

猴子类

package deepprototype;

import java.util.Date;

/**
 * Created by Lenovo on 2019-7-1.
 */
public class Mokey {
    public int height;
    public int weight;
    public Date birthday;
}

金箍棒类

package deepprototype;

import java.io.Serializable;

/**
 * Created by Lenovo on 2019-7-1.
 */
public class JinGuBang implements Serializable{
    public float h=100;
    public float d=10;
    public void big(){
        this.h*=2;
        this.d*=2;
    }
    public void small(){
        this.d/=2;
        this.h/=2;
    }
}

齐天大圣类

package deepprototype;

import java.io.*;
import java.util.Date;

/**
 * Created by Lenovo on 2019-7-1.
 */
public class QiTianDaSheng extends Mokey implements Cloneable,Serializable {
    public JinGuBang jinGuBang;
    public QiTianDaSheng(){
        this.birthday=new Date();
        this.jinGuBang=new JinGuBang();
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return  this.deepClone();
    }
    public Object deepClone(){

        try {
            ByteArrayOutputStream bos=new ByteArrayOutputStream();
            ObjectOutputStream oos=new ObjectOutputStream(bos);
            oos.writeObject(this);

            ByteArrayInputStream bis=new ByteArrayInputStream(bos.toByteArray());
            ObjectInputStream ois=new ObjectInputStream(bis);
            QiTianDaSheng copy=(QiTianDaSheng)ois.readObject();
            copy.birthday=new Date();
            return copy;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;

    }
    public QiTianDaSheng shallowClone(QiTianDaSheng target){
        QiTianDaSheng qiTianDaSheng=new QiTianDaSheng();
        qiTianDaSheng.height=target.height;
        qiTianDaSheng.weight=target.weight;
        qiTianDaSheng.jinGuBang=target.jinGuBang;
        qiTianDaSheng.birthday=new Date();
        return qiTianDaSheng;
    }
}

测试类

package deepprototype;

/**
 * Created by Lenovo on 2019-7-1.
 */
public class DeepCloneTest {
    public static void main(String [] args){
        QiTianDaSheng qiTianDaSheng=new QiTianDaSheng();
        try {
            QiTianDaSheng clone=(QiTianDaSheng)qiTianDaSheng.clone();
            System.out.println(qiTianDaSheng.jinGuBang==clone.jinGuBang);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值