模式定义
原型模式:是一种对象创造型模式,用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象。原型模式允许一个对象创建另一个可定制的对象,无需知道任何创建新的对象。
模式结构
模式分析
常见的复制黏贴就运用了原型模式,原型模式分为浅克隆和深克隆。
浅克隆:浅克隆仅仅复制所考虑的对象,而不复制他所引用的成员对象。换言之,复制的对象成员对象仍指向源对象的成员对象。
深克隆:复制的对象及成员对象全部复制一遍。
优点:
(1)当创建的对象较复杂时,使用原型模式可以简化对象的创建。
(2)可以动态的增加或减少产品类
(3)提供了简化的创建结构,无需专门的工厂类实现对象的复制。
(4)可以使用深克隆的方式保存对象的状态。
缺点:
(1)违背“开闭原则”,需要每个类配置一个克隆方法。
(2)在实现深克隆时,需要用到复杂代码。
邮件案例
浅克隆
邮件实体类
package com.zck.prototype; public class ShallowCopyEmail implements Cloneable{ private ShallowCopyAttachment attachment; public ShallowCopyEmail(){ this.attachment = new ShallowCopyAttachment(); } public Object clone(){ ShallowCopyEmail clone = null; try { clone = (ShallowCopyEmail) super.clone(); } catch (CloneNotSupportedException e) { System.out.print("copy faillure"); } return clone; } public ShallowCopyAttachment getAttachment() { return this.attachment; } public void display(){ System.out.print("查看邮件"); } }
邮件成员对象类
package com.zck.prototype; //附件类,是eamil类的成员对象 public class ShallowCopyAttachment { public void downLoad(){ System.out.print("下载附件"); } }
客户端测试类
package com.zck.prototype; public class ShallowCopyClient { public static void main(String[] args) { ShallowCopyEmail email,copyEmail; email = new ShallowCopyEmail(); copyEmail = (ShallowCopyEmail) email.clone(); //两个对象不同,但其成员对象指向同一个对象。 System.out.println(email == copyEmail);//false System.out.println(email.getAttachment() == copyEmail.getAttachment());//true } }
测试结果
深克隆
邮件实体类
package com.zck.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; public class DeepCopyEmail implements Serializable{ private DeepCopyAttachment attachment; public DeepCopyEmail(){ this.attachment = new DeepCopyAttachment(); } public Object deepClone() throws IOException, ClassNotFoundException{ //将对象写入流 ByteArrayOutputStream bao = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bao); oos.writeObject(this); //将对象从流中取出 ByteArrayInputStream bis = new ByteArrayInputStream(bao.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); return (ois.readObject()); } public DeepCopyAttachment getAttachment() { return this.attachment; } public void display(){ System.out.print("查看邮件"); } }
邮件成员实体类
package com.zck.prototype; import java.io.Serializable; public class DeepCopyAttachment implements Serializable{ public void downLoad(){ System.out.print("下载附件"); } }
客户端测试类
package com.zck.prototype; import java.io.IOException; public class DeepCopyClient { public static void main(String[] args) throws ClassNotFoundException, IOException { DeepCopyEmail email,copyEmail = null; email = new DeepCopyEmail(); copyEmail = (DeepCopyEmail) email.deepClone(); //两个对象不同,但其成员对象指向同一个对象。 System.out.println(email == copyEmail);//false System.out.println(email.getAttachment() == copyEmail.getAttachment());//true } }
测试结果