设计模式之原型模式
Posted lwx-apollo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式之原型模式相关的知识,希望对你有一定的参考价值。
概念原文
Specify the kinds of objects to create using a prototypical instance,and create new objects by copying this prototype.
概念翻译
用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象。
特点
- 性能优良:Java 自带的原型模式基于内存二进制流的复制,在性能上比直接 new 一个对象更加优良。
- 可以使用深克隆方式保存对象的状态,使用原型模式将对象复制一份,并将其状态保存起来,简化了创建对象的过程,以便在需要的时候使用(例如恢复到历史某一状态),可辅助实现撤销操作。
优点与缺点
优点
- 性能提高
- 逃避构造函数的约束。
缺点
- 需要为每一个类都配置一个 clone 方法
- clone 方法位于类的内部,当对已有类进行改造的时候,需要修改代码,违背了开闭原则。
- 当实现深克隆时,需要编写较为复杂的代码,而且当对象之间存在多重嵌套引用时,为了实现深克隆,每一层对象对应的类都必须支持深克隆,实现起来会比较麻烦。
应用场景
- 资源优化场景
- 类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等
- 性能和安全要求的场景
- 通过 new 产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式
- 一个对象多个修改者的场景
- 一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用
项目或框架应用
- java中的Object中的clone方法
代码实现
实现代码
/**
* The class used to be a prototype for students' scores .
* Implements Cloneable interface and override clone method to clone prototype .
* These properties set default value to check whether the value of properties can be cloned when the object is cloned .
* @author luowenxing
*/
public class StudentScore implements Cloneable
private int math = 100;
private int chinese = 100;
private int english = 100;
private String name;
public void score()
System.out.println(name + "'s score are as follows : math-" + math + " ,chinese-" + chinese + " ,english-" + english + " .");
@Override
protected StudentScore clone() throws CloneNotSupportedException
System.out.println("Invoke clone .");
return (StudentScore) super.clone();
public void setMath(int math)
this.math = math;
public void setChinese(int chinese)
this.chinese = chinese;
public void setEnglish(int english)
this.english = english;
public void setName(String name)
this.name = name;
测试
public class PrototypeTest
public static void main(String[] args) throws CloneNotSupportedException
StudentScore jay = new StudentScore();
jay.setName("Jay");
jay.setChinese(95);
jay.setEnglish(85);
jay.setMath(100);
jay.score();
// clone object
StudentScore tom = jay.clone();
// clone object does not equals source object
System.out.println(jay.equals(tom));
// reset student's name, and does not set score
tom.setName("Tom");
tom.score();
测试结果
可以看出原型模式clone出的对象是不一样的,会重新申明一块内存空间,但是属性内容是一样的。
知识拓展
- Java 自带的原型模式基于内存二进制流的复制,不会调用构造函数。
- 浅拷贝和深拷贝:
浅拷贝:Object类提供的方法clone只是拷贝本对象,其对象内部的数组、引用对象等都不拷贝,还是指向原生对象的内部元素地址,这种拷贝就叫做浅拷贝,其他的原始类型比如int、long、char、string(当做是原始类型)等都会被拷贝。
注意: 使用原型模式时,引用的成员变量必须满足两个条件才不会被拷贝:一是类的成员变量,而不是方法内变量;二是必须是一个可变的引用对象,而不是一个原始类型或不可变对象。
深拷贝:对私有的类变量进行独立的拷贝
如:thing.arrayList = (ArrayList)this.arrayList.clone();
相关面试题
- Q:什么是原型模式?
A:见上述文章 - Q:原型模式的特点
A:见上述文章 - Q:原型模式中的clone的对象内存地址分配一样吗?
A:不一样
以上是关于设计模式之原型模式的主要内容,如果未能解决你的问题,请参考以下文章