瞭解23種設計模式之原型模式

一,什麼是原型模式。

Prototype 模式 是一種對象創建型模式,它採取複製原型對象的方法來創建對象的實例。使用Prototype模式創建的實例,具有與原型一樣的數據。

二,原型模式的特點。

由原型對象自身創建目標對象,通過實現接口 (Cloneable) ,目標對象是原型對象的一個克隆,不僅僅是具有相同的結構,屬性,還與原型對象具有相同的值。

但是 在實例化目標對象,和實例化原型對象後, 在jvm 虛擬機 堆內存裏是 兩個地址不相同的引用對象。

根據對象克隆深度層次的不同,有淺度克隆與深度克隆。

三,實例。

3.1 淺度克隆

public class ProtoType  implements  Cloneable{

    //淺度克隆基礎數據類型
    private  String name;
    private  String age;

    public String getName() {
        return name;
    }

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

    public String getAge() {
        return age;
    }

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

    public ProtoType cloneObject(){
        try {
            //每一個對象的父類的都是Object, object 實現了clone(), 這裏可以直接調用
            return (ProtoType)super.clone();
        } catch (CloneNotSupportedException e) {
            //沒有實現(Cloneable)接口,會拋出不支持克隆異常,
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public String toString() {
        return "ProtoType{" +
                "name='" + name + '\'' +
                ", age='" + age + '\'' +
                ", peopleList=" + peopleList +
                '}';
    }
}
public class Test {

    public static void main(String[] args) {

        //具有相同的值,和結構 ,淺度克隆
        ProtoType protoType = new ProtoType();
        protoType.setName("張三");
        protoType.setAge("18");
        System.out.println("原型對象===" +protoType.toString());

        ProtoType protoType2 =  protoType.cloneObject();
        System.out.println("克隆對象===" +protoType.toString());

        System.out.println("原型對象=克隆對象:"+(protoType == protoType2));

     
    }
}

3.2 深度克隆對象

public class ProtoType  implements  Cloneable{

   
    private  String name;
    private  String age;

    /**
     * 深度克隆引用類型,使原型對象中的引用數據類型 與 模型對象中的引用數據類型 地址不一致
     */
    private List<String> peopleList;

    public List<String> getPeopleList() {
        return peopleList;
    }

    public void setPeopleList(List<String> peopleList) {
        this.peopleList = peopleList;
    }

    public String getName() {
        return name;
    }

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

    public String getAge() {
        return age;
    }

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

    public ProtoType cloneObject(){
        try {
            //每一個類的父類的都是Object, object 實現了clone(), 這裏可以直接調用
            ProtoType protoType =(ProtoType)super.clone();
            //深度克隆原型對象中的引用數據類型,其實就是創建一個新的對象,
            // 使原型對象中的引用數據類型 被克隆 模型對象時,讓引用數據類型 地址不一致
            List<String> list = new ArrayList<String>();
            for(String str:this.peopleList){
                list.add(str);
            }
            protoType.setPeopleList(list);
            return protoType;
        } catch (CloneNotSupportedException e) {
            //沒有實現(Cloneable)接口,會拋出不支持克隆異常,
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public String toString() {
        return "ProtoType{" +
                "name='" + name + '\'' +
                ", age='" + age + '\'' +
                ", peopleList=" + peopleList +
                '}';
    }
}
public class Test {

    public static void main(String[] args) {

        //深度克隆
        ProtoType protoType1 = new ProtoType();
        List<String> peopleList = new ArrayList<String>();
        peopleList.add("小王");
        peopleList.add("小李");

        protoType1.setPeopleList(peopleList);
        ProtoType protoType2 = protoType1.cloneObject();

        System.out.println(protoType1.getPeopleList());
        System.out.println(protoType2.getPeopleList());

        peopleList.add("小美");
        protoType1.setPeopleList(peopleList);
        System.out.println(protoType1.getPeopleList());
        System.out.println(protoType2.getPeopleList());
    }
}

總結:

在創建對象的時候,我們不只是希望被創建的對象繼承其基類的基本結構,還希望繼承原型對象的數據

希望對目標對象的修改不影響既有的原型對象(深度克隆的時候可以完全互補影響)

隱藏克隆操作的細節,很多時候,對對象本身的克隆需要涉及到本身的數據細節

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章