您的位置:首页 > 编程语言 > Java开发

原型模式(设计模式_09)

2016-12-16 10:19 197 查看
今天给大家介绍一种模式,原型模式

例如:要创建很多个对象,常规思维是 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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息