Java设计模式(四):原型模式Prototype
2016-05-25 22:45
656 查看
原型模式是一种创建型设计模式,它通过复制一个已经存在的实例来返回新的实例,而不是新建实例.被复制的实例就是我们所称的原型,这个原型是可定制的.
原型模式多用于创建复杂的或者耗时的实例, 因为这种情况下,复制一个已经存在的实例可以使程序运行更高效,或者创建值相等,只是命名不一样的同类数据.
原型模式中的拷贝分为"浅拷贝"和"深拷贝":
浅拷贝: 对值类型的成员变量进行值的复制,对引用类型的成员变量只复制引用,不复制引用的对象.
深拷贝: 对值类型的成员变量进行值的复制,对引用类型的成员变量也进行引用对象的复制.
类图:
下面我们用克隆羊的例子来示例
改变date之前s1的值==111羊: 1010-04-21 07:34:43
改变date之前s2的值==222羊: 1010-04-21 07:34:43
改变date之前s3的值==333羊: 1010-04-21 07:34:43
改变date之后s1的值==111羊: 2120-05-22 08:35:44
改变date之后s2的值==222羊: 1010-04-21 07:34:43
改变date之后s3的值==333羊: 1010-04-21 07:34:43
原型模式多用于创建复杂的或者耗时的实例, 因为这种情况下,复制一个已经存在的实例可以使程序运行更高效,或者创建值相等,只是命名不一样的同类数据.
原型模式中的拷贝分为"浅拷贝"和"深拷贝":
浅拷贝: 对值类型的成员变量进行值的复制,对引用类型的成员变量只复制引用,不复制引用的对象.
深拷贝: 对值类型的成员变量进行值的复制,对引用类型的成员变量也进行引用对象的复制.
类图:
下面我们用克隆羊的例子来示例
package com.iter.devbox.prototype; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.text.SimpleDateFormat; import java.util.Date; // 克隆 public class Sheep implements Cloneable,Serializable { private String sname; private Date birthday; //利用系统的克隆方法实现克隆对象 protected Object clone() throws CloneNotSupportedException { Sheep s = (Sheep) super.clone(); // 添加下面代码实现深拷贝。即把成员变量为对象的进行拷贝 s.birthday = (Date) this.birthday.clone(); return s; } /** * 利用串行化来做深复制 * 把对象写到流里的过程是串行化(Serilization)过程; * 把对象从流中读出来是并行化(Deserialization)过程. * 写在流里的是对象的一个拷贝,然后再从流里读出来重建对象. */ public Object deepClone() { try { ByteArrayOutputStream bo = new ByteArrayOutputStream(); ObjectOutputStream oo = new ObjectOutputStream(bo); oo.writeObject(this); ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray()); ObjectInputStream oi = new ObjectInputStream(bi); return oi.readObject(); } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); return null; } } public String toString() { return this.sname + ": " + new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(birthday); } public Sheep(String sname, Date birthday) { super(); this.sname = sname; this.birthday = birthday; } public String getSname() { return sname; } public void setSname(String sname) { this.sname = sname; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } } package com.iter.devbox.prototype; import java.util.Calendar; import java.util.Date; public class Client { public static void main(String[] args) throws CloneNotSupportedException { Calendar calendar = Calendar.getInstance(); calendar.set(1010, 3, 21, 7, 34, 43); Date date = new Date(calendar.getTimeInMillis()); Sheep s1 = new Sheep("111羊",date); Sheep s2 = (Sheep) s1.clone(); Sheep s3 = (Sheep) s1.deepClone(); s2.setSname("222羊"); s3.setSname("333羊"); System.out.println("改变date之前s1的值==" + s1.toString()); System.out.println("改变date之前s2的值==" + s2.toString()); System.out.println("改变date之前s3的值==" + s3.toString() + "\n"); calendar.set(2120, 4, 22, 8, 35, 44); date.setTime(calendar.getTimeInMillis()); System.out.println("改变date之后s1的值==" + s1.toString()); System.out.println("改变date之后s2的值==" + s2.toString()); System.out.println("改变date之后s3的值==" + s3.toString()); } }运行结果:
改变date之前s1的值==111羊: 1010-04-21 07:34:43
改变date之前s2的值==222羊: 1010-04-21 07:34:43
改变date之前s3的值==333羊: 1010-04-21 07:34:43
改变date之后s1的值==111羊: 2120-05-22 08:35:44
改变date之后s2的值==222羊: 1010-04-21 07:34:43
改变date之后s3的值==333羊: 1010-04-21 07:34:43
相关文章推荐
- Java 内部类访问格式
- error和exception有什么区别?
- java的primitive主数据类型和引用
- 异常整理之:java.lang.NoClassDefFoundError:org/hamcrest/SelfDescribing
- struts2的一点知识(引入别人的项目,path问题,package的名字不能一样哦 )
- 是不是有经验的JavaEE开发者,看你json玩的6不6(下)
- struts2复制项目的时候需要注意的
- Java代理学习-创建动态类及查看其方法列表信息
- 描述使用AJAX提交请求,处理响应的基本步骤。
- java中注解的使用与实例(一)
- TopCoder 客户端被 Java 安全程序拦截
- 如何检查和解决Java虚拟机内存溢出的问题?
- Java实现定时任务的三种方法(转)
- 观察者模式-JAVA
- java注释指导手册
- Java 内部类访问规则
- java 包关键字和面向对象总结
- java keytool 使用
- ubuntu安装Eclipse和创建快捷方式
- java通过字符串调用方法,java反射应用实例