【java_設計模式】原型模式、淺拷貝和深拷貝

【java_設計模式】原型模式、淺拷貝和深拷貝
應用場景
須要同一個類的多個不一樣對象完成業務操做,羣發email,須要多個Mail類的對象
好處:提升性能
[Java] 純文本查看 複製代碼
?java

public static void main(String[] args) throws CloneNotSupportedException {設計模式

Mail mail = new Mail();
   mail.setContent("初始化模板");
   for(int i=0; i<10; i++) {
        //建立10個Mail的對象進行發郵件的操做,使用原型模式加快性能
       Mail mailTemp = (Mail) mail.clone();
       mailTemp.setName("第" + i + "個克隆出來的對象");
       // 使用克隆採用的是二進制的拷貝,效率比直接new高不少
   }
   // 不改變原來的Mail
   MailUtil.saveOriginMailRecord(mail);

}ide

實現
[Java] 純文本查看 複製代碼
?性能

// 省略get set方法
public class Mail implements Cloneable{.net

private String name;
private String address;
private String content;
public Mail() {
    System.out.println("Mail Class Constructor");
}

/**
 * 記得重寫方法
 * @return
 * @throws CloneNotSupportedException
 */
@Override
protected Object clone() throws CloneNotSupportedException {
    return super.clone();
}

@Override
public String toString() {
    return "Mail{" +
            "name='" + name + '\'' +
            ", address='" + address + '\'' +
            ", content='" + content + '\'' +
            '}';
}

}設計

[Java] 純文本查看 複製代碼
?code

public class MailUtil {orm

public static void sendMail(Mail mail) {
    String outputContent = "向{0}同窗,郵件地址{1},郵件內容:{2},發送成功";
    System.out.println(MessageFormat.format(outputContent, mail.getName(),mail.getAddress(),mail.getContent()));
}

public static void saveOriginMailRecord(Mail mail) {
  System.out.println("存儲originMail記錄,originMail:" + mail.getContent());
}

}對象

原理blog

原型模式的本質是類繼承Clonable接口,重寫clone方法。clone的底層是使用二進制拷貝,須要多個對象的時候能夠用該方法取代屢次new,提升性能。

修改原對象的成員變量,可能會同時修改克隆出來的對象。避免這種坑即便用深拷貝。
不重寫clone方法,默認使用淺拷貝

[Java] 純文本查看 複製代碼
?

public class Pig implements Cloneable{

private String name;
// 引用對象
private Date birthday;
 
// 默認的clone方法,不會修改引用對象的指向,即拷貝出來的對象中birthday引用指向的是同一塊內存區域
@Override
protected Object clone() throws CloneNotSupportedException {
    Pig pig = (Pig)super.clone();

    // 深拷貝,有引用對象的時候須要重寫clone()方法
    pig.birthday = (Date)pig.birthday.clone();
    return pig;
}

}

拓展
原型模式和單例模式結合的時候,注意修改clone方法
1.極端場景

[Java] 純文本查看 複製代碼
?

<font style="color:rgb(79, 79, 79)"><font face="&quot"><font style="font-size:16px">// step 2克隆破壞單例

HungrySingleton hungrySingleton = HungrySingleton.getInstance();
    Method method = hungrySingleton.getClass().getDeclaredMethod("clone");
    method.setAccessible(true);
    HungrySingleton cloneHungrySingleton = (HungrySingleton) method.invoke(hungrySingleton);
    System.out.println(hungrySingleton);
    System.out.println(cloneHungrySingleton);

</font></font></font>
2.關鍵代碼

[Java] 純文本查看 複製代碼
?

<font style="color:rgb(79, 79, 79)"><font face="&quot"><font style="font-size:16px"> /**

* 單例模式下使用的clone方法, 防止克隆破壞就要修改方法實現
 * @return
 * @throws CloneNotSupportedException
 */
@Override
protected Object clone() throws CloneNotSupportedException {
    return getInstance();
}</font></font></font>

做者:Ch.yang
來源:CSDN
原文:https://blog.csdn.net/chengha... 版權聲明:本文爲博主原創文章,轉載請附上博文連接!

相關文章
相關標籤/搜索