Java设计模式-原型模式

发布于:2024-04-26 ⋅ 阅读:(25) ⋅ 点赞:(0)

概念:

原型模式是一种创建型设计模式,它允许通过复制现有对象来创建新对象,而无需通过标准构造函数来创建。在原型模式中,新对象的创建是通过克隆现有对象而实现的,因此它是基于原型对象的复制而创建新对象的。
在Java中,原型模式通常通过实现 Cloneable 接口和重写 clone() 方法来实现。Cloneable 接口是一个标记接口,它指示了该类的实例可以被克隆。然后,通过重写 clone() 方法来实现对象的克隆。
换一个方式理解
原型模式就像是制作复印件一样。假设你有一份文件,想要多份一模一样的,但是你又不想重新从头写一遍。这时候,你可以使用原型模式:先制作一份原始文件,然后通过复制这份原始文件,就可以得到多份完全相同的副本。

代码1:

/**
 * 怎么实现克隆。拷贝?
 * 1、实现一个接口:
 * 2、重写一个方法
 */
public class Video implements Cloneable{//克隆视频
    private String name;

    private Date createTime;

    /**
     * 重写克隆方法
     * @return
     * @throws CloneNotSupportedException
     */
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    public Video(String name, Date createTime) {
        this.name = name;
        this.createTime = createTime;
    }

    public Video() {
    }

    public String getName() {
        return name;
    }

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

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    @Override
    public String toString() {
        return "Video{" +
                "name='" + name + '\'' +
                ", createTime=" + createTime +
                '}';
    }
}

我们这有一个视频类。实现了Cloneable接口并重写clone()方法。这个clone()方法调用父类的克隆方法。而这个父类中的clone()是在本地克隆
在这里插入图片描述

测试类
import java.util.Date;

/**
 * 客户端。实现克隆
 */
public class BiliBiliClient {
    public static void main(String[] args) throws CloneNotSupportedException {
        Date date = new Date();
        //需要一个原型对象实现克隆
        //原型对象叫做v1
        Video v1 = new Video("Java从入门到精通", date);
        System.out.println("v1=====>"+v1);
        System.out.println("v1.hashCode=====>"+v1.hashCode());
        //v1可以克隆v2
        Video v2 = (Video) v1.clone();
        System.out.println("v2=====>"+v2);
        System.out.println("v2.hashCode=====>"+v2.hashCode());
        //修改v2的值
        v2.setName("张三");
        System.out.println(v2);
    }
}

创建一个BliBlili客户端类实现克隆,首先,我们先把原型对象创建出来,v1的hashCode输出。我们在想创建一个v2对象的时候,传统的方式是不是还需要new Video对象,但是现在我们可以直接使用v1.clone()方法进行创建,返回的是一个Object类。强制转换成Video对象。在进行把克隆的内容V2进行输出。此时两个对象内容一样,但是hashCode不一样

测试结果:

在这里插入图片描述

问题:

在这里插入图片描述
V2对象是V1对象拷贝过来的。但是他们还是指向同一个地址。

验证:

修改客户端的代码:

import java.util.Date;

/**
 * 客户端。实现克隆
 */
public class BiliBiliClient {
    public static void main(String[] args) throws CloneNotSupportedException {
        Date date = new Date();
        //需要一个原型对象实现克隆
        //原型对象叫做v1
        Video v1 = new Video("Java从入门到精通", date);
        Video v2 = (Video) v1.clone();
        System.out.println("v1原始的值:=====>"+v1);
        System.out.println("v2原始的值:=====>"+v2);
        //修改后的值,把date数值改变一下
        System.out.println("==================================");
        date.setTime(12345678);
        System.out.println("v1修改后的:=====>"+v1);
        System.out.println("v2修改后的:=====>"+v2);

//
//
//        System.out.println("v1.hashCode=====>"+v1.hashCode());
//        //v1可以克隆v2
//
//        System.out.println("v2=====>"+v2);
//        System.out.println("v2.hashCode=====>"+v2.hashCode());
//        //修改v2的值
//        v2.setName("张三");
//        System.out.println(v2);
    }
}

此时我们修改V1的值。上图所示,我们v1指向的是data。但是v2是v1克隆出来的。地址值是没有变化的。所以这是浅克隆。

测试结果:

在这里插入图片描述
我们理想的情况是:深度克隆
在这里插入图片描述
地址也会完全变化的。最简单的一种就是改造克隆的方法、修改原型类中的克隆方法实现深度克隆:

代码2:

package com.MrSun.PrototypeTest.demo02;

import java.util.Date;

public class Video implements Cloneable{
    private String name;

    private Date createTime;

    /**
     * 重写克隆方法
     * @return
     * @throws CloneNotSupportedException
     */
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Object obj = super.clone();//深度克隆
        Video v=(Video) obj;
        //将这个对象的属性也进行克隆
        v.createTime= (Date) this.createTime.clone();
        return obj;
    }

    public Video(String name, Date createTime) {
        this.name = name;
        this.createTime = createTime;
    }

    public Video() {
    }

    public String getName() {
        return name;
    }

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

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    @Override
    public String toString() {
        return "Video{" +
                "name='" + name + '\'' +
                ", createTime=" + createTime +
                '}';
    }
}

主要就修改了cole方法

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Object obj = super.clone();//深度克隆
        Video v=(Video) obj;
        //将这个对象的属性也进行克隆
        v.createTime= (Date) this.createTime.clone();
        return obj;
    }

我们对里面的属性也进行克隆。这样就可以实现深度克隆、

验证:

在这里插入图片描述
加油!!!!!!!!!!