第六章 原型模式

Java设计模式浅析

第一章 简单工厂模式
第二章 工厂方法模式
第三章 抽象工厂模式
第四章 单例模式
第五章 破坏单例模式
第六章 原型模式



第六章 原型模式

概述

原型模式(Prototype Pattern)是指原型实例指定创建对象的种类,
并且通过拷贝这些原型创建新的对象。

所谓原型模式,就是 Java 中的克隆技术,以某个对象为原型,复制出新的对象。
显然新的对象具备原型对象的特点,效率高(避免了重新执行构造过程步骤)。

我们在设计后端代码的工程结构的时候会定义分层领域模型(VO、DTO、DO等),
Service 层调 Dao 层代码获取数据库数据,返回的对象模型是 DO,
在 Service 需要把 DO 对象转换为 VO 对象,这个时候就需要使用到原型模式。

● 类初始化消耗资源较多;
● 使用 new 产生一个对象需要非常繁琐的过程(数据准备、访问权限等);
● 构造函数比较复杂;
● 在循环体中生产大量对象。


一、浅克隆

示例代码

School

public class School {
    private String schoolName;

    public School() {
        schoolName = new String("苏州小学");
    }

    // get set
      public String getSchool() {
        return schoolName;
    }

}
Student  实现 Cloneable接口
public class Student implements Cloneable{

    private String studentName;
    private School school;

    public Student() {
        studentName = new String("张三");
        school = new School();
    }

    @Override
    protected Object clone() {
        Student o = null;
        try{
        o = (Student)super.clone();
        //需要捕获异常
        }catch(CloneNotSupportedException e){
            e.printStackTrace();
        }
            return o;
        }
        //必须对其捕捉或者声明,以便抛出
        //
        //protected Object clone() throws CloneNotSupportedException {
        //return super.clone();
    //}
    // get set
    public String getSchool() {
        return school.getSchool();
    }
}

测试代码


public class PrototypeTest {
    public static void main(String[] args) {
    System.out.println("*************浅克隆*************");

    Student s1 = new Student();
    Student s2 = (Student) s1.clone();
    System.out.println(s1 == s2);
    System.out.println(s1.getSchool() == s2.getSchool());
    System.out.println(s1.getSchool());
    System.out.println(s2.getSchool());
    }
}

在这里插入图片描述

二、深克隆

示例代码

School  实现Serializable 接口
import java.lang.*;
import java.io.*;

public class School implements Serializable {

    private static final long serialVersionUID = 1L;
    private String schoolName;

    public School() {
        schoolName = new String("苏州小学");
    }

    // get set
    public String getSchool() {
        return schoolName;
    }
}

Student 实现的Cloneable接口、Serializable接口
public class Student implements Cloneable, Serializable {
    //实现的Cloneable接口、Serializable接口
  private static final long serialVersionUID = 1L;
    private String studentName;
    private School school;

    public Student() {
        studentName = new String("张三");
        school = new School();
    }
    @Override
    //浅拷贝
    protected Object clone() {
        Student o = null;
        try{
        o = (Student)super.clone();
        //需要捕获异常
        }catch(CloneNotSupportedException e){
            e.printStackTrace();
        }
            return o;
        }
    /**
     * 利用序列化、反序列化实现深拷贝
     *
     * @return
     * @throws Exception
     */
     
     //深拷贝
    public Student deepClone() {
        Student o1 = null;
        try {
            
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(this);

            ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bis);
            o1 = (Student)ois.readObject();
        }
        catch(Exception e){
            e.printStackTrace();
        }
        return o1;
    }

    // get set
    public String getSchool() {
        return school.getSchool();
    }
}

测试代码

DeepClone

public class DeepClone {
public static void main(String[] args) {
    System.out.println("*************深克隆*************");

    Student s1 = new Student();
    Student s2 = (Student) s1.deepClone();
    System.out.println("s1、s2是否相等: "+ (s1 == s2) );
    System.out.println("s1、s2 school equals 比较 : "+s1.getSchool().equals(s2.getSchool()));
    //private String schoolName 所以不相等
    System.out.println("s1、s2 school toString 比较 : "+s1.getSchool().toString()==s2.getSchool().toString());
    //System.out.println(System.identityHashCode(s2.getSchool().toString()));
    }
}

在这里插入图片描述


总结

对象克隆有如下实现方式:
● 继承 Cloneable 接口,实现 clone 方法
● 反射实现克隆,例子有 Apache BeanUtils、PropertyUtils,Spring BeanUtils
● 序列化实现克隆(字节流、JSON)

浅克隆
对值类型的成员变量进行值的复制,
对引用类型的成员变量仅仅复制引用,不复制引用的对象。
对应的实现方式有 Java clone、反射。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值