Java 设计模式——原型模式(创建型设计模式)
2021/12/16 12:11:05
本文主要是介绍Java 设计模式——原型模式(创建型设计模式),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
一、什么是原型模式
所谓原型模式就是克隆模式
也可以理解为复制一个对象
克隆存在两个方向:浅克隆、深克隆
二、浅克隆
首先我们要知道对象中除了常量类型(int、boolean、double等)、特殊的字符串类型外还有引用类型(其实就是java类中的另外的一个java对象),其次就是要知道这些类型都是有一个内存地址指向的
最后要注意的是被克隆的对象必须Cloneable,Serializable这两个接口
那么浅克隆是什么呢?
被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。 Object类提供的方法clone只是拷贝本对象 , 其对象内部的数组、引用对象等都不拷贝,还是指向原生对象的内部元素地址
举例
//这里用了lombok插件,不知道的建议可以百度一下 @Data public class Psn implements Cloneable,Serializable{ private String name; private String age; private Date birth; /** * 实现克隆的方法 */ public Object clone() throws CloneNotSupportedException{ return super.clone(); } }
Test
public static void main(String[] args) throws CloneNotSupportedException { Date date = new Date(1231231231231l); Psn psn= new Psn (); psn.setName("test"); psn.setAge(18); psn.setBirth(date); System.out.println("----输出原型对象的属性------"); System.out.println(psn); System.out.println(psn.getName()); System.out.println(psn.getBirth()); // 克隆对象 Psn psn1 =(Psn ) psn.clone(); // 修改原型对象中的属性 date.setTime(123231231231l); System.out.println(user.getBirth()); // 修改参数 psn1.setName("test1"); System.out.println("-------克隆对象的属性-----"); System.out.println(psn1); System.out.println(psn1.getName()); System.out.println(psn1.getBirth()); }
这里就不输出结果了,自己观察一下日志
三、深克隆
被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍。
第一种方式,重写实例clone方法内的部分
Object object = super.clone(); // 实现深度克隆(deep clone) PsnCopy psnCopy = (PsnCopy)object; psnCopy.birth = (Date) this.birth.clone(); return object;
第二种方式,使用序列化和反序列化
public static void main(String[] args) throws CloneNotSupportedException { Date date = new Date(1231231231231l); Psn psn= new Psn (); psn.setName("test"); psn.setAge(18); psn.setBirth(date); System.out.println("----输出原型对象的属性------"); System.out.println(psn); System.out.println(psn.getName()); System.out.println(psn.getBirth()); //使用序列化和反序列化实现深复制 ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(psn); byte[] bytes = bos.toByteArray(); ByteArrayInputStream bis = new ByteArrayInputStream(bytes); ObjectInputStream ois = new ObjectInputStream(bis); //克隆好的对象! Psn psn1 = (Psn) ois.readObject(); // 修改原型对象的值 date.setTime(221321321321321l); System.out.println(psn.getBirth()); System.out.println("------克隆对象的属性-------"); System.out.println(psn1); System.out.println(psn1.getName()); System.out.println(psn1.getBirth());
四、原型模式和直接new对象方式的比较
当我们需要大量的同一类型对象的时候可以使用原型模式,下面是两种方式的性能对比:
用两种方式同时生成1000个对象
/** * 测试普通new方式创建对象和clone方式创建对象的效率差异! * 如果需要短时间创建大量对象,并且new的过程比较耗时。则可以考虑使用原型模式! * @author 波波烤鸭 * */ public class Client4 { public static void testNew(int size){ long start = System.currentTimeMillis(); for(int i=0;i<size;i++){ Psn t = new Psn(); } long end = System.currentTimeMillis(); System.out.println("new的方式创建耗时:"+(end-start)); } public static void testClone(int size) throws CloneNotSupportedException{ long start = System.currentTimeMillis(); User t = new User(); for(int i=0;i<size;i++){ Psn temp = (Psn) t.clone(); } long end = System.currentTimeMillis(); System.out.println("clone的方式创建耗时:"+(end-start)); } public static void main(String[] args) throws Exception { testNew(1000); testClone(1000); } } class User implements Cloneable { //用户 public User() { try { Thread.sleep(10); //模拟创建对象耗时的过程! } catch (InterruptedException e) { e.printStackTrace(); } } @Override protected Object clone() throws CloneNotSupportedException { Object obj = super.clone(); //直接调用object对象的clone()方法! return obj; } }
输出结果:
小结:通过clone的方式在获取大量对象的时候性能开销基本没有什么影响,而new的方式随着实例的对象越来越多,性能会急剧下降,所以原型模式是一种比较重要的获取实例的方式。大家应该掌握好
原型模式很少单独出现,一般是和工厂方法模式一起出现,通过clone的方法创建一个对象,然后由工厂方法提供给调用者。
• spring中bean的创建实际就是两种:单例模式和原型模式。(原型模式需要和工厂模式搭配起来)
这篇关于Java 设计模式——原型模式(创建型设计模式)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南