一、定义
主要作用:主要用来对象的复制。通过第一次new的实例化的对象进行克隆,之后需要实例化对象时,直接克隆实例化对象变行。
二、UML图
三、原型模式的用法和注意点
1)用法
原型模式的核心类(接口)是:Prototype类(接口),在Java中Prototype需要具备以下的条件:
1、实现Cloneable接口,Java中的Cloneable是一个标志性接口,接口中不存在任何的方法。目的是为了告诉Jvm,实现了这个接口就可以被克隆,否则在运行的时候回抛出CloneNotSupportedException异常。
2、clone方法的作用是对象的拷贝,重写Object类的clone()方法,原因是因为Object类中的clone()方法是protected访问权限。有些类无法进行访问,将其改为public访问权限变行。
2)注意点
1、clone()方法具有两种拷贝,一种是浅拷贝,一种是深拷贝。浅拷贝,拷贝的只是对象中的基本数据类型和其包装类还有String。想要深拷贝,必须要将对象中的数组,容器,对象进行另外拷贝。
2、原型模式复制对象不会调用类的构造方法,但是你进行new初始化一定是通过构造方法的。为什么原型模型复制对象不会调用类的构造方法呢?因为对象的复制通过Object类中clone方法进行,clone方法是直接在内存中进行复制数据,因此不会调用到类的构造方法。因此clone方法也会直接无视构造方法的访问权限,也因此和单例模式是有冲突的。
四、实例
创建个人简历
简历的接口:
package com.golf.Prototype; public interface Resume { public void show(); }
具体简历的实现(浅拷贝):
package com.golf.Prototype; import java.util.ArrayList; public class PersonResume implements Cloneable,Resume { private String name; private String age; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } @Override public Object clone() { PersonResume personResume=null; try { personResume = (PersonResume) super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return personResume; } @Override public void show() { System.out.println(name+age); } }
具体简历的实现(深拷贝):
package com.golf.Prototype; import java.util.ArrayList; public class PersonResume2 implements Cloneable,Resume{ private String name; private String age; private ArrayList arrayList; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } @Override public Object clone() { PersonResume2 personResume2=null; personResume2 = (PersonResume2) super.clone(); //拷贝基本数据类型和String personResume2.arrayList = (ArrayList) this.arrayList.clone();//拷贝对象 return personResume2; } @Override public void show() { System.out.println(name+age); } }
客户端:
package com.golf.Prototype; public class Client { public static void main(String[] args) { PersonResume personResume = new PersonResume(); personResume.setName("白"); personResume.setAge("23"); personResume.show(); PersonResume personResume1 = (PersonResume) personResume.clone(); personResume1.setName("黑"); personResume1.setAge("32"); personResume1.show(); } }
五、原型模式的优缺点