原型模式

本文介绍了原型模式的概念及其在Java中的实现方式,探讨了浅复制与深复制的区别,并通过简历类实例展示了如何实现深复制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原型模式:
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
类图:
这里写图片描述

原型模式主要用于对象的复制,其核心是Prototype类。JAVA中Prototype类具备以下两个条件:
- 实现Cloneable接口。JAVA中有一个Cloneable接口,作用是通知虚拟机可以安全的在实现了此接口的类上使用clone方法。在JAVA中,只有实现了Cloneable才能使用clone方法进行拷贝,否则会抛出CloneNotSupportedException异常。
- 重写Clone方法。Clone方法是Object中的方法,作用是返回对象的一个拷贝,但其作用域一般是protected,一般的类无法调用,因此Prototype需要把clone方法改成public修饰。

浅复制与深复制:
现在已要写一份简历类,简历包括姓名,性别,包括一个工作经历类,工作经历类包括工作时间和公司信息。然后拷贝简历三份。

浅赋值代码如下:

// 工作经历类
public class WorkExperience {

    public String workDate;
    public String company;
    public void setWorkDate(String workDate){
        this.workDate = workDate;
    }
    public String getWorkDate(){
        return workDate;
    }

    public void setCompany(String company){
        this.company = company;
    }
    public String getCompany(){
        return company;
    }
}

// 简历类

    private String name;
    private String age;
    private String sex;
    private WorkExperience workExperience;

    public Resume(String name){
        this.name = name;
        workExperience = new WorkExperience();
    }
    // 设置个人信息
    public void SetPersonalInfo(String sex, 
            String age){
        this.age = age;
        this.sex = sex;
    }

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

    //打印
    public void Dispaly(){
        System.out.println(name + "  " + age+" "+ " "+sex );
        System.out.println("工作经历:" + workExperience.workDate + " "+
                workExperience.company);
    }

    // 重写clone方法
    @Override
    public Resume clone() throws CloneNotSupportedException {
        // TODO Auto-generated method stub
        Resume resume = null;
        try{
            resume = (Resume)super.clone();
        }catch (CloneNotSupportedException e) {
            // TODO: handle exception
            e.printStackTrace();
        }
        return resume;
    }
}

// 客户端

    private String name;
    private String age;
    private String sex;
    private WorkExperience workExperience;

    public Resume(String name){
        this.name = name;
        workExperience = new WorkExperience();
    }
    // 设置个人信息
    public void SetPersonalInfo(String sex, 
            String age){
        this.age = age;
        this.sex = sex;
    }

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

    //打印
    public void Dispaly(){
        System.out.println(name + "  " + age+" "+ " "+sex );
        System.out.println("工作经历:" + workExperience.workDate + " "+
                workExperience.company);
    }

    // 重写clone方法
    @Override
    public Resume clone() throws CloneNotSupportedException {
        // TODO Auto-generated method stub
        Resume resume = null;
        try{
            resume = (Resume)super.clone();
        }catch (CloneNotSupportedException e) {
            // TODO: handle exception
            e.printStackTrace();
        }
        return resume;
    }
}

以上代码叫做浅复制,被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用都仍然指向原来的对象。也就是说,代码中“工作经历”虽然在resumeA,resumeB,resumeC中分别有复制,但是这三份简历中的引用都指向同一个对象的。

将浅复制改为深复制,代码如下:

// 工作经历类
public class WorkExperience implements Cloneable{

    public String workDate;
    public String company;
    public void setWorkDate(String workDate){
        this.workDate = workDate;
    }
    public String getWorkDate(){
        return workDate;
    }

    public void setCompany(String company){
        this.company = company;
    }
    public String getCompany(){
        return company;
    }

    // 重写clone方法
    @Override
    public WorkExperience clone() throws CloneNotSupportedException {
        // TODO Auto-generated method stub
        WorkExperience workExperience = null;
        try{
            workExperience = (WorkExperience) super.clone();
        }catch (CloneNotSupportedException e) {
            // TODO: handle exception
            e.printStackTrace();
        }
        return workExperience;
    }
}

// 简历类
public class Resume implements Cloneable {

    private String name;
    private String age;
    private String sex;
    private WorkExperience workExperience;

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

    private Resume(WorkExperience workExperience){
        this.workExperience = workExperience;
    }
    // 设置个人信息
    public void SetPersonalInfo(String sex, 
            String age){
        this.age = age;
        this.sex = sex;
    }

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

    //打印
    public void Dispaly(){
        System.out.println(name + "  " + age+" "+ " "+sex );
        System.out.println("工作经历:" + workExperience.workDate + " "+
                workExperience.company);
    }

    // 重写clone方法
    @Override
    public Resume clone() throws CloneNotSupportedException {
        // TODO Auto-generated method stub
        Resume resume = new Resume(this.workExperience);
        resume.name = this.name;
        resume.age = this.age;
        resume.sex = this.sex;
        return resume;
    }
}

// 客户端
public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        Resume resumeA = new Resume("大磊");
        resumeA.SetPersonalInfo("男", "22");
        resumeA.SetWorkExperience("2016-2017", "bbk");

        resumeA.Dispaly();

        Resume resumeB = null;
        Resume resumeC = null;
        try {
            resumeB = (Resume)resumeA.clone();
            resumeC = (Resume)resumeA.clone();
        } catch (CloneNotSupportedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        resumeB.Dispaly();
        resumeC.Dispaly();

    }

}

深复制把引用对象的变量指向复制过的新对象,而不是原有的引用对象。

分析:
使用原型模式创建对象比直接new一个对象在性能上要好的多,因为Object类的clone方法是一个本地方法,它直接操作内存中的二进制流,特别是复制大对象时,性能的差别非常明显。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值