欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java設(shè)計(jì)模式中的原型模式講解

 更新時(shí)間:2023年04月27日 08:37:19   作者:.番茄炒蛋  
原型模式是用于創(chuàng)建重復(fù)的對(duì)象,同時(shí)又能保證性能。這種類型的設(shè)計(jì)模式屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對(duì)象的最佳方式,今天通過本文給大家介紹下Java?原型設(shè)計(jì)模式,感興趣的朋友一起看看吧

介紹

原型模式

在Java中,原型模式是一種創(chuàng)建型設(shè)計(jì)模式,它允許通過復(fù)制一個(gè)現(xiàn)有對(duì)象來創(chuàng)建一個(gè)新對(duì)象,而不是通過創(chuàng)建新的對(duì)象來初始化一個(gè)對(duì)象,原型模式是一種基于克隆的設(shè)計(jì)模式,通過復(fù)制現(xiàn)有對(duì)象的數(shù)據(jù)來創(chuàng)建新的對(duì)象.

原型模式需要實(shí)現(xiàn)Cloneable接口并重寫Object類中的clone()方法,在重謝clone()方法時(shí),需要調(diào)用super.clone()方法來創(chuàng)建一個(gè)新的對(duì)象,并復(fù)制原始對(duì)象中的所有屬性.默認(rèn)情況下,Java中的Object類提供的clone()方法會(huì)執(zhí)行淺拷貝,如果原始對(duì)象中包含引用類型的成員變量,則需要進(jìn)行深拷貝操作,以確保新對(duì)象中所有成員變量都是獨(dú)立的.

深拷貝與淺拷貝

淺拷貝(Shallow Copy)會(huì)創(chuàng)建一個(gè)新的對(duì)象,該對(duì)象具有與原始對(duì)象相同的屬性值.但是,如果原始對(duì)象包含對(duì)其他對(duì)象的引用,則新對(duì)象也將包含對(duì)相同對(duì)象的引用.換句話說,新對(duì)象僅僅是原始對(duì)象的一個(gè)副本,而不是獨(dú)立的對(duì)象.

深拷貝(Deep Copy)則是創(chuàng)建一個(gè)新的對(duì)象,該對(duì)象具有與原始對(duì)象相同的屬性值,但是它會(huì)遞歸的復(fù)制對(duì)象圖中所有的對(duì)象,而不是只復(fù)制引用.換句話說,深拷貝會(huì)創(chuàng)建一個(gè)完全獨(dú)立的新對(duì)象,該對(duì)象與原始對(duì)象沒有任何關(guān)聯(lián).

區(qū)別:

  • 對(duì)于基本數(shù)據(jù)類型,淺拷貝和深拷貝沒有區(qū)別,因?yàn)榛緮?shù)據(jù)類型在內(nèi)存中儲(chǔ)存為值.但是對(duì)于引用類型,淺拷貝和深拷貝會(huì)有不同的行為.淺拷貝只復(fù)制對(duì)象本身以及其中的基本數(shù)據(jù)類型成員,而不會(huì)復(fù)制引用類型成員.因此,如果原始對(duì)象中包含引用類型成員,淺拷貝得到的對(duì)象中的引用類型成員與原始對(duì)象中的相同,即兩者指向同一塊內(nèi)存地址.而深拷貝則會(huì)遞歸的復(fù)制所有的引用類型成員,因此得到的對(duì)象中的引用類型成員與原始對(duì)象中的不同,即兩者指向不同的內(nèi)存地址.
  • 淺拷貝速度相對(duì)較快,因?yàn)樗粡?fù)制了對(duì)象本身以及其中的基本數(shù)據(jù)類型成員.而深拷貝速度相對(duì)較慢,因?yàn)樗枰f歸的復(fù)制所有引用類型成員.

應(yīng)用場(chǎng)景:

  • 淺拷貝通常用于快速創(chuàng)建對(duì)象副本,且原始對(duì)象中不包含引用類型成員的情況下,可以使用淺拷貝.比如,當(dāng)需要多個(gè)對(duì)象共享某些狀態(tài)時(shí),可以使用淺拷貝來快速創(chuàng)建副本
  • 深拷貝通常用于創(chuàng)建完全獨(dú)立的對(duì)象,且原始對(duì)象中包含引用類型成員的情況下,可以使用深拷貝

淺拷貝示例代碼

@Data
public class Person implements Cloneable{
    private String name;
    private int age;
    private Address address;
    public Person(String name, int age, Address address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
@Data
public class Address {
    private String city;
    private String street;
    public Address(String city, String street) {
        this.city = city;
        this.street = street;
    }
}

測(cè)試淺拷貝

package com.fanqiechaodan.prototype.copy.shollow;
import com.alibaba.fastjson.JSON;
/**
 * @Classname Demo
 * @Description 淺拷貝
 */
public class Demo {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person1 = new Person("張三", 18, new Address("上海", "南京路"));
        Person person2 = (Person) person1.clone();
        System.out.println(JSON.toJSONString(person1));
        System.out.println(JSON.toJSONString(person2));
        System.out.println("淺拷貝后:");
        person1.getAddress().setCity("南京");
        System.out.println(JSON.toJSONString(person1));
        System.out.println(JSON.toJSONString(person2));
    }
}

深拷貝示例代碼

@Data
public class Person implements Serializable {
    private String name;
    private int age;
    private Address address;
    public Person(String name, int age, Address address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }
    @Override
    protected Object clone() {
        try {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(this);
            ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bis);
            return ois.readObject();
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }
}
@Data
public class Address implements Serializable {
    private String city;
    private String street;
    public Address(String city, String street) {
        this.city = city;
        this.street = street;
    }
}

測(cè)試深拷貝

package com.fanqiechaodan.prototype.copy.deep;
import com.alibaba.fastjson.JSON;
import org.springframework.util.SerializationUtils;
import java.io.IOException;
/**
 * @Classname Demo
 * @Description 深拷貝
 */
public class Demo {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        Person person1 = new Person("張三", 18, new Address("上海", "南京路"));
        // 重寫clone完成深拷貝
        Person person2 = (Person) person1.clone();
        // 使用工具類完成深拷貝
        Person person3 = (Person) SerializationUtils.deserialize(SerializationUtils.serialize(person1));
        System.out.println(JSON.toJSONString(person1));
        System.out.println(JSON.toJSONString(person2));
        System.out.println(JSON.toJSONString(person3));
        System.out.println("深拷貝后:");
        person1.getAddress().setCity("南京");
        System.out.println(JSON.toJSONString(person1));
        System.out.println(JSON.toJSONString(person2));
        System.out.println(JSON.toJSONString(person3));
    }
}

原型模式代碼

原型類代碼

@Data
public class Person implements Cloneable{
    private String name;
    private int age;
    private Address address;
    public Person(String name, int age, Address address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
@Data
public class Address {
    private String city;
    private String street;
    public Address(String city, String street) {
        this.city = city;
        this.street = street;
    }
}

測(cè)試

package com.fanqiechaodan.prototype;
import com.alibaba.fastjson.JSON;
/**
 * @Classname Demo
 * @Description
 */
public class Demo {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person1 = new Person("張三", 18, new Address("北京", "青年路"));
        Person person2 = (Person) person1.clone();
        System.out.println(JSON.toJSONString(person1));
        System.out.println(JSON.toJSONString(person2));
    }
}

需要注意的是,在使用Cloneable接口實(shí)現(xiàn)原型模式時(shí),需要注意以下幾點(diǎn):

  • 要使用克隆方法,必須確保該對(duì)象實(shí)現(xiàn)了Cloneable接口.否則,在調(diào)用clone方法時(shí)會(huì)拋出CloneNotSupportedException異常
  • 調(diào)用clone方法返回的是一個(gè)淺拷貝對(duì)象,如果對(duì)象包含了引用類型的成員變量,那么這些成員變量依然會(huì)被多個(gè)對(duì)象共享.
  • 在實(shí)現(xiàn)clone方法時(shí),需要注意對(duì)成員變量的處理,特別是對(duì)引用類型的成員變量的處理.如果需要實(shí)現(xiàn)深拷貝,可以通過重寫clone方法來實(shí)現(xiàn).

總結(jié)

優(yōu)點(diǎn):

  • 減少了重復(fù)代碼的編寫,避免了創(chuàng)建大量相似對(duì)象的開銷,提高了系統(tǒng)的性能.
  • 可以動(dòng)態(tài)的創(chuàng)建對(duì)象,而不是靜態(tài)地在代碼中定義,更加靈活.
  • 簡(jiǎn)化了對(duì)象的創(chuàng)建過程,減少了不必要的參數(shù)傳遞.

缺點(diǎn):

  • 由于原型模式會(huì)復(fù)制對(duì)象,可能導(dǎo)致對(duì)象狀態(tài)的改變,因此需要謹(jǐn)慎處理.
  • 由于原型模式使用了克隆的方式創(chuàng)建對(duì)象,可能導(dǎo)致類的層次結(jié)構(gòu)比較復(fù)雜.

應(yīng)用場(chǎng)景:

  • 當(dāng)需要?jiǎng)?chuàng)建大量相似的對(duì)象時(shí),使用原型模式可以大大減少對(duì)象創(chuàng)建的開銷.
  • 當(dāng)對(duì)象的創(chuàng)建過程比較復(fù)雜,或者對(duì)象的狀態(tài)會(huì)隨著時(shí)間的推移而發(fā)生改變時(shí),可以考慮使用原型模式.
  • 當(dāng)需要?jiǎng)討B(tài)地創(chuàng)建對(duì)象時(shí),可以使用原型模式.例如:在運(yùn)行時(shí)動(dòng)態(tài)創(chuàng)建新對(duì)象或者在數(shù)據(jù)庫中讀取對(duì)象并創(chuàng)建新對(duì)象.

到此這篇關(guān)于Java設(shè)計(jì)模式中的原型模式講解的文章就介紹到這了,更多相關(guān)Java原型設(shè)計(jì)模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring注解驅(qū)動(dòng)之@EventListener注解使用方式

    Spring注解驅(qū)動(dòng)之@EventListener注解使用方式

    這篇文章主要介紹了Spring注解驅(qū)動(dòng)之@EventListener注解使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • Java實(shí)現(xiàn)excel動(dòng)態(tài)列導(dǎo)出的示例代碼

    Java實(shí)現(xiàn)excel動(dòng)態(tài)列導(dǎo)出的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何使用Java實(shí)現(xiàn)excel動(dòng)態(tài)列導(dǎo)出,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-03-03
  • Java?實(shí)戰(zhàn)范例之校園二手市場(chǎng)系統(tǒng)的實(shí)現(xiàn)

    Java?實(shí)戰(zhàn)范例之校園二手市場(chǎng)系統(tǒng)的實(shí)現(xiàn)

    讀萬卷書不如行萬里路,只學(xué)書上的理論是遠(yuǎn)遠(yuǎn)不夠的,只有在實(shí)戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用java+SSM+mysql+maven+tomcat實(shí)現(xiàn)一個(gè)校園二手市場(chǎng)系統(tǒng),大家可以在過程中查缺補(bǔ)漏,提升水平
    2021-11-11
  • java實(shí)現(xiàn)微信公眾號(hào)消息推送的方法詳解

    java實(shí)現(xiàn)微信公眾號(hào)消息推送的方法詳解

    這篇文章主要為大家詳細(xì)介紹了如何利用java實(shí)現(xiàn)微信公眾號(hào)消息推送的功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-10-10
  • drools中使用function的方法小結(jié)

    drools中使用function的方法小結(jié)

    當(dāng)我們?cè)赿rools中編寫規(guī)則時(shí),有些時(shí)候存在重復(fù)的代碼,那么我們是否可以將這些重復(fù)代碼抽取出來,封裝成一個(gè)function來調(diào)用呢?那么在drools中如何自定義function?下面小編給大家介紹下drools中使用function的方法,需要的朋友可以參考下
    2022-05-05
  • MybatisPlus實(shí)現(xiàn)邏輯刪除功能

    MybatisPlus實(shí)現(xiàn)邏輯刪除功能

    這篇文章主要介紹了MybatisPlus實(shí)現(xiàn)邏輯刪除功能,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • Java實(shí)現(xiàn)滑動(dòng)驗(yàn)證碼的示例代碼

    Java實(shí)現(xiàn)滑動(dòng)驗(yàn)證碼的示例代碼

    這篇文章主要介紹了Java實(shí)現(xiàn)滑動(dòng)驗(yàn)證碼的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-01-01
  • Java 將字符串動(dòng)態(tài)生成字節(jié)碼的實(shí)現(xiàn)方法

    Java 將字符串動(dòng)態(tài)生成字節(jié)碼的實(shí)現(xiàn)方法

    本篇文章主要是對(duì)Java將字符串動(dòng)態(tài)生成字節(jié)碼的實(shí)現(xiàn)方法進(jìn)行了介紹,需要的朋友可以過來參考下,希望對(duì)大家有所幫助
    2014-01-01
  • Java中Synchronized鎖的使用和原理詳解

    Java中Synchronized鎖的使用和原理詳解

    這篇文章主要介紹了Java中Synchronized鎖的使用和原理詳解,synchronized是?Java?內(nèi)置的關(guān)鍵字,它提供了一種獨(dú)占的加鎖方式,synchronized的獲取和釋放鎖由JVM實(shí)現(xiàn),用戶不需要顯示的釋放鎖,非常方便,需要的朋友可以參考下
    2023-07-07
  • java SSLContext創(chuàng)建方式

    java SSLContext創(chuàng)建方式

    這篇文章主要介紹了java SSLContext創(chuàng)建方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01

最新評(píng)論