設計模式——原型模式

一、介紹

當系統(tǒng)中需要頻繁的創(chuàng)建同一個對象,對象創(chuàng)建時又伴隨著大量初始化操作、比較繁瑣時,這個時候考慮用原型模式去生成多個對象。Java中所有的類最終都繼承自父類Object,Obejct中定義了clone這個抽象方法,子類調(diào)用clone方法獲取的對象屬于淺拷貝;定義類的時候?qū)崿F(xiàn)Cloneable接口,重寫clone方法重寫具體的clone細節(jié)可實現(xiàn)深拷貝。
原型模式是對對象的拷貝,分為淺拷貝深拷貝兩種方式。

二、代碼實例

1、淺拷貝

定義Sheep類,實現(xiàn)Cloneable接口,重寫clone方法:

public class Sheep implements Cloneable{

    private String name;

    private int age;

    private Sheep friend;

    public Sheep(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Sheep getFriend() {
        return friend;
    }

    public void setFriend(Sheep friend) {
        this.friend = friend;
    }

    @Override
    protected Object clone() {
        Sheep sheep = null;
        try {
            sheep = (Sheep)super.clone();
        }catch (CloneNotSupportedException e){
            e.printStackTrace();
        }
        return sheep;
    }
}

調(diào)用:

public class Main {

    public static void main(String[] args){
        Sheep sheep1 = new Sheep("喜羊羊",1);
        sheep1.setFriend(new Sheep("懶羊羊",1));
        Sheep sheep2 = (Sheep) sheep1.clone();


        System.out.println("sheep1 hashcode:"+sheep1.hashCode());
        System.out.println("sheep2 hashcode:"+sheep2.hashCode());

        System.out.println("sheep1 friend hashcode:"+sheep1.getFriend().hashCode());
        System.out.println("sheep2 friend hashcode:"+sheep2.getFriend().hashCode());

        sheep2.getFriend().setName("美羊羊");
        System.out.println("sheep1 friend name:"+sheep1.getFriend().getName());
        System.out.println("sheep2 friend name:"+sheep2.getFriend().getName());
    }
}
淺拷貝

2、深拷貝

定義Person類:

public class Person implements Cloneable{

    private String name;

    private int age;

    private Boy boy;

    public Person(String name, int age, Boy boy) {
        this.name = name;
        this.age = age;
        this.boy = boy;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Boy getBoy() {
        return boy;
    }

    public void setBoy(Boy boy) {
        this.boy = boy;
    }

    @Override
    protected Object clone()  {
        Object person;
        try{
            person = super.clone();
            Person clonePerson = (Person) person;
            clonePerson.setBoy((Boy)clonePerson.getBoy().clone());
            return clonePerson;
        }catch (CloneNotSupportedException e){
            e.printStackTrace();
        }
        return null;
    }
}

調(diào)用:

public class Main {

    public static void main(String[] args){
        Person person1 = new Person("張三",22,new Boy("張三boy",22));
        Person person2 = (Person) person1.clone();

        System.out.println("person1 hashcode:"+person1.hashCode());
        System.out.println("person2 hashcode:"+person2.hashCode());

        System.out.println("person1 boy hashcode:"+person1.getBoy().hashCode());
        System.out.println("person2 boy hashcode:"+person2.getBoy().hashCode());

        person2.getBoy().setName("李四boy");

        System.out.println("person1 boy name:"+person1.getBoy().getName());
        System.out.println("person2 boy name:"+person2.getBoy().getName());
    }
}
深拷貝

三、總結(jié)

原型模式作為Java23中設計模式中創(chuàng)建型模式的一種,主要是對于對象創(chuàng)建麻煩,牽扯到其他變量的初始化,同時又需要大量、頻繁的創(chuàng)建場景使用,通過調(diào)用父類Objec定義的clone方法或者實現(xiàn)Cloneable接口,重寫clone方法來實現(xiàn),原型模式的實現(xiàn)分為淺拷貝深拷貝

  • 淺拷貝:直接調(diào)用super.clone()即可。clone對象的時候,類中包含的基本類型變量和String類型的變量只是進行值傳遞,clone的對象對于這些變量新開辟一片內(nèi)存地址去存儲值;引用類型的變量在clone后還是指向之前的內(nèi)存地址,原對象和clone的對象共享同一個內(nèi)存地址,即改變其中某個對象的引用類型變量值,其他對象的對應值也會變化。(淺拷貝代碼貼圖中,改變了sheep2對象中的引用對象friend的name值,sheep1的friend name值也改變了。)
  • 深拷貝:引用類型變量也需要實現(xiàn)Cloneable接口,重寫clone方法,對引用類型調(diào)用clone方法,重新賦值給對象返回。深拷貝中不管什么類型的變量都會重新開辟內(nèi)存,即clone的對象和原對象的變量指向不同的地址,clone的對象變量值變化不會引起原對象變量值的變化。(深拷貝代碼貼圖中clone對象person2改變引用變量boy的name后,原對象person1的boy name還是沒變。)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

  • 前言 本文的主要內(nèi)容如下: 介紹原型模式 示例Java語言的clone淺克隆與深克隆實現(xiàn)深克隆 原型模式的典型應用...
    小旋鋒的簡書閱讀 2,025評論 0 2
  • 個性電子賬單 現(xiàn)在電子賬單越來越流行了,比如你的信用卡,沒到月初的時候銀行就會發(fā)一份電子郵件給你,說你這個月消費了...
    stayiwithime閱讀 537評論 0 0
  • 原型模式(Prototype Pattern) 原型模式(Prototype Pattern)是用于創(chuàng)建重復的對象...
    thorhill閱讀 1,519評論 0 2
  • 定義:用原型實例指定創(chuàng)建對象的種類,并通過拷貝這些原型創(chuàng)建新的對象。 類型:創(chuàng)建類模式 類圖: 原型模式主要用于對...
    郭某人1閱讀 251評論 0 0
  • 我們在創(chuàng)建對象時,通常是通過new關(guān)鍵字來創(chuàng)建的。但是,思考一下,如果當前類的構(gòu)造函數(shù)很復雜,每次new對象時都會...
    煙雨星空閱讀 128評論 0 0

友情鏈接更多精彩內(nèi)容