十万个分身之原型模式

1.你一定写过如下的代码:

/**
 * @author dxy
 * @version 1.0
 * @date 2021/10/24 9:22
 * @decripton 简历
 * @mail victorydeng@163.com
 */
@Data
public class Resume {
    private String name;
    private String sex;
    private String age;
    private String timeArea;
    private String company;

    public Resume(String name) {
        this.name = name;
    }

    //设置个人信息
    public void setPersonalInfo(String age, String sex) {
        this.sex = sex;
        this.age = age;
    }

    //设置工作经历
    public void setWorkExperience(String timeArea, String company) {
        this.timeArea = timeArea;
        this.company = company;
    }

    public void display() {
        System.out.println(String.format("个人基础信息:%s,%s,%s", name, sex, age));
        System.out.println(String.format("工作经历:%s,%s", timeArea, company));
    }
}

 

public class Test {
    public static void main(String[] args) {
        Resume resumeA = new Resume("张无忌");
        resumeA.setPersonalInfo("18","男");
        resumeA.setWorkExperience("533-537","武当派");

        Resume resumeB = new Resume("周芷若");
        resumeB.setPersonalInfo("25","女");
        resumeB.setWorkExperience("555-559", "峨眉派");

        Resume resumeC = new Resume("赵敏");
        resumeC.setPersonalInfo("23","女");
        resumeC.setWorkExperience("554-558", "王府");

        resumeA.display();
        resumeB.display();
        resumeC.display();



    }
}

 

如果需要创建很多个对象,而且这些对象都差不多时,我们可以使用原型模式来帮我们简化。

2.原型模式

类图 

多份简历的例子:

对于java而言,只要实现Cloneable接口就可以实现基于浅表复制的原型模式

修改代码:

@Data
public class Resume implements Cloneable {
    private String name;
    private String sex;

    @Override
    protected Resume clone() throws CloneNotSupportedException {
        return (Resume)super.clone();
    }

    private String age;
    private String timeArea;
    private String company;

    public Resume(String name) {
        this.name = name;
    }

    //设置个人信息
    public void setPersonalInfo(String age, String sex) {
        this.sex = sex;
        this.age = age;
    }

    //设置工作经历
    public void setWorkExperience(String timeArea, String company) {
        this.timeArea = timeArea;
        this.company = company;
    }

    public void display() {
        System.out.println(String.format("个人基础信息:%s,%s,%s", name, sex, age));
        System.out.println(String.format("工作经历:%s,%s", timeArea, company));
    }
}

 测试:

 

    public static void main(String[] args) throws CloneNotSupportedException {
        Resume resumeA = new Resume("张无忌");
        resumeA.setPersonalInfo("18","男");
        resumeA.setWorkExperience("533-537","武当派");

        Resume resumeB  = resumeA.clone();
        resumeB.setWorkExperience("537-538", "波斯");

        Resume resumeC  = resumeA.clone();
        resumeC.setWorkExperience("537-538", "波斯");

        resumeA.display();
        resumeB.display();
        resumeC.display();
}
}

结果:

 

3.浅克隆和深克隆

由于简历里的对象都是string类型的,算是基本数据类型,clone方法只是把对象的引用拷贝过去,

所以当我门把工作经理脱离出去时,都是使用的最新的引用。

测试修改:

@Data
public class WorkExperience {

    public String timeArea;
    public String company;

    
}
@Data
public class Resume implements Cloneable {
    private String name;
    private String sex;

    @Override
    protected Resume clone() throws CloneNotSupportedException {
        return (Resume)super.clone();
    }

    private String age;

    private WorkExperience workExperience;

    public Resume(String name) {
        this.name = name;
        workExperience = new WorkExperience();
    }

    //设置个人信息
    public void setPersonalInfo(String age, String sex) {
        this.sex = sex;
        this.age = age;
    }

    //设置工作经历
    public void setWorkExperience(String timeArea, String company) {
        workExperience.timeArea =timeArea;
        workExperience.company = company;
    }

    public void display() {
        System.out.println(String.format("个人基础信息:%s,%s,%s", name, sex, age));
        System.out.println(String.format("工作经历:%s,%s", workExperience.getTimeArea(),workExperience.getCompany()));
    }
}
public class AfterTest {
    public static void main(String[] args) throws CloneNotSupportedException {
        Resume resumeA = new Resume("张无忌");
        resumeA.setPersonalInfo("18","男");
        resumeA.setWorkExperience("533-537","武当派");

        Resume resumeB  = resumeA.clone();
        resumeB.setWorkExperience("537-538", "波斯");

        Resume resumeC  = resumeA.clone();
        resumeC.setWorkExperience("536-539", "明教");

        resumeA.display();
        resumeB.display();
        resumeC.display();



    }
}

 结果如下,可以看到拷贝的对象中引用对象都是同一个。

 

 解决办法:

让workExperience也实现cloneable接口修改如下:

@Data
public class WorkExperience implements Cloneable {

    public String timeArea;
    public String company;

    @Override
    protected WorkExperience clone() throws CloneNotSupportedException {
        return (WorkExperience) super.clone();
    }
}

简历类修改clone方法,并增加workExperience的构造方法:

/**
 * @author dxy
 * @version 1.0
 * @date 2021/10/24 9:22
 * @decripton 简历
 * @mail victorydeng@163.com
 */
@Data
public class Resume implements Cloneable {
    private String name;
    private String sex;

    public Resume(WorkExperience workExperience) throws CloneNotSupportedException {
        this.workExperience = workExperience.clone();
    }

    @Override
    protected Resume clone() throws CloneNotSupportedException {
        Resume resume = new Resume(this.workExperience);
        resume.age = this.age;
        resume.name = this.name;
        resume.sex = this.sex;
        return resume;
    }

    private String age;

    private WorkExperience workExperience;



    public Resume(String name) {
        this.name = name;
        workExperience = new WorkExperience();
    }

    //设置个人信息
    public void setPersonalInfo(String age, String sex) {
        this.sex = sex;
        this.age = age;
    }

    //设置工作经历
    public void setWorkExperience(String timeArea, String company) {
        workExperience.timeArea =timeArea;
        workExperience.company = company;
    }

    public void display() {
        System.out.println(String.format("个人基础信息:%s,%s,%s", name, sex, age));
        System.out.println(String.format("工作经历:%s,%s", workExperience.getTimeArea(),workExperience.getCompany()));
    }
}

测试结果:

4.总结:

当我们需要new很多同个类型的对象时,而且这些对象初始化的信息没有很大变化的情况下,克隆是最好的办法。这既隐藏了对象创建的细节,又对性能是大大的提高,,它等于昰不用重新初始化对象,而是动态地获得对象运行时的状态。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

焱童鞋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值