原型模式
定义:是一种对象创建型模式,他采取复制原型对象的方法来创建对象的实例。使用原型模式创建的实例,具有与原型一样的数据。
特点:
1) 由原型对象自身创建目标对象,也就是说,对象创建这一动作发自原型对象本身。
2) 目标对象是原型对象的一个克隆,也就是说通过原型模式创建的对象,不仅仅与原型对象具有相同的结构,还与原型对象具有相同的值。
3) 根据对象克隆深度层次的不同,有浅度克隆与深度克隆。
图示:
浅度克隆:
package com.offcn.designpattern.prototypepattern; import java.util.Date; public class QIanduClone { public static void main(String[] args) throws CloneNotSupportedException { Date date = new Date(); Video v1 = new Video("原型模式", date); Video v2 = (Video)v1.clone(); System.out.println("v1:"+v1); System.out.println("v2:"+v2); System.out.println("=========================="); date.setTime(32342342); System.out.println("v1:"+v1); System.out.println("v2:"+v2); } } //如果要克隆就必须实现Cloneable接口 class Video implements Cloneable{ private String name; private Date createTime; //浅度克隆时,不需要重写接口中的clone方法 @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } public Video(){}; public Video(String name,Date createTime) { this.name = name; this.createTime = createTime; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Date getCreateTime() { return createTime; } public void setCreateTime(Date createTime) { this.createTime = createTime; } @Override public String toString() { return "Video{" + "name=‘" + name + ‘\‘‘ + ", createTime=" + createTime + ‘}‘; } }
输出:
不足:当被克隆的类中有引用对象(String或Integer等包装类型除外)时,克隆出来的类中的引用变量存储的还是之前的内存地址,也就是说克隆与被克隆的对象是同一个。
这样的话两个对象共享了一个私有变量(Date date),所有人都可以改,是一个种非常不安全的方式,在实际项目中使用还是比较少的。
深度克隆:
package com.offcn.designpattern.prototypepattern; import java.util.Date; public class QIanduClone { public static void main(String[] args) throws CloneNotSupportedException { Date date = new Date(); Video v1 = new Video("原型模式", date); Video v2 = (Video)v1.clone(); System.out.println("v1:"+v1); System.out.println("v2:"+v2); System.out.println("=========================="); date.setTime(32342342); System.out.println("v1:"+v1); System.out.println("v2:"+v2); } } //如果要克隆就必须实现Cloneable接口 class Video implements Cloneable{ private String name; private Date createTime; //深度克隆时,需要重写接口中的clone方法 @Override protected Object clone() throws CloneNotSupportedException { Object obj = super.clone(); Video v = (Video)obj; v.createTime = (Date)this.createTime.clone(); return obj; } public Video(){}; public Video(String name,Date createTime) { this.name = name; this.createTime = createTime; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Date getCreateTime() { return createTime; } public void setCreateTime(Date createTime) { this.createTime = createTime; } @Override public String toString() { return "Video{" + "name=‘" + name + ‘\‘‘ + ", createTime=" + createTime + ‘}‘; } }
输出:
注意:final 类型修饰的成员变量不能进行深度拷贝
使用场景:
1、在创建对象的时候,我们不只是希望被创建的对象继承其基类的基本结构,还希望继承原型对象的数据。
2、希望对目标对象的修改不影响既有的原型对象(深度克隆的时候可以完全互不影响)。
3、隐藏克隆操作的细节,很多时候,对对象本身的克隆需要涉及到类本身的数据细节。
4、类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等;
5、通过 new 产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式;
6、一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用。在实际项目中,原型模式很少单独出现,一般是和工厂方法模式一起出现,通过 clone的方法创建一个对象,然后由工厂方法提供给调用者。原型模式先产生出一个包含
大量共有信息的类,然后可以拷贝出副本,修正细节信息,建立了一个完整的个性对象。
原文:https://www.cnblogs.com/bai3535/p/12313740.html