最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一文帶你了解Java創(chuàng)建型設(shè)計(jì)模式之原型模式

 更新時(shí)間:2022年09月23日 09:55:29   作者:丨Jack_Chen丨  
原型模式其實(shí)就是從一個(gè)對象在創(chuàng)建另外一個(gè)可定制的對象,不需要知道任何創(chuàng)建的細(xì)節(jié)。本文就來通過示例為大家詳細(xì)聊聊原型模式,需要的可以參考一下

原型模式

概述

原型模式(Prototype Pattern)是屬于創(chuàng)建型模式。

它指用原型實(shí)例指定創(chuàng)建對象的種類,并且通過拷貝這些原型創(chuàng)建新的對象。

原型模式的核心在于拷貝原型對象。以存在的一個(gè)對象為原型,直接基于內(nèi)存二進(jìn)制流進(jìn)行拷貝,無需再經(jīng)歷耗時(shí)的對象初始化過程(不調(diào)用構(gòu)造函數(shù)),性能提升許多。

當(dāng)直接創(chuàng)建對象的代價(jià)比較大時(shí),則采用這種模式。利用當(dāng)前系統(tǒng)中已存在的對象作為原型,對其進(jìn)行克隆,避免初始化的過程。

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

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

1.java自帶的原型模式是基于內(nèi)存二進(jìn)制流的拷貝,比直接new一個(gè)對象性能上提升許多

2.使用原型模式將對象復(fù)制一份并將其狀態(tài)保存起來,簡化創(chuàng)建對象的過程,以便在需要的時(shí)候使用

缺點(diǎn):

1.需要為每一個(gè)類配置一個(gè)克隆方法

2克隆方法位于類的內(nèi)部,當(dāng)對已有類進(jìn)行改造的時(shí)候,需要修改代碼,違反開閉原測

3.在實(shí)現(xiàn)深克隆時(shí)需要編寫較為復(fù)雜的代碼,而且當(dāng)對象之間存在多重嵌套引用時(shí),為了實(shí)現(xiàn)深克隆,每一層對象對應(yīng)的類都必須支特深克隆,實(shí)現(xiàn)比較麻煩

應(yīng)用場景

1.類初始化消耗資源較多

2.new產(chǎn)生的一個(gè)對象需要非常繁瑣的過程(數(shù)據(jù)準(zhǔn)備或訪問權(quán)限)

3.構(gòu)造函數(shù)處比較復(fù)雜

4.循環(huán)體中生產(chǎn)大量對象時(shí)

5.資源優(yōu)化場景

6.性能和安全要求的場景

主要角色

1.客戶(Client)角色

客戶端類向原型管理器提出創(chuàng)建對象的請求。

2.抽象原型(Prototype)角色

這是一個(gè)抽象角色,此角色給出所有的具體原型類所需的接口。

3.具體原型(Concrete Prototype)角色

被復(fù)制的對象。此角色需要實(shí)現(xiàn)抽象的原型角色所要求的接口。

4.原型管理器(Prototype Manager)角色

創(chuàng)建具體原型類的對象,并記錄每一個(gè)被創(chuàng)建的對象。

原型模式的基本使用

創(chuàng)建原型接口

public interface IPrototype<T> {
    T clone();
}

創(chuàng)建具體需要克隆對象

@Data
@ToString
public class ConcretePrototype implements IPrototype {
    private int age;
    private String name;
    @Override
    public ConcretePrototype clone() {
        ConcretePrototype concretePrototype = new ConcretePrototype();
        concretePrototype.setAge(this.age);
        concretePrototype.setName(this.name);
        return concretePrototype;
    }
}

使用

    public static void main(String[] args) {
        //創(chuàng)建原型對象
        ConcretePrototype prototype = new ConcretePrototype();
        prototype.setAge(20);
        prototype.setName("jack");
        System.out.println(prototype);
        //拷貝原型對象
        ConcretePrototype cloneType = prototype.clone();
        System.out.println(cloneType);
    }

JDK自帶原型接口的使用

原型模式就是如此簡單,通常開發(fā)中不會這樣使用。其實(shí)JDK提供了一個(gè)現(xiàn)成的API接口,那就是Cloneable接口。

@Data
@ToString
public class ConcretePrototype implements Cloneable {
    private int age;
    private String name;
    private List<String> hobbies;
    @Override
    public ConcretePrototype clone() {
        try {
            return (ConcretePrototype)super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
            return null;
        }
    }
}

淺克隆與深度克隆

淺克隆

添加一個(gè)hobby屬性,當(dāng)給克隆對象的hobby屬性添加一項(xiàng)時(shí),最終結(jié)果會導(dǎo)致原型對象發(fā)生變化,也就是hobby屬性用于一個(gè)內(nèi)存地址。這就是淺克隆。

@Data
@ToString
public class ConcretePrototype implements Cloneable {
    private int age;
    private String name;
    private List<String> hobby;
    @Override
    public ConcretePrototype clone() {
        try {
            return (ConcretePrototype)super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
            return null;
        }
    }
}
    public static void main(String[] args) {
        ConcretePrototype prototype = new ConcretePrototype();
        prototype.setAge(22);
        prototype.setName("jack");
        List<String> hobby = new ArrayList<String>();
        hobby.add("java");
        hobby.add("python");
        hobby.add("go");
        prototype.setHobby(hobby);
        // 拷貝原型對象
        ConcretePrototype cloneType = prototype.clone();
        cloneType.getHobby().add("php");
        System.out.println("原型對象:" + prototype);
        System.out.println("克隆對象:" + cloneType);
        System.out.println(prototype == cloneType);
        System.out.println(prototype.getHobby() == cloneType.getHobby());
    }

原型對象:ConcretePrototype(age=22, name=jack, hobby=[java, python, go, php])
克隆對象:ConcretePrototype(age=22, name=jack, hobby=[java, python, go, php])
false
true

深度克隆

可使用序列化方式實(shí)現(xiàn)對象的深度克隆

@Data
@ToString
public class ConcretePrototype implements Cloneable, Serializable {
    private int age;
    private String name;
    private List<String> hobby;
    @Override
    public ConcretePrototype clone() {
        try {
            return (ConcretePrototype) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
            return null;
        }
    }
    public ConcretePrototype deepClone() {
        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 (ConcretePrototype) ois.readObject();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}
    public static void main(String[] args) {
        //創(chuàng)建原型對象
        ConcretePrototype prototype = new ConcretePrototype();
        prototype.setAge(22);
        prototype.setName("jack");
        List<String> hobby = new ArrayList<String>();
        hobby.add("java");
        hobby.add("python");
        hobby.add("go");
        prototype.setHobby(hobby);
        // 拷貝原型對象
        ConcretePrototype cloneType = prototype.deepClone();
        cloneType.getHobby().add("php");
        System.out.println("原型對象:" + prototype);
        System.out.println("克隆對象:" + cloneType);
        System.out.println(prototype == cloneType);
        System.out.println(prototype.getHobby() == cloneType.getHobby());
    }

原型對象:ConcretePrototype(age=22, name=jack, hobby=[java, python, go])
克隆對象:ConcretePrototype(age=22, name=jack, hobby=[java, python, go, php])
false
false

也可這樣操作,多克隆一次

    public ConcretePrototype deepClone2() {
        try {
            ConcretePrototype result = (ConcretePrototype) super.clone();
            result.hobby = (List) ((ArrayList) result.hobby).clone();
            return result;
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
            return null;
        }
    }

單例的破壞

如果克隆的目標(biāo)對象是單例對象,深克隆就會破壞單例。

解決方案:禁止深克隆。

1.讓單例類不實(shí)現(xiàn)Cloneable接口

2.重寫clone方法,在clone方法中返回單例對象即可

@Data
@ToString
public class ConcretePrototype implements Cloneable {
    private static  ConcretePrototype instance = new ConcretePrototype();
    private ConcretePrototype(){}
    public static ConcretePrototype getInstance(){
        return instance;
    }
    @Override
    public ConcretePrototype clone() {
       return instance;
    }
}

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

相關(guān)文章

  • 解決java-jar報(bào)錯(cuò):xxx.jar 中沒有主清單屬性的方法

    解決java-jar報(bào)錯(cuò):xxx.jar 中沒有主清單屬性的方法

    在使用 java -jar xxx.jar 命令運(yùn)行 Java 應(yīng)用程序時(shí),遇到了以下錯(cuò)誤:xxx.jar 中沒有主清單屬性,這個(gè)錯(cuò)誤表示 JAR 文件缺少必要的啟動(dòng)信息,本文將介紹該錯(cuò)誤的原因以及如何通過修改 pom.xml 文件來解決,需要的朋友可以參考下
    2024-11-11
  • 配置Ant執(zhí)行Jmeter腳本過程詳解

    配置Ant執(zhí)行Jmeter腳本過程詳解

    這篇文章主要介紹了配置Ant執(zhí)行Jmeter腳本過程詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09
  • Java lastIndexOf類使用方法原理解析

    Java lastIndexOf類使用方法原理解析

    這篇文章主要介紹了Java lastIndexOf類使用方法解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-07-07
  • 關(guān)于@MapperScan和@ComponentScan的使用問題

    關(guān)于@MapperScan和@ComponentScan的使用問題

    文章介紹了在使用`@MapperScan`和`@ComponentScan`時(shí)可能會遇到的包掃描沖突問題,并提供了解決方法,同時(shí),還詳細(xì)解釋了`@MapperScan`和`@ComponentScan`的功能和使用場景
    2025-01-01
  • 8種常見的接口請求重試方法總結(jié)

    8種常見的接口請求重試方法總結(jié)

    在跨境業(yè)務(wù)中,可能第三方的服務(wù)器分布在世界的各個(gè)角落,所以請求三方接口的時(shí)候,難免會遇到一些網(wǎng)絡(luò)問題,這時(shí)候需要加入重試機(jī)制了,下面小編就給大家分享幾個(gè)接口重試的寫法吧
    2023-11-11
  • Java設(shè)計(jì)模式之策略模式示例詳解

    Java設(shè)計(jì)模式之策略模式示例詳解

    這篇文章主要為大家詳細(xì)介紹了Java的策略模式,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • JAVA版排序算法之快速排序示例

    JAVA版排序算法之快速排序示例

    這篇文章主要介紹了JAVA版排序算法之快速排序,結(jié)合實(shí)例形式分析了基于java版的遍歷、遞歸實(shí)現(xiàn)快速排序功能的具體步驟與操作技巧,需要的朋友可以參考下
    2017-01-01
  • 詳解SpringBoot中自定義starter的開發(fā)與使用

    詳解SpringBoot中自定義starter的開發(fā)與使用

    starter是SpringBoot中非常重要的一個(gè)機(jī)制,他是基于約定優(yōu)于配置的思想所衍生出來的,本文主要介紹了SpringBoot中自定義starter的開發(fā)與使用,感興趣的可以了解下
    2023-09-09
  • Java中字符串中連續(xù)相同字符去重方法

    Java中字符串中連續(xù)相同字符去重方法

    今天小編就為大家分享一篇Java中字符串中連續(xù)相同字符去重方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-07-07
  • SpringMVC中控制器返回JSON數(shù)據(jù)的實(shí)現(xiàn)

    SpringMVC中控制器返回JSON數(shù)據(jù)的實(shí)現(xiàn)

    本文主要介紹了SpringMVC中控制器返回JSON數(shù)據(jù)的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07

最新評論

梅州市| 阳春市| 平武县| 武定县| 工布江达县| 沧州市| 建水县| 光山县| 阿鲁科尔沁旗| 漳平市| 卓资县| 凤凰县| 沁阳市| 兴隆县| 南乐县| 长寿区| 鄂托克旗| 镇安县| 兴国县| 米易县| 罗城| 水城县| 宜兰县| 蒙阴县| 吕梁市| 磐石市| 万荣县| 温州市| 揭东县| 萝北县| 文化| 叙永县| 永城市| 德保县| 昆明市| 松桃| 沂水县| 新竹县| 安阳县| 安顺市| 宿松县|