今天给大家介绍一种模式,原型模式
例如:要创建很多个对象,常规思维是 new 对象(),new 对象(),new 对象(),new 对象(),new 对象(),new 对象(),new 对象(),new 对象(),
省略…
原型模式可以去复制对象,而不是创建new对象,可以提高性能,以下就用一个案例来以说明:
在用案例说明之前,首先了解 Cloneable接口
Cloneable接口 (对象克隆):
Object中的clone执行的时候使用了RTTI(run-time type identification)的机制,动态找到目前正在调用clone方法的那个reference,根据它的大小申请内存空间,然后进行bitwise的复制,将该对象的内存空间完全复制到新的空间中去,从而达到shallowcopy的目的,所以你调用super.clone() 得到的是当前调用类的副本,而不是父类的副本。
// 定义一个原型类 实现 Cloneable接口
public class Prototype implements Cloneable{
// 返回 Prototype,这种方式 在 JDK1.8是不支持的
/*
protected Prototype clone() throws CloneNotSupportedException {
Prototype prototype = (Prototype) super.clone();
return prototype;
}
*/
/**
* 实现Cloneable接口后,重写clone方法,此方法放回最终父类Object
*/
protected Object clone() {
Prototype prototype = null;
try {
prototype = (Prototype) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return prototype;
}
}
// 原型Class继承 Prototype
public class PrototypeClass extends Prototype{
// 年龄
private int age;
// 传入年龄
public void setAge(int age) {
this.age = age;
}
/**
* 此方法就是打印一句话
*/
public void println() {
System.out.println("PrototypeClass println()... 年龄是:" + age);
}
}
// 客户端程序,传统方式,不使用原型模式
public class Main {
public static void main(String[] args) throws CloneNotSupportedException {
// 不使用原型的方式
PrototypeClass prototypeClass1 = new PrototypeClass();
prototypeClass1.setAge(1);
prototypeClass1.println();
PrototypeClass prototypeClass2 = new PrototypeClass();
prototypeClass2.setAge(2);
prototypeClass2.println();
PrototypeClass prototypeClass3 = new PrototypeClass();
prototypeClass3.setAge(3);
prototypeClass3.println();
PrototypeClass prototypeClass4 = new PrototypeClass();
prototypeClass4.setAge(4);
prototypeClass4.println();
PrototypeClass prototypeClass5 = new PrototypeClass();
prototypeClass5.setAge(5);
prototypeClass5.println();
// 省略... 后续 写了一百次 new new PrototypeClass();
}
使用原型模式
// 客户端程序,调用原型
public class Main {
public static void main(String[] args) throws CloneNotSupportedException {
// 就是简单的 原型Class = new 原型Class,值new 这一次之后,后续不在重新去new,只拷贝对象:例如:
PrototypeClass pc = new PrototypeClass();
for (int i = 0; i < 100; i++) {
// pc.clone(); 对象的复制
PrototypeClass pcFor = (PrototypeClass) pc.clone();
pc.setAge(i);
pcFor.println();
}
}
}
运行结果:
小故事:
虢霭窿是热爱学习的学生,学习成绩很好,每一次考试自己的名字都几乎会写错,他爸爸知道这件事情之后,决定让他写自己的名字一百遍,于是就有了以下这些代码的实现:
//定义一个原型类(我的名字) 实现 Cloneable接口
public class MyName implements Cloneable{
// 返回 MyName,这种方式 在 JDK1.8是不支持的
/*
protected MyName clone() throws CloneNotSupportedException {
MyName myName = (MyName) super.clone();
return myName;
}
*/
/**
* 实现Cloneable接口后,重写clone方法,此方法放回最终父类Object
*/
protected Object clone() {
MyName myName = null;
try {
myName = (MyName) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return myName;
}
}
// 写我的名字类 继承 原型
public class WriteMyName extends MyName {
// 写的内容
private String context;
// 封装写的内容
public void setContext(String context) {
this.context = context;
}
public void writeName() {
System.out.println(context);
}
}
常规的方式去抄写一百遍自己的名字:
// 客户端程序
public class Main {
public static void main(String[] args) {
WriteMyName myName1 = new WriteMyName();
myName1.setContext("写虢霭窿第1遍");
myName1.writeName();
WriteMyName myName2 = new WriteMyName();
myName2.setContext("写虢霭窿第2遍");
myName2.writeName();
WriteMyName myName3 = new WriteMyName();
myName3.setContext("写虢霭窿第3遍");
myName3.writeName();
WriteMyName myName4 = new WriteMyName();
myName4.setContext("写虢霭窿第4遍");
myName4.writeName();
WriteMyName myName5 = new WriteMyName();
myName5.setContext("写虢霭窿第5遍");
myName5.writeName();
// 省略 ....
}
}
最后虢霭窿写完了,发现好累啊
原型模式去完成:
// 客户端程序
public class Main {
public static void main(String[] args) {
/**
WriteMyName myName1 = new WriteMyName();
myName1.setContext("写虢霭窿第1遍");
myName1.writeName();
WriteMyName myName2 = new WriteMyName();
myName2.setContext("写虢霭窿第2遍");
myName2.writeName();
WriteMyName myName3 = new WriteMyName();
myName3.setContext("写虢霭窿第3遍");
myName3.writeName();
WriteMyName myName4 = new WriteMyName();
myName4.setContext("写虢霭窿第4遍");
myName4.writeName();
WriteMyName myName5 = new WriteMyName();
myName5.setContext("写虢霭窿第5遍");
myName5.writeName();
// 省略 ....
**/
WriteMyName myName = new WriteMyName();
for (int i = 0; i < 100; i++) {
WriteMyName wmn = (WriteMyName) myName.clone();
wmn.setContext("写虢霭窿第" + i + "遍");
wmn.writeName();
}
}
}
运行结果:
以上是简单的原型模式示例,并不完善,谢谢大家观赏!!!
谢谢大家的观看,更多精彩技术博客,会不断的更新,请大家访问,
刘德利CSDN博客, http://blog.csdn.net/u011967006