原型模式是一种创建型的模式,原型模式的简单程度仅次于单例模式和迭代器模式,正是由于简单,使用的场景非常多。
通过原型模式的通用类图可以看到,其实原型模式的核心就是一个clone方法,通过该方法实现对象的拷贝。
原型模式的优点:
1.原型模式是在内存二进制流的拷贝,要比直接new一个对象性能好很多,特别是要在一个循环体内产生大量对象时。
2.规避构造方法的约束,因为原型模式是在内存二进制流的拷贝,所以是不会调用构造方法的
原型模式的使用场景
1.类的初始化需要消耗非常多的资源(数据、硬件资源等)
2.性能和安全的要求,因为通过new产生一个对象需要非常繁琐的数据准备或访问权限
克隆满足的条件:
clone()方法将对象复制了一份并返还给调用者。所谓“复制”的含义与clone()方法是怎么实现的。一般而言,clone()方法满足以下的描述:
(1)对任何的对象x,都有:x.clone()!=x。换言之,克隆对象与原对象不是同一个对象。
(2)对任何的对象x,都有:x.clone().getClass() == x.getClass(),换言之,克隆对象与原对象的类型一样。
(3)如果对象x的equals()方法定义其恰当的话,那么x.clone().equals(x)应当成立的。
在JAVA语言的API中,凡是提供了clone()方法的类,都满足上面的这些条件。JAVA语言的设计师在设计自己的clone()方法时,也应当遵守着三个条件。一般来说,上面的三个条件中的前两个是必需的,而第三个是可选的。
可能分为浅克隆和深克隆
先看一个例子,看看什么是浅克隆:
public class Something implements Cloneable { private List<String> list = new ArrayList<String>(); // 重写Object类中的clone方法 @Override protected Something clone() { Something something = null; try { something = (Something) super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return something; } public void setValue(String value) { this.list.add(value); } public List<String> getList() { return this.list; } public static void main(String[] args) { //产生一个对象 Something something=new Something(); something.setValue("aaa"); //克隆一个对象 Something thing=something.clone(); thing.setValue("bbb"); System.out.println(something.getList());//结果:[aaa, bbb] } }
从输出结果看,这并不是我们想要的拷贝,Object类提供的clone方法只是拷贝对象,对于对象内部的数组、引用对象都不拷贝,还是指向原生对象的内部元素,这种拷贝就是浅拷贝。
- 浅度克隆
只负责克隆按值传递的数据(比如基本数据类型、String类型),而不复制它所引用的对象,换言之,所有的对其他对象的引用都仍然指向原来的对象。
- 深度克隆
除了浅度克隆要克隆的值外,还负责克隆引用类型的数据。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深度克隆把要复制的对象所引用的对象都复制了一遍,而这种对被引用到的对象的复制叫做间接复制。
深度克隆要深入到多少层,是一个不易确定的问题。在决定以深度克隆的方式复制一个对象的时候,必须决定对间接复制的对象时采取浅度克隆还是继续 采用深度克隆。因此,在采取深度克隆时,需要决定多深才算深。此外,在深度克隆的过程中,很可能会出现循环引用的问题,必须小心处理。
下面以一个场景来叙述一下原型模式的使用,相信大家在大学考试的时候都有过打小抄的情况(没有也不能说明什么),上一面代理模式中说道小明同学找代理打游戏,但是人就不去上课,整体的睡懒觉,好了一个学期过去,今天同小强说马上要考试了,小明很惊讶的说:“不是吧,大学还有考试啊?”此处只能呵呵,那么小明如何应对考试呢,当然是自己上了这么多年学积累下来的经验了,那就是抄别人的.....
代码如下:
/** * 试卷 * */ public class Paper implements Cloneable { private Student student=new Student(); @Override protected Paper clone() { Paper paper = null; try { paper = (Paper) super.clone(); } catch (CloneNotSupportedException e) { // TODO Auto-generated catch block e.printStackTrace(); } return paper; } // 获取学生信息 public Student getStudent() { return this.student; } // 获取考生姓名 public void setName(String name) { this.student.setName(name); } public int getResult() { return 29; } }
/** * * */ public class Student { // 学生姓名 private String name; // 学生学号 private String no; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getNo() { return no; } public void setNo(String no) { this.no = no; } }
public class Client { public static void main(String[] args) { //生成一份试卷 Paper paper=new Paper(); //考生姓名 paper.setName("小强"); //小明复制一份小强的试卷 Paper clonePaper=paper.clone(); clonePaper.setName("小明"); System.out.println(paper.getStudent().getName()); } }
这段程序的输出结果是小明,那小强呢?这就是浅拷贝,结果就是两份试卷的答题人都变成了小明。
相关推荐
该代码是android应用设计模式之原型模式小例子
设计模式之原型模式的Java版本实现和UML类设计图
iOS设计模式之原型模式 博客地址:http://blog.csdn.net/ioswyl88219/article/details/17662945
java设计模式之原型模式,希望对大家有所帮助。
设计模式
设计模式之Prototype(原型) 设计模式之Builder 设计模式之Singleton(单态) 结构模式: 设计模式之Facade(外观) 设计模式之Proxy(代理) 设计模式之Adapter(适配器) 设计模式之Composite(组合) 设计模式之Decorator...
Java 经典设计模式讲解以及项目实战 设计模式简介:主要介绍各种设计模式的概念和运用场景等 设计模式综合运用:主要是笔者在实际工作中运用到的一些设计模式综合运用事例的提炼 Spring设计模式简介:主要是讲述...
iOS设计模式之原型设计模式
设计模式的原型模式的例子,希望对大家有用~~~~~~~~
章节介绍:1、爪哇语言结构性模式之变压器模式介绍 2、爪哇语言抽象工厂创立性模式介绍 3、工厂方法创立...10、设计模式之State 11、设计模式之Facade(外观) 12、设计模式之Interpreter(解释器) 13、设计模式之Visitor
设计模式之禅之 原型模式 设计模式之禅之 原型模式 设计模式之禅之 原型模式设计模式之禅之 原型模式