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

Java設(shè)計(jì)模式之原型模式詳細(xì)解讀

 更新時(shí)間:2023年12月31日 09:12:41   作者:理想萬(wàn)歲萬(wàn)萬(wàn)歲  
這篇文章主要介紹了Java設(shè)計(jì)模式之原型模式詳細(xì)解讀,原型模式屬于創(chuàng)建型設(shè)計(jì)模式,用于創(chuàng)建重復(fù)的對(duì)象,且同時(shí)又保證了性能,該設(shè)計(jì)模式的好處是將對(duì)象的創(chuàng)建與調(diào)用方分離,需要的朋友可以參考下

一、介紹

原型模式屬于創(chuàng)建型設(shè)計(jì)模式,用于創(chuàng)建重復(fù)的對(duì)象,且同時(shí)又保證了性能。

該設(shè)計(jì)模式的好處是將對(duì)象的創(chuàng)建與調(diào)用方分離。

其目的就是**根據(jù)一個(gè)對(duì)象(稱為原型)創(chuàng)建一個(gè)與其完全相同的對(duì)象(當(dāng)然內(nèi)存地址不同)。**原對(duì)象被認(rèn)為是新對(duì)象的原型。

二、實(shí)現(xiàn)步驟

原型模式的實(shí)現(xiàn)步驟如下:

  • 應(yīng)用原型模式的類要實(shí)現(xiàn)Cloneable接口。
  • 應(yīng)用原型模式的類要重寫Object類定義的clone()方法。
  • 通過調(diào)用對(duì)象的clone()方法,獲得一個(gè)與該對(duì)象相同的對(duì)象。

在重寫Object類定義的clone()方法時(shí),直接通過調(diào)用super.clone()即可得到一個(gè)新對(duì)象,如下所示

@Override
public Object clone() {
    try {
        Object obj = super.clone();
        return obj;
    } catch (CloneNotSupportedException e) {
        throw new AssertionError();
    }
}

而super.clone()調(diào)用的其實(shí)就是在Object類中定義的方法

public class Object {
    // ...
    protected native Object clone() throws CloneNotSupportedException;
    // ...
}

該方法由native關(guān)鍵字修飾,表明其具體實(shí)現(xiàn)邏輯在JVM中已經(jīng)完成了,我們無需知道其細(xì)節(jié),只需知道調(diào)用該方法后將返回一個(gè)具有相同屬性的對(duì)象即可。也正因此,該方式要比我們創(chuàng)建實(shí)例再初始化實(shí)例的性能好。

另外,該方法顯式地拋出了CloneNotSupportedException異常,要求我們?cè)谡{(diào)用clone()方法的對(duì)象必須實(shí)現(xiàn)Cloneable接口,否則將拋出該異常。

注意:調(diào)用super.clone()時(shí),只能夠滿足淺拷貝,如果要實(shí)現(xiàn)深拷貝,則需要我們根據(jù)實(shí)際情況重寫clone()的具體邏輯而不是調(diào)用super.clone()。

三、案例

我們創(chuàng)建一個(gè)Person類,實(shí)現(xiàn)Cloneable接口,并重寫clone()方法。

public class Person implements Cloneable{
    private String name;
    private Integer age;
    private String sex;
    // 省略get、set方法
    @Override
    public Person clone() {
        try {
            Person person = (Person) super.clone();
            return person;
        } catch (CloneNotSupportedException e) {
            throw new AssertionError();
        }
    }
}

然后進(jìn)行測(cè)試

public class PrototypeTest {
    public static void main(String[] args) {
        Person person = new Person();
        person.setName("name");
        person.setAge(1);
        person.setSex("男");
        Person clone = person.clone();
        System.out.println("獲得的新對(duì)象:" + clone);
    }
}

得到的輸出如下,可以發(fā)現(xiàn),通過clone()方法可以獲得一個(gè)與原對(duì)象具有相同屬性的新對(duì)象。

在這里插入圖片描述

四、應(yīng)用

原型模式在實(shí)際應(yīng)用中不是很廣泛,因?yàn)榻^大多數(shù)實(shí)例要么是有狀態(tài)的(例如持有文件、遠(yuǎn)程鏈接等),則無法應(yīng)用原型模式;要么是無狀態(tài)的,此時(shí)應(yīng)用單例模式更合適。

思來想去,基于原型模式創(chuàng)建重復(fù)對(duì)象的作用,我們可以利用該模式模擬細(xì)胞分裂。

五、細(xì)胞分裂

按照上面案例,我們新建一個(gè)細(xì)胞類Cell

public class Cell implements Cloneable{
    // 當(dāng)前細(xì)胞為第num次分裂所得,細(xì)胞分裂是一個(gè)1變2,2變4,4變8的過程,
    private Integer num = 0;
    @Override
    public Cell clone() {
        try {
            // 每當(dāng)克隆一次,num+1
            num++;
            Cell clone = (Cell) super.clone();
            return clone;
        } catch (CloneNotSupportedException e) {
            throw new AssertionError();
        }
    }
}

演示細(xì)胞分裂過程

public static void cellDivision() {
    // 第一個(gè)細(xì)胞
    Cell cell1 = new Cell();
    System.out.println("cell1:" + cell1);
    // cell1 通過自我復(fù)制, 產(chǎn)生一個(gè)新細(xì)胞 cell2
    Cell cell2 = cell1.clone();
    System.out.println("第一次分裂后:");
    System.out.println("cell1:" + cell1);
    System.out.println("cell2:" + cell2);
    // cell1、cell2 通過自我復(fù)制, 產(chǎn)生新細(xì)胞 cell3、cell4
    Cell cell3 = cell1.clone();
    Cell cell4 = cell2.clone();
    System.out.println("第二次分裂后:");
    System.out.println("cell1:" + cell1);
    System.out.println("cell2:" + cell2);
    System.out.println("cell3:" + cell3);
    System.out.println("cell4:" + cell4);
}

輸出如下:

在這里插入圖片描述

此時(shí)如果要計(jì)算當(dāng)前一共有多少個(gè)細(xì)胞,就可以通過 2 n u m 2^{num} 2num得到結(jié)果。

六、改造細(xì)胞分裂邏輯

我們將N個(gè)細(xì)胞(無論分裂多少次)作為一個(gè)整體,假設(shè)該整體中所有細(xì)胞同時(shí)分裂,則可以將該細(xì)胞整體進(jìn)行抽象。如下所示,新建一個(gè)細(xì)胞整體類Cells。

  • 實(shí)現(xiàn)Cloneable接口,表示該細(xì)胞整體可進(jìn)行復(fù)制分裂。
  • 重寫clone()方法,該細(xì)胞整體分裂的過程,其實(shí)就是所有個(gè)體在分裂,最后將其整合即可
public class Cells implements Cloneable{
	// 該細(xì)胞整體中的所有細(xì)胞個(gè)體
    private List<Cell> cellList = new ArrayList<>();
    // 添加一個(gè)細(xì)胞
    public void addCell(Cell cell) {
        cellList.add(cell);
    }
    // 該細(xì)胞整體復(fù)制分裂的過程
    @Override
    public Cells clone() {
        try {
            System.out.println("第" + (cellList.get(0).getNum()+1) + "次分裂...");
            // 新增的細(xì)胞數(shù)量和原細(xì)胞數(shù)量相同
            List<Cell> clonedCellList = new ArrayList<>(cellList.size());
            for (Cell cell : cellList) {
                // 將每一個(gè)細(xì)胞分裂得到的新細(xì)胞添加到clonedCellList集合中
                clonedCellList.add(cell.clone());
            }
            // 新細(xì)胞與原細(xì)胞合并
            cellList.addAll(clonedCellList);
            // 復(fù)制該細(xì)胞整體
            Cells clone = (Cells) super.clone();
            clone.setCellList(cellList);
            System.out.println("分裂后得到細(xì)胞數(shù):" + cellList.size());
            return clone;
        } catch (CloneNotSupportedException e) {
            throw new AssertionError();
        }
    }
}

下面我們對(duì)該細(xì)胞整體的分裂過程進(jìn)行演示

public static void cellDivision() {
    // 第一個(gè)細(xì)胞
    Cell cell = new Cell();
	// 向該細(xì)胞整體中添加第一個(gè)細(xì)胞
    Cells cells = new Cells();
    cells.addCell(cell);
    // 細(xì)胞分裂10次
    for (int i = 0; i < 10; i++) {
        cells = cells.clone();
    }
}

輸出如下:

在這里插入圖片描述

七、總結(jié)

  • 原型模式用于創(chuàng)建具有相同屬性的重復(fù)對(duì)象。
  • 原型模式的實(shí)現(xiàn)就是實(shí)現(xiàn)Cloneable接口 + 重寫clone()方法實(shí)現(xiàn)的。
  • Object類的clone()方法實(shí)現(xiàn)由JVM實(shí)現(xiàn),性能較好。但僅能實(shí)現(xiàn)淺拷貝。

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

相關(guān)文章

  • 淺談Java的SPI技術(shù)

    淺談Java的SPI技術(shù)

    這篇文章主要介紹了Java的SPI技術(shù)的相關(guān)資料,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-07-07
  • 很詳細(xì)的Log4j配置步驟

    很詳細(xì)的Log4j配置步驟

    Log4J的配置文件(Configuration File)就是用來設(shè)置記錄器的級(jí)別、存放器和布局的,它可接key=value格式的設(shè)置或xml格式的設(shè)置信息。通過配置,可以創(chuàng)建出Log4J的運(yùn)行環(huán)境。
    2008-11-11
  • 如何用java計(jì)算兩個(gè)時(shí)間相差多少小時(shí)

    如何用java計(jì)算兩個(gè)時(shí)間相差多少小時(shí)

    最近工作中遇到需要計(jì)算時(shí)間差,下面這篇文章主要給大家介紹了關(guān)于如何用java計(jì)算兩個(gè)時(shí)間相差多少小時(shí)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-12-12
  • 基于java構(gòu)造方法Vector遍歷元素源碼分析

    基于java構(gòu)造方法Vector遍歷元素源碼分析

    本篇文章是關(guān)于ava構(gòu)造方法Vector源碼分析系列文章,本文主要介紹了Vector遍歷元素的源碼分析,有需要的朋友可以借鑒參考下,希望可以有所幫助
    2021-09-09
  • Java常用時(shí)間工具類總結(jié)(珍藏版)

    Java常用時(shí)間工具類總結(jié)(珍藏版)

    這篇文章主要為大家詳細(xì)介紹了Java中一些常用時(shí)間工具類的使用示例代碼,文中的代碼簡(jiǎn)潔易懂,對(duì)我們學(xué)習(xí)Java有一定幫助,需要的可以參考一下
    2022-07-07
  • 最最常用的 100 個(gè) Java類分享

    最最常用的 100 個(gè) Java類分享

    這篇文章主要介紹了最最常用的 100 個(gè) Java類分享,需要的朋友可以參考下
    2015-04-04
  • JDK源碼之PriorityQueue解析

    JDK源碼之PriorityQueue解析

    這篇文章主要為大家詳細(xì)介紹了JDK源碼之PriorityQueue,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • SpringBoot?Web開發(fā)之請(qǐng)求響應(yīng)、分層解耦問題記錄

    SpringBoot?Web開發(fā)之請(qǐng)求響應(yīng)、分層解耦問題記錄

    在?Spring?Boot?的?Web?請(qǐng)求響應(yīng)處理中,Servlet?起著關(guān)鍵的作用,Servlet?是?Java?Web?開發(fā)中的基本組件,主要負(fù)責(zé)處理客戶端的請(qǐng)求并生成響應(yīng),這篇文章主要介紹了SpringBoot?Web開發(fā)之請(qǐng)求響應(yīng),分層解耦,需要的朋友可以參考下
    2024-08-08
  • Spring 日志規(guī)范及作用

    Spring 日志規(guī)范及作用

    日志是在系統(tǒng)運(yùn)行過程中關(guān)鍵的節(jié)點(diǎn)的數(shù),這個(gè)些日志的記錄方便當(dāng)系統(tǒng)出現(xiàn)問題方便問題查找,這篇文章主要介紹了Spring 日志規(guī)范及作用,需要的朋友可以參考下
    2024-03-03
  • SpringBoot使用外置的Servlet容器的方法步驟

    SpringBoot使用外置的Servlet容器的方法步驟

    SpringBoot 是一個(gè)非常流行的 Java 開發(fā)框架,它提供了一個(gè)簡(jiǎn)單而強(qiáng)大的方式來創(chuàng)建基于 Servlet 容器的 Web 應(yīng)用程序,本文將介紹 SpringBoot 中如何使用 Servlet 容器,需要的朋友可以參考下
    2024-12-12

最新評(píng)論