这里有新鲜出炉的 Java 函数式编程,程序狗速度看过来!
Java 程序设计语言
java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的 Java 程序设计语言和 Java 平台(即 JavaEE(j2ee), JavaME(j2me), JavaSE(j2se))的总称.
这篇文章主要介绍了设计模式之原型模式,小编觉得挺不错的,现在分享给大家,也给大家做个参考.一起跟随小编过来看看吧
定义:用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象.
类型:创建类模式
类图:
原型模式主要用于对象的复制,它的核心是就是类图中的原型类 Prototype.Prototype 类需要具备以下两个条件:
实现 Cloneable 接口.在 java 语言有一个 Cloneable 接口,它的作用只有一个,就是在运行时通知虚拟机可以安全地在实现了此接口的类上使用 clone 方法.在 java 虚拟机中,只有实现了这个接口的类才可以被拷贝,否则在运行时会抛出 CloneNotSupportedException 异常.
重写 Object 类中的 clone 方法.Java 中,所有类的父类都是 Object 类,Object 类中有一个 clone 方法,作用是返回对象的一个拷贝,但是其作用域 protected 类型的,一般的类无法调用,因此,Prototype 类需要将 clone 方法的作用域修改为 public 类型.
原型模式是一种比较简单的模式,也非常容易理解,实现一个接口,重写一个方法即完成了原型模式.在实际应用中,原型模式很少单独出现.经常与其他模式混用,他的原型类 Prototype 也常用抽象类来替代.
实现代码:
原型模式的优点及适用场景
class Prototype implements Cloneable {
public Prototype clone() {
Prototype prototype = null;
try {
prototype = (Prototype) superclone();
} catch(CloneNotSupportedException e) {
e.printStackTrace();
}
return prototype;
}
}
class ConcretePrototype extends Prototype {
public void show() {
System.out.println("原型模式实现类");
}
}
public class Client {
public static void main(String[] args) {
ConcretePrototype cp = new ConcretePrototype();
for (int i = 0; i < 10; i++) {
ConcretePrototype clonecp = (ConcretePrototype) cpclone();
clonecp.show();
}
}
}
使用原型模式创建对象比直接 new 一个对象在性能上要好的多,因为 Object 类的 clone 方法是一个本地方法,它直接操作内存中的二进制流,特别是复制大对象时,性能的差别非常明显.
使用原型模式的另一个好处是简化对象的创建,使得创建对象就像我们在编辑文档时的复制粘贴一样简单.
因为以上优点,所以在需要重复地创建相似对象时可以考虑使用原型模式.比如需要在一个循环体内创建对象,假如对象创建过程比较复杂或者循环次数很多的话,使用原型模式不但可以简化创建过程,而且可以使系统的整体性能提高很多.
原型模式的注意事项
使用原型模式复制对象不会调用类的构造方法.因为对象的复制是通过调用 Object 类的 clone 方法来完成的,它直接在内存中复制数据,因此不会调用到类的构造方法.不但构造方法中的代码不会执行,甚至连访问权限都对原型模式无效.还记得单例模式吗?单例模式中,只要将构造方法的访问权限设置为 private 型,就可以实现单例.但是 clone 方法直接无视构造方法的权限,所以,单例模式与原型模式是冲突的,在使用时要特别注意.
深拷贝与浅拷贝.Object 类的 clone 方法只会拷贝对象中的基本的数据类型,对于数组,容器对象,引用对象等都不会拷贝,这就是浅拷贝.如果要实现深拷贝,必须将原型模式中的数组,容器对象,引用对象等另行拷贝.例如:
由于 ArrayList 不是基本类型,所以成员变量 list,不会被拷贝,需要我们自己实现深拷贝,幸运的是 Java 提供的大部分的容器类都实现了 Cloneable 接口.所以实现深拷贝并不是特别困难.
public class Prototype implements Cloneable {
private ArrayList list = new ArrayList();
public Prototype clone() {
Prototype prototype = null;
try {
prototype = (Prototype) superclone();
prototype.list = (ArrayList) this.list.clone();
} catch(CloneNotSupportedException e) {
e.printStackTrace();
}
return prototype;
}
}
PS:深拷贝与浅拷贝问题中,会发生深拷贝的有 java 中的 8 中基本类型以及他们的封装类型,另外还有 String 类型.其余的都是浅拷贝.
来源: http://www.phperz.com/article/18/0118/355302.html