原型(Prototype)模式的定义:用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象。在这里,原型实例指定了要创建的对象的种类。用这种方式创建对象非常高效,根本无须知道对象创建的细节。(对象创建型)
原型模式包含三个角色:
我们会发现其实原型模式的核心就是Prototype(抽象原型),他需要继承Cloneable接口,并且重写Object类中的clone方法才能有复制粘贴的功能。
- package prototype.demo;
- //抽象原型角色
- public interface Prototype {
- public Prototype clone();
- }
- package prototype.demo;
- //具体原型角色
- public class ConcretePrototype implements Prototype{
- private int dataInt=1;
- private A dataA=new A();
- public String toString() {
- return "ConcretePrototype"+"["+",dataInt"+dataInt
- +",dataA_address="+dataA
- +",dataA="+dataA.getChar_a()+
- "]";
- }
- public int getDataInt() {
- return dataInt;
- }
- public void setDataInt(int dataInt) {
- this.dataInt = dataInt;
- }
- public A getDataA() {
- return dataA;
- }
- public void setDataA(A dataA) {
- this.dataA = dataA;
- }
- //克隆方法 shallow
- public Prototype clone() {
- ConcretePrototype copy=new ConcretePrototype();
- copy.setDataInt(this.getDataInt());
- copy.setDataA(this.getDataA());
- return copy;
- }
- //克隆方法 deep
- public Prototype clone2() {
- ConcretePrototype copy=new ConcretePrototype();
- copy.setDataInt(this.getDataInt());
- A ta=new A();
- ta.setChar_a(this.getDataA().getChar_a());
- copy.setDataA(this.getDataA());
- return copy;
- }
-
- }
- package prototype.demo;
- //封装的方法
- public class A {
- char char_a;
-
- public char getChar_a() {
- return char_a;
- }
-
- public void setChar_a(char char_a) {
- this.char_a = char_a;
- }
- public A(char char_a) {
- super();
- this.char_a=char_a;
- }
- public A() {
- this.char_a='a';
- }
- }
- package prototype.demo;
-
- public class Client {
-
- public static void main(String[] args) {
- // TODO 自动生成的方法存根
- /*ConcretePrototype p=new ConcretePrototype();
- ConcretePrototype copy=(ConcretePrototype) p.clone();
- ConcretePrototype copy2=(ConcretePrototype) p.clone();
- System.out.println(p.toString());
- System.out.println(copy.toString());
- System.out.println(copy2.toString());
-
- copy.setDataInt(2);
- A a=new A('b');
- copy.setDataA(a);
- System.out.println("-------------------------------");
- System.out.println(p.toString());
- System.out.println(copy.toString());
- System.out.println(copy2.toString());*/
- ConcretePrototype p=new ConcretePrototype();
- ConcretePrototype copy=(ConcretePrototype) p.clone2();
- ConcretePrototype copy2=(ConcretePrototype) p.clone2();
- System.out.println(p.toString());
- System.out.println(copy.toString());
- System.out.println(copy2.toString());
-
- copy.setDataInt(2);
- A a=new A('b');
- copy.setDataA(a);
- System.out.println("-------------------------------");
- System.out.println(p.toString());
- System.out.println(copy.toString());
- System.out.println(copy2.toString());
- }
-
- }
java.io.Serializable这个接口。
- package prototype.deepclone;
-
- import java.io.Serializable;
- //实现了Serializable这个接口
- public class Attachment implements Serializable{
- private String name;
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
- public void download() {
- System.out.println("下载附件,文件名为:"+name);
- }
- }
- package prototype.shallowclone;
-
- public class WeeklyLog implements Cloneable{
- //简化设计,定义一个附件
- private Attachment attachment;
- private String name;
- private String date;
- private String content;
- public Attachment getAttachment() {
- return attachment;
- }
- public void setAttachment(Attachment attachment) {
- this.attachment = attachment;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public String getDate() {
- return date;
- }
- public void setDate(String date) {
- this.date = date;
- }
- public String getContent() {
- return content;
- }
- public void setContent(String content) {
- this.content = content;
- }
- //使用clone()方法实现浅克隆
- @Override
- protected WeeklyLog clone(){
- // TODO 自动生成的方法存根
- try {
- return (WeeklyLog)super.clone();
- } catch (CloneNotSupportedException e) {
- // TODO 自动生成的 catch 块
- e.printStackTrace();
- return null;
- }
- }
-
- }
- package prototype.shallowclone;
-
- public class Client {
-
- public static void main(String[] args) {
- // TODO 自动生成的方法存根
- WeeklyLog obj=new WeeklyLog();
- Attachment att=new Attachment();
- att.setName("obj");
- obj.setAttachment(att);
-
- WeeklyLog copy=obj.clone();
- obj.getAttachment().download();
- copy.getAttachment().download();
- }
-
- }
java.io.Serializable这个接口。
- package prototype.deepclone;
-
- import java.io.Serializable;
- //实现了Serializable这个接口
- public class Attachment implements Serializable{
- private String name;
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
- public void download() {
- System.out.println("下载附件,文件名为:"+name);
- }
- }
- package prototype.deepclone;
-
- import java.io.*;
-
- public class WeeklyLog implements Serializable{
- //简化设计,定义一个附件
- private Attachment attachment;
- private String name;
- private String date;
- private String content;
- public Attachment getAttachment() {
- return attachment;
- }
- public void setAttachment(Attachment attachment) {
- this.attachment = attachment;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public String getDate() {
- return date;
- }
- public void setDate(String date) {
- this.date = date;
- }
- public String getContent() {
- return content;
- }
- public void setContent(String content) {
- this.content = content;
- }
- //使用序列化技术实现克隆
- protected WeeklyLog deepClone() throws IOException,ClassNotFoundException{
- // TODO 自动生成的方法存根
- //将对象写入流中
- ByteArrayOutputStream bao=new ByteArrayOutputStream();
- ObjectOutputStream oos=new ObjectOutputStream(bao);
- oos.writeObject(this);
- //将对象从流中取出
- ByteArrayInputStream bis=new ByteArrayInputStream(bao.toByteArray());
- ObjectInputStream ois=new ObjectInputStream(bis);
- return (WeeklyLog)ois.readObject();
- }
-
- }
- package prototype.deepclone;
-
- public class Client {
-
- public static void main(String[] args) {
- // TODO 自动生成的方法存根
- WeeklyLog log_previous,log_new=null;
- log_previous=new WeeklyLog();//创建原型对象
- Attachment attachment=new Attachment();//创建附件对象
- attachment.setName("aaa");
- log_previous.setAttachment(attachment);//将附件添加到周报中
- try {
- log_new=log_previous.deepClone();//调用深克隆方法
- }catch(Exception e) {
- System.out.println("克隆失败!");
- }
- //比较周报
- System.out.println("周报是否相同?"+(log_previous==log_new));
- //比较附件
- System.out.println("附件是否相同?"+(log_previous.getAttachment()==log_new.getAttachment()));
- log_previous.getAttachment().download();
- log_new.getAttachment().download();
- }
-
- }