原型模式

定义:

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

原型模式就是从一个对象再创建另外一个可制定的对象,而且不需要知道任何创建的细节。

结构图

这里写图片描述

Prototype:原型抽象类,保存类的数据和申明克隆自身的接口。

ConcretePrototype:具体原型类,不同的实现会导致克隆的方式不同。

Client:客户端类。

对于Java而言,那个原型抽象类用不着,因为有一个Cloneable接口,需要克隆的对象只需要实现实现Cloneable接口然后按照需求重写clone方法。

深克隆与浅克隆

浅克隆:只复制了普通变量,而引用变量还是共用一份。

深克隆:复制了普通变量和引用变量,引用变量不再共用一份。

Java中可以用序列化和实现Cloneable接口且实现clone()的方法实现深克隆。
在java中普通只实现了Cloneable接口,并在重写时只调用spuer.clone(),只是浅拷贝(Object类的clone方法只是浅拷贝),只会拷贝普通的属性,如果需要拷贝引用属性,属性类得实现Cloneable接口,属性类得有支持深拷贝的clone方法,且在类的Clone方法中需要自己写复制引用属性的部分给新对象。

关于Cloneable接口和clone方法

1.Object中的clone执行的时候使用了RTTI(run-time type identification)的机制,动态得找到目前正在调用clone方法的那个reference,根据它的大小申请内存空间,然后进行bitwise的复制,将该对象的内存空间完全复制到新的空间中去,从而达到shallowcopy的目的。
所以你调用super.clone() 得到的是当前调用类的副本,而不是父类的副本。根本没有必用调用this.clone();

2.要让实例调用clone方法就需要让此类实现Cloneable接口,API里面还有句话是:如果在没有实现 Cloneable 接口的实例上调用 Object 的 clone 方法,则会导致抛出 CloneNotSupportedException 异常,这便是“合法”的含义。 但请注意,Cloneable接口只是个标签接口,不含任何需要实现的方法,就像Serializable接口一样。

实例

复制简历

简历实体类:

public class Resume implements Cloneable{

    private String name;
    private String sex;
    private int age;
    private WorkExperience workExperience;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public WorkExperience getWorkExperience() {
        return workExperience;
    }
    public void setWorkExperience(WorkExperience workExperience) {
        this.workExperience = workExperience;
    }
     @Override
    protected Object clone() throws CloneNotSupportedException {
        //简历的类浅复制
        Resume obj  = (Resume) super.clone();
        //复制引用属性
        obj.setWorkExperience((WorkExperience)this.workExperience.clone());
        return obj;
    }
}

工作经历类:

public class WorkExperience  implements Cloneable{
    private String workDate;
    private String company;
    public String getWorkDate() {
        return workDate;
    }
    public void setWorkDate(String workDate) {
        this.workDate = workDate;
    }
    public String getCompany() {
        return company;
    }
    public void setCompany(String company) {
        this.company = company;
    }

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

客户端类:

public class Client {
    public static void main(String[] args) {
        Resume resume = new Resume();
        resume.setName("A同学");
        resume.setAge(20);
        resume.setSex("男");
        WorkExperience workExperience = new WorkExperience();
        workExperience.setCompany("T公司");
        workExperience.setWorkDate("2017年");
        resume.setWorkExperience(workExperience);

        try {
            Resume obj = (Resume) resume.clone();
            workExperience.setCompany("A公司");
            System.out.println(obj.getWorkExperience().getCompany());
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
}

最终的输出结果是:T公司
证明确实复制了引用。而不是共用原来的引用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值