IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 设计模式-创建型模式-原型(Prototype)模式及Java中原型模式的更多实现方式 -> 正文阅读

[Java知识库]设计模式-创建型模式-原型(Prototype)模式及Java中原型模式的更多实现方式

1、前言

当需要克隆100个名称为Dolly 年龄 1的羊,以往的写法都是直接new 100个Sheep对象;

public class PrototypeDemo {
    public static void main(String[] args) {
        // 克隆100个 名称为Dolly 年龄 1;
        Sheep dolly1 = new Sheep("Dolly", 1);
        Sheep dolly2 = new Sheep("Dolly", 1);
        Sheep dolly3 = new Sheep("Dolly", 1);
        Sheep dolly4 = new Sheep("Dolly", 1);
        // ...
        Sheep dolly100 = new Sheep("Dolly", 1);
    }
    @Data
    static
    class Sheep {
        private String name;

        private int age;
    
        public Sheep (String name,int age){
            this.name = name;
            this.age = age;
        }
    }
}
  • 优点
    • 代码直观,易于理解
  • 缺点
    • 在创建新的对象时,总是需要重新获取原始对象的属性,如果创建的对象比较复杂时,效率较低
    • 总是需要重新初始化对象,而不是动态地获得对象运行时的状态,不够灵活

2、什么是原型模式

原型模式(Prototype Pattern)通过拷贝这些原型,创建新的对象,是用于创建重复的对象,同时又能保证性能。原型模式属于创建型模式,它提供了一种创建对象的最佳方式。

原型模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。

Java中Object类提供了一个clone()方法,该方法可以将一个Java对象复制一份,但是需要实现clone的Java类必须要实现一个接口Cloneable,该接口表示该类能够复制且具有复制的能力

  • 原型模式的实例的拷贝包括

    • 浅复制:将一个对象复制后,其基本数据类型的变量都会重新创建,而引用类型的变量指向的还是原对象所指向的,也就是指向的内存堆地址没变。
    • 深复制:将一个对象复制后,不论是基本数据类型还是引用类型,都是重新创建的
  • 通过实现Cloneable接口,Java默认的实现方式是浅复制,而非深复制。由于Object并没有实现Cloneable接口,所以子类必须实现Cloneable,并调用基类的clone方法才能实现浅复制。

3、原型模式实现


/**
 * 原型模式
 * @author liushiwei
 */
public class PrototypeDemo {
    public static void main(String[] args) throws Exception {
        prototype();
    }
    private static void prototype() throws Exception {

        ArrayList arrayList = new ArrayList();
        arrayList.add("foreFoot");
        Sheep dolly1 = new Sheep("Dolly", 1,arrayList);
        // 对象深拷贝
        Sheep dolly2 = (Sheep)dolly1.clone();
        ArrayList list = dolly2.getListFoot();
        list.add("hindFoot2");

        // 序列化的方式深拷贝
        Sheep dolly3 = (Sheep)dolly1.deepClone();
        ArrayList list3 = dolly3.getListFoot();
        list3.add("hindFoot3");

        System.out.println(dolly1 == dolly2);
        // 验证是拷贝类型,结果浅拷贝
        System.out.println("dolly1.list="+dolly1.getListFoot());
        System.out.println("dolly2.list="+dolly2.getListFoot());
        System.out.println("dolly3.list="+dolly3.getListFoot());
    }

    private static void tradition() {
        // 克隆100个 名称为Dolly 年龄 1;
        Sheep dolly1 = new Sheep("Dolly", 1,null);
        Sheep dolly2 = new Sheep("Dolly", 1,null);
        Sheep dolly3 = new Sheep("Dolly", 1,null);
        Sheep dolly4 = new Sheep("Dolly", 1,null);
        // ...
        Sheep dolly100 = new Sheep("Dolly", 1,null);
    }

}

public class Sheep implements Cloneable, Serializable {

    private String name;

    private int age;

    private ArrayList listFoot;

    public Sheep (){

    }

    public Sheep (String name,int age,ArrayList listFoot){
        this.name = name;
        this.age = age;
        this.listFoot = listFoot;
    }
    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public ArrayList getListFoot() {
        return listFoot;
    }

    public void setListFoot(ArrayList listFoot) {
        this.listFoot = listFoot;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Sheep sheep = (Sheep)super.clone();
        // 对listFoot深拷贝
        sheep.listFoot = (ArrayList) this.listFoot.clone();

        return sheep;
    }

    /**
     * 通过序列化的方式 深拷贝
     * @return
     */
    protected Object deepClone() throws Exception{

        //把对象写入到字节流中
        ByteArrayOutputStream baos =new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(this);

        //把字节流转化为对象
        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bais);
        return (Sheep) ois.readObject();
    }

}

4、原型模式优缺点

  • 原型模式的优点:

    • 提高了创建对象的性能,避免了调用构造器创建对象。

    • 对于创建一个对象需要很多资源的情况,可以减少资源的浪费。

  • 原型模式的缺点:

    • 如果使用Cloneable接口的方式,需要实现Cloneable接口,对代码有一定的侵入性。

    • 如果使用序列化方式,则需要实现Serializable接口,对代码也有一定的侵入性。

5、原型模式的更多实现

  • Spring
    Sheep dolly4 = new Sheep();
    BeanUtils.copyProperties(dolly1,dolly4);
    ArrayList list4 = dolly4.getListFoot();
    list4.add("hindFoot4");
    System.out.println("list4.list="+dolly4.getListFoot());
    
  • fastjson
    • 通过JSONObject.parseObject方法实现
  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-02-28 15:14:49  更:2022-02-28 15:15:08 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 11:52:58-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码