博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
重学设计模式(四)—— 原型模式
阅读量:4223 次
发布时间:2019-05-26

本文共 2764 字,大约阅读时间需要 9 分钟。

前言

Prototype原型模式是一种创建型设计模式,它允许一个对象再创建另外一个可定制的对象。

这里写图片描述

Java Object中已经提供了一个Clone( )方法,但是要实现原型模式,必须实现Cloneable接口,使用Cloneable接口都不用导入包。

克隆一个对象有两种方式:

浅克隆:copy该对象,然后保留该对象原有的引用。也就是说不克隆该对象的属性。

深克隆:copy该对象,并且把该对象的所有属性也克隆出一份新的。

浅克隆

我们先看一下如下代码的运行结果:

public class School {    private String name;    private String type;    public School(String name, String type){        this.name = name;        this.type = type;    }    /*构造方法、get方法、set方法省略*/}
public class Student implements Cloneable {
private String name; private int age; private School school; /*构造方法、get方法、set方法省略*/ @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); }}
public class Prototype {    public static void main(String[] args){        School school = new School("AAA","Junior High");        Student studentA = new Student("alex", 0, school);        System.out.println(studentA.toString());        try {            Student studentB = (Student) studentA.clone();            System.out.println(studentB.toString());            System.out.println("======================");            school.setName("BBB");            school.setType("Senior High");            studentA.setName("Jack");            studentA.setAge(10);            System.out.println(studentA.toString());            System.out.println(studentB.toString());        }catch (CloneNotSupportedException e){            e.printStackTrace();        }    }}

运行结果:

这里写图片描述

上图的运行结果中,感觉部分属性复制成功(红色字段),部分属性没有复制成功(绿色字段),这是什么原因呢?

我们需要来了解clone()主要做了些什么,创建一个新对象,然后将当前对象的非静态字段复制到该新对象,如果字段是值类型的,那么对该字段执行复制;如果该字段是引用类型的话,则复制引用但不复制引用的对象。因此,原始对象及其副本引用同一个对象

也就是说Student的内部属性中包含有两个引用类型,因此即便使用clone方法,原始对象及其副本引用同一个对象。

那这么实现完全的复制呢,也就是深克隆呢?

深克隆

一个简单直接的想法就是在克隆对象的同时,把该对象的属性也连带着克隆出新的。 这就要求这个被引用的对象必须也要实现Cloneable接口并且实现clone方法。其实此法也是换汤不换药,那有没有更好一点的方法呢?有的,这就是序列化与反序列化

public class School implements Serializable{
private String name; private String type; public School(String name, String type){ this.name = name; this.type = type; }}
public class Student implements Serializable {
private String name; private int age; private School school; public Student(String name, int age, School school){ this.name = name; this.age = age; this.school = school; /*构造方法、get方法、set方法省略*/ protected Object deepClone() throws IOException, ClassNotFoundException { ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(this); ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); return ois.readObject(); }}

这里写图片描述

可以看到,对象被完全复制了。

总结

本文介绍了原型模式,并以此引出了浅拷贝和深拷贝两种对象复制方式,希望能对读者有所帮助。

你可能感兴趣的文章
面向自动驾驶车辆验证的抽象仿真场景生成
查看>>
一种应用于GPS反欺骗的基于MLE的RAIM改进方法
查看>>
自动驾驶汽车GPS系统数字孪生建模(一)
查看>>
自动驾驶汽车GPS系统数字孪生建模(二)
查看>>
CUDA 学习(五)、线程块
查看>>
CUDA 学习(八)、线程块调度
查看>>
CUDA 学习(九)、CUDA 内存
查看>>
CUDA 学习(十一)、共享内存
查看>>
游戏感:虚拟感觉的游戏设计师指南——第十四章 生化尖兵
查看>>
游戏感:虚拟感觉的游戏设计师指南——第十五章 超级马里奥64
查看>>
游戏感:虚拟感觉的游戏设计师指南——第十七章 游戏感的原理
查看>>
游戏感:虚拟感觉的游戏设计师指南——第十八章 我想做的游戏
查看>>
游戏设计的艺术:一本透镜的书——第十章 某些元素是游戏机制
查看>>
游戏设计的艺术:一本透镜的书——第十一章 游戏机制必须平衡
查看>>
游戏设计的艺术:一本透镜的书——第十二章 游戏机制支撑谜题
查看>>
游戏设计的艺术:一本透镜的书——第十三章 玩家通过界面玩游戏
查看>>
编写苹果游戏中心应用程序(翻译 1.3 为iOS应用程序设置游戏中心)
查看>>
编写苹果游戏中心应用程序(翻译 1.4 添加游戏工具包框架)
查看>>
编写苹果游戏中心应用程序(翻译 1.5 在游戏中心验证本地玩家)
查看>>
编写苹果游戏中心应用程序(翻译 1.6 获取本地玩家的信息)
查看>>