原型模式是创建型模式
首先我们要了解原型模式是干嘛的,有什么好处?
- 克隆对象
- 为了简化new对象的过程,有时候需要许多操作才能new
原型模式无非就分为两种克隆方式,一种是浅克隆,另一种是深克隆,
下面用B站无良up盗版别人视频为例子我们来说明:
浅克隆
浅克隆的话如果无良up盗版了视频,发出来就会和正版一样,但是有一点就是如果正版视频哪里有改动的话,盗版视频就会跟着改动,一模一样
Video.java
import java.util.Date;
/*
* 1.实现一个接口 Cloneable
* 2.重写一个方法 clone()
*/
//video类
public class Video implements Cloneable{//无良up主,克隆别人视频
private String name;
private Date createTime;
@Override
protected Object clone() throws CloneNotSupportedException {
// TODO 自动生成的方法存根
return super.clone();
}
public Video() {
// TODO 自动生成的构造函数存根
}
public Video(String name,Date createTime) {
// TODO 自动生成的构造函数存根
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;
}
public String toString() {
return "Video("+"name='"+name+'\''+
",createTime"+createTime+')';
}
}
BiliBili.java
import java.util.Date;
/*
* 客户端:克隆
*/
public class BiliBili {
public static void main(String[] args) throws CloneNotSupportedException {
// TODO 自动生成的方法存根
//原型对象的创建
Date date=new Date();
Video v1=new Video("狂神说",date);
Video v2=(Video)v1.clone();
System.out.println("v1="+v1);
System.out.println("v2="+v2);
//v1克隆v2
// Video v2=new Video("狂神说",date);
System.out.println("==========浅克隆=============");
date.setTime(2323221);
System.out.println("v1="+v1);
System.out.println("v2="+v2);
/*输出发现一改值克隆的值也改了,这个叫做浅克隆,不是理想的克隆
v1=Video(name='狂神说',createTimeWed Feb 19 10:50:16 CST 2020)
v2=Video(name='狂神说',createTimeWed Feb 19 10:50:16 CST 2020)
=======================
v1=Video(name='狂神说',createTimeThu Jan 01 08:38:43 CST 1970)
v2=Video(name='狂神说',createTimeThu Jan 01 08:38:43 CST 1970)
*/
}
}
深克隆
克隆双方改值无影响,随你up主知道我盗版你视频后怎么改动视频,我自己不改依然还是克隆的最原版的视频
Video.java
import java.util.Date;
/*
* 1.实现一个接口 Cloneable
* 2.重写一个方法 clone()
*/
//video类
public class Video implements Cloneable{//无良up主,克隆别人视频
private String name;
private Date createTime;
@Override
protected Object clone() throws CloneNotSupportedException {
//深克隆,序列化,反序列化
Object obj=super.clone();
Video v=(Video)obj;
v.createTime=(Date)this.createTime.clone();//将这个对象的属性也进行克隆
return obj;
}
public Video() {
// TODO 自动生成的构造函数存根
}
public Video(String name,Date createTime) {
// TODO 自动生成的构造函数存根
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;
}
public String toString() {
return "Video("+"name='"+name+'\''+
",createTime"+createTime+')';
}
}
BiliBili.java
import java.util.Date;
/*
* 客户端:克隆
*/
public class BiliBili {
public static void main(String[] args) throws CloneNotSupportedException {
// TODO 自动生成的方法存根
//原型对象的创建
Date date=new Date();
Video v1=new Video("狂神说",date);
Video v2=(Video)v1.clone();
System.out.println("v1="+v1);
System.out.println("v2="+v2);
//v1克隆v2
// Video v2=new Video("狂神说",date);
System.out.println("==========深克隆=============");
date.setTime(2323221);
System.out.println("v1="+v1);
System.out.println("v2="+v2);
/*输出发现一改值克隆的值不会改了,这个叫做深克隆
v1=Video(name='狂神说',createTimeWed Feb 19 10:50:16 CST 2020)
v2=Video(name='狂神说',createTimeWed Feb 19 10:50:16 CST 2020)
==========深克隆=============
v1=Video(name='狂神说',createTimeThu Jan 01 08:38:43 CST 1970)
v2=Video(name='狂神说',createTimeWed Feb 19 11:02:05 CST 2020)
*/
}
}
如果代码过程中出现这个异常
java.lang.CloneNotSupportedException: com.sxit.Object01
at java.lang.Object.clone(Native Method)
at com.sxit.Object01.main(Object01.java:63)
原因
类没有实现Cloneable接口
public class Video implements Cloneable
反思:
1. SPring bean 单例模式和原型模式不用每次创造节省空间
2. 原型模式会和工厂模式打交道,把工厂模式当作的new用原型模式实现,大多企业都会这么干
3. 生产可乐,不用在看可乐结构,只用把原来的可乐配方接着生产就可以了