原型模式(Prototype Pattern):原型模式是一种对象创建型模式,用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象。原型模式允许一个对象再创建另外一个可定制的对象,无须知道任何创建的细节。
原型模式的基本工作原理是通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝原型自己来实现创建过程。
在面向对象系统中,使用原型模式来复制一个对象自身,从而克隆出多个与原型对象一模一样的对象。
在软件系统中,有些对象的创建过程较为复杂,而且有时候需要频繁创建,原型模式通过给出一个原型对象来指明所要创建的对象的类型,然后用复制这个原型对象的办法创建出更多同类型的对象,这就是原型模式的意图所在。
从孙大圣的手段谈起
孙悟空在与黄风怪的战斗中,"使一个身外身的手段:把毫毛揪下一把,用口嚼得粉碎,望上一喷,叫声'变',变有百十个行者,都是一样得打扮,各执一根铁棒,把那怪围在空中。"换而言之,孙悟空可以根据自己的形象,复制出很多"身外身"来。
老孙这种身外身的手段在面向对象设计领域里叫原型(Prototype)模式。
public class Attachment { public void download() { System.out.println("下载附件"); } }
public class Email implements Cloneable { private Attachment attachment=null; public Email() { this.attachment=new Attachment(); } public Object clone() { Email clone=null; try { clone=(Email)super.clone(); } catch(CloneNotSupportedException e) { System.out.println("Clone failure!"); } return clone; } public Attachment getAttachment() { return this.attachment; } public void display() { System.out.println("查看邮件"); } }
public class Client { public static void main(String a[]) { Email email,copyEmail; email=new Email(); copyEmail=(Email)email.clone(); System.out.println("email==copyEmail?"); System.out.println(email==copyEmail); System.out.println("email.getAttachment==copyEmail.getAttachment?"); System.out.println(email.getAttachment()==copyEmail.getAttachment()); } }代码二、
import java.io.*; public class Attachment implements Serializable { public void download() { System.out.println("下载附件"); } }
import java.io.*; public class Email implements Serializable { private Attachment attachment=null; public Email() { this.attachment=new Attachment(); } public Object deepClone() throws IOException, ClassNotFoundException, OptionalDataException { //将对象写入流中 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 Attachment getAttachment() { return this.attachment; } public void display() { System.out.println("查看邮件"); } }
public class Client { public static void main(String a[]) { Email email,copyEmail=null; email=new Email(); try{ copyEmail=(Email)email.deepClone(); } catch(Exception e) { e.printStackTrace(); } System.out.println("email==copyEmail?"); System.out.println(email==copyEmail); System.out.println("email.getAttachment==copyEmail.getAttachment?"); System.out.println(email.getAttachment()==copyEmail.getAttachment()); } }
import java.util.*; interface MyColor extends Cloneable { public Object clone(); public void display(); } class Red implements MyColor { public Object clone() { Red r=null; try { r=(Red)super.clone(); } catch(CloneNotSupportedException e) { } return r; } public void display() { System.out.println("This is Red!"); } } class Blue implements MyColor { public Object clone() { Blue b=null; try { b=(Blue)super.clone(); } catch(CloneNotSupportedException e) { } return b; } public void display() { System.out.println("This is Blue!"); } } class PrototypeManager { private Hashtable ht=new Hashtable(); public PrototypeManager() { ht.put("red",new Red()); ht.put("blue",new Blue()); } public void addColor(String key,MyColor obj) { ht.put(key,obj); } public MyColor getColor(String key) { return (MyColor)((MyColor)ht.get(key)).clone(); } } class Client { public static void main(String args[]) { PrototypeManager pm=new PrototypeManager(); MyColor obj1=(MyColor)pm.getColor("red"); obj1.display(); MyColor obj2=(MyColor)pm.getColor("red"); obj2.display(); System.out.println(obj1==obj2); } }
class Student implements Cloneable { private String stuName; private String stuSex; private int stuAge; private String stuMajor; private String stuCollege; private String stuUniversity; public Student(String stuName,String stuSex,int stuAge,String stuMajor,String stuCollege,String stuUniversity) { this.stuName=stuName; this.stuSex=stuSex; this.stuAge=stuAge; this.stuMajor=stuMajor; this.stuCollege=stuCollege; this.stuUniversity=stuUniversity; } public void setStuName(String stuName) { this.stuName = stuName; } public void setStuSex(String stuSex) { this.stuSex = stuSex; } public void setStuAge(int stuAge) { this.stuAge = stuAge; } public void setStuMajor(String stuMajor) { this.stuMajor = stuMajor; } public void setStuCollege(String stuCollege) { this.stuCollege = stuCollege; } public void setStuUniversity(String stuUniversity) { this.stuUniversity = stuUniversity; } public String getStuName() { return (this.stuName); } public String getStuSex() { return (this.stuSex); } public int getStuAge() { return (this.stuAge); } public String getStuMajor() { return (this.stuMajor); } public String getStuCollege() { return (this.stuCollege); } public String getStuUniversity() { return (this.stuUniversity); } public Student clone() { Student cpStudent=null; try { cpStudent=(Student)super.clone(); } catch(CloneNotSupportedException e) { } return cpStudent; } } class MainClass { public static void main(String args[]) { Student stu1,stu2,stu3; stu1=new Student("张无忌","男",24,"软件工程","软件学院","中南大学"); //状态相似 //使用原型模式 stu2=stu1.clone(); stu2.setStuName("杨过"); //使用原型模式 stu3=stu1.clone(); stu3.setStuName("小龙女"); stu3.setStuSex("女"); System.out.print("姓名:" + stu1.getStuName()); System.out.print(",性别:" + stu1.getStuSex()); System.out.print(",年龄:" + stu1.getStuAge()); System.out.print(",专业:" + stu1.getStuMajor()); System.out.print(",学院:" + stu1.getStuCollege()); System.out.print(",学校:" + stu1.getStuUniversity()); System.out.println(); System.out.print("姓名:" + stu2.getStuName()); System.out.print(",性别:" + stu2.getStuSex()); System.out.print(",年龄:" + stu2.getStuAge()); System.out.print(",专业:" + stu2.getStuMajor()); System.out.print(",学院:" + stu2.getStuCollege()); System.out.print(",学校:" + stu2.getStuUniversity()); System.out.println(); System.out.print("姓名:" + stu3.getStuName()); System.out.print(",性别:" + stu3.getStuSex()); System.out.print(",年龄:" + stu3.getStuAge()); System.out.print(",专业:" + stu3.getStuMajor()); System.out.print(",学院:" + stu3.getStuCollege()); System.out.print(",学校:" + stu3.getStuUniversity()); System.out.println(); } }
java.lang.Object#clone()
(the class has to implement java.lang.Cloneable
)