23种设计模式之原型模式

Posted 暴躁的程序猿啊

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了23种设计模式之原型模式相关的知识,希望对你有一定的参考价值。

原型模式

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

主要用于创建对象

原型模式实现只需要实现一个接口 重写clone()方法 。

我们实现中 会有深拷贝和浅拷贝两种情况。

浅克隆

创建一个羊类 作为prototype

public class Sheep{
    /**
     * name名字
     * creatTime 创建时间
     */
    private String name;
    private Date creatTime;

    public Sheep() {
    }

    public Sheep(String name, Date creatTime) {
        this.name = name;
        this.creatTime = creatTime;
    }

    public String getName() {
        return name;
    }

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

    public Date getCreatTime() {
        return creatTime;
    }

    public void setCreatTime(Date creatTime) {
        this.creatTime = creatTime;
    }

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

实现一个Cloneable的接口

重写clone方法

/**
 * 克隆的步骤:
 *  1.实现一个接口  Cloneable
 *  2.重写一个方法
 * 羊的原型
 * @create: 2021/6/28
 * @author: Tony Stark
 */
public class Sheep implements Cloneable{
    /**
     * name名字
     * creatTime 创建时间
     */
    private String name;
    private Date creatTime;

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


    public Sheep() {
    }

    public Sheep(String name, Date creatTime) {
        this.name = name;
        this.creatTime = creatTime;
    }

    public String getName() {
        return name;
    }

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

    public Date getCreatTime() {
        return creatTime;
    }

    public void setCreatTime(Date creatTime) {
        this.creatTime = creatTime;
    }

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

创建一个克隆对象的客户端

先创建一个原型 羊的对象

public class Client {
    public static void main(String[] args) {
        //创建一个原型对象
        Date date = new Date();
        Sheep sheep1 = new Sheep("喜洋洋",date);
        System.out.println("sheep1==>"+sheep1);
        System.out.println("sheep1==>hash"+sheep1.hashCode());
    }
}

在这里插入图片描述

我们克隆出一只羊

public class Client {
    public static void main(String[] args) throws CloneNotSupportedException {
        //创建一个原型对象
        Date date = new Date();
        Sheep sheep1 = new Sheep("喜洋洋",date);
        System.out.println("sheep1==>"+sheep1);
        System.out.println("sheep1==>hash"+sheep1.hashCode());

        //sheep1  克隆出一个 sheep2  克隆羊
        Sheep sheep2 = (Sheep)sheep1.clone();
        System.out.println("sheep2==>"+sheep2);
        System.out.println("sheep2==>hash"+sheep2.hashCode());
    }
}

可以看出我们已经成功克隆出来一模一样的对象了

在这里插入图片描述
小问题

这时候我们sheep1 和sheep2共同用了一个date对象

但是如果我们修改data对象的值 我们会发现一个问题

public class Client {
    public static void main(String[] args) throws CloneNotSupportedException {
        //创建一个原型对象
        Date date = new Date();
        Sheep sheep1 = new Sheep("喜洋洋",date);
        Sheep sheep2 = (Sheep)sheep1.clone();
        System.out.println("sheep1==>"+sheep1);
        System.out.println("sheep2==>"+sheep2);
        date.setTime(123213);
        //sheep1  克隆出一个 sheep2  克隆羊
        //克隆出来的对象跟原来是一模一样的
        System.out.println("sheep1==>"+sheep1);
        System.out.println("sheep2==>"+sheep2);
    }
}

此时我们可以发现两个对象的值都被更改了 这就是浅克隆的一些弊端
在这里插入图片描述

深克隆

我们要实现深克隆有多种方式 可以序列化与反序列化 我们这里直接采用改造克隆方法


    /**
     * 克隆的方法
     * @return
     * @throws CloneNotSupportedException
     */
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Object obj = super.clone();
        //实现深克隆     或者 序列化与反序列化
        Sheep s=(Sheep)obj;
        //将对象的属性也进行克隆
        s.creatTime = (Date) this.creatTime.clone();
        return obj;
    }


当然此时如果属性较多我们这样做就相形见绌了

但现在只有一个字段 是可以的

测试

我们可以看到只有一个 对象被更改了
在这里插入图片描述

完整代码

public class Sheep implements Cloneable{
    /**
     * name名字
     * creatTime 创建时间
     */
    private String name;
    private Date creatTime;

    /**
     * 克隆的方法
     * @return
     * @throws CloneNotSupportedException
     */
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Object obj = super.clone();
        //实现深克隆     或者 序列化与反序列化
        Sheep s=(Sheep)obj;
        //将对象的属性也进行克隆
        s.creatTime = (Date) this.creatTime.clone();
        return obj;
    }


    public Sheep() {
    }

    public Sheep(String name, Date creatTime) {
        this.name = name;
        this.creatTime = creatTime;
    }

    public String getName() {
        return name;
    }

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

    public Date getCreatTime() {
        return creatTime;
    }

    public void setCreatTime(Date creatTime) {
        this.creatTime = creatTime;
    }

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

public class Client {
    public static void main(String[] args) throws CloneNotSupportedException {
        //创建一个原型对象
        Date date = new Date();
        Sheep sheep1 = new Sheep("喜洋洋",date);
        Sheep sheep2 = (Sheep)sheep1.clone();
        System.out.println("sheep1==>"+sheep1);
        System.out.println("sheep2==>"+sheep2);
        date.setTime(123213);
        //sheep1  克隆出一个 sheep2  克隆羊
        System.out.println("sheep1==>"+sheep1);
        System.out.println("sheep2==>"+sheep2);
    }
}

以上是关于23种设计模式之原型模式的主要内容,如果未能解决你的问题,请参考以下文章

GoF 23 种设计模式之原型模式和建造者模式

Java23种设计模式之创建型模式「原型模式」

java设计模式之Prototype 原型模式(浅拷贝和深拷贝)纯干货

23种设计模式 - 原型模式

设计模式之原型模式

Unity与23种设计模式原型模式(Prototype)