设计模式(七)—原型模式
最后更新于:2022-04-01 16:26:07
**英文名称:Prototype Pattern**
**定义**:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
原型模式的核心就是一个clone方法,通过该方法进行对象的拷贝,java提供了一个Cloneable接口,来标示这个对象是可拷贝的。
**一个例子:**
一个银行,定时给不同的用户发送特定的邮件。
AdvTemplate类,advSubject(标题)advContext(内容)
Mail receiver(接收者),subject(名称),appellation(称谓),context(内容),tail(版本信息).
**![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-06-06_57553409923ab.jpg)**
~~~
public class PrototypeTest {
public static void main(String[] args) {
//将模板放入到Mail实例中,发送邮件。
Mail mail = new Mail(new AdvTemplate());
for(int i=0;i<10000;i++){
Mail cloneMail = (Mail) mail.clone();
cloneMail.setAppellation(getRandString(5)+"先生:您好!\n");
cloneMail.setReceiver(getRandString(5)+".com\n");
sendMail(mail);
}
}
//发送信息,并返回已发送成功的回执。
public static void sendMail(Mail mail){
System.out.println("标题:"+mail.getSubject()+"\t 内容:"+mail.getContext()+"\t"+"发送成功!\n");
}
//随机产生一些接收者和称谓信息。
public static String getRandString(int length){
String source = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
Random random = new Random();
StringBuffer sb = new StringBuffer();
while(length-- != 0){
sb.append(source.charAt(random.nextInt(source.length())));
}
return sb.toString();
}
}
class AdvTemplate{
private String advSubject="某银行元旦信用卡抽奖活动";
private String advContext="元旦抽奖活动,只要刷卡就送你一个大红包!";
public String getAdvSubject() {
return advSubject;
}
public String getAdvContext() {
return advContext;
}
}
class Mail implements Cloneable{
//收件人
private String receiver;
//名称
private String subject;
//称谓
private String appellation;
//内容
private String context;
//版本信息
private String tail;
public Mail(AdvTemplate advTemplate) {
this.subject = advTemplate.getAdvSubject();
this.context = advTemplate.getAdvContext();
}
public String getReceiver() {
return receiver;
}
public void setReceiver(String receiver) {
this.receiver = receiver;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getAppellation() {
return appellation;
}
public void setAppellation(String appellation) {
this.appellation = appellation;
}
public String getContext() {
return context;
}
public void setContext(String context) {
this.context = context;
}
public String getTail() {
return tail;
}
public void setTail(String tail) {
this.tail = tail;
}
//重写Object类中的clone方法。
@Override
protected Object clone(){
Mail mail = null;
try {
mail = (Mail) super.clone();
} catch (Exception e) {
e.printStackTrace();
}
return mail;
}
}
~~~
**原型模型优点:**
性能优良,---原型模型是在内存二进制流的拷贝,比直接new一个对象性能好很多,特别是在循环体内产生大量的对象时,原型模式可以更好的体现其优点。
逃避构造函数的约束,--直接从内存中拷贝,构造函数是不会执行的。
**原型模式的注意事项**
1、构造函数不会被执行。
2、浅拷贝和深拷贝
**浅拷贝**
--|Object类提供的方法clone只是拷贝本对象,其对象内部的数组、引用对象等都不拷贝,还是指向原声对象的内部元素地址,这种拷贝叫做浅拷贝。
**深拷贝**
--|两个对象之间没有任何瓜葛,你修改你的,我修改我的。互不影响,这种拷贝叫做深拷贝。
3、clone和final是冤家。
出现final的对象或变量,不能clone。
~~~
public class Prototype {
public static void main(String[] args) {
//创建一个对象
MyClone myClone = new MyClone();
myClone.setArrayList("lzl");
//将该对象clone。
MyClone clone2 = (MyClone) myClone.clone();
clone2.setArrayList("xy");
//输出原对象的结果。
System.out.println("原对象...."+myClone.getArrayList());
//输出拷贝后的结果。
System.out.println("拷贝结果...."+clone2.getArrayList());
}
}
class MyClone implements Cloneable{
private ArrayList<String> arrayList = new ArrayList<String>();
@SuppressWarnings("unchecked")
@Override
public MyClone clone(){
MyClone myClone =null;
try {
myClone = (MyClone) super.clone();
//把私有对象也进行拷贝。做到深拷贝的效果
myClone.arrayList = (ArrayList<String>) this.arrayList.clone();
} catch (Exception e) {
e.printStackTrace();
}
return myClone;
}
public ArrayList<String> getArrayList() {
return arrayList;
}
public void setArrayList(String name) {
this.arrayList.add(name);
}
}
~~~