java設計模式-原型模式(淺複製,深複製)

使用場景:
多次創建重複的類,每個類又需要非常繁瑣的數據準備和訪問權限。

原型模式類似用new創建出來的類,但又不new的類,new出來的類屬性都是默認值,而用原型模式克隆出來的類,屬性都和原對象一樣。原型模式的優點是複製類效率高,而且避免重複無聊的new類動作

下面,我們使用原型模式來clone一個類,這裏的demo既有深複製也有淺複製

首先是我們複製的實體類

package com.javademo.pattern.prototype;

import java.io.Serializable;


/**
 * Cloneable,clone淺複製需要用
 * Serializable序列話和反序列化需要用
 * @author liuxg
 * @date 2016年5月24日 下午9:29:19
 */
@SuppressWarnings("serial")
public class User implements Cloneable ,Serializable {

    private String name ;
    private int age ;

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

    public User(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;
    }

}

接下來寫測試類

package com.javademo.pattern.prototype;

import java.io.ByteArrayInputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import org.apache.commons.io.output.ByteArrayOutputStream;


/**
 * 原型模式測試
 * @author liuxg
 * @date 2016年5月24日 下午9:27:21
 */
public class Client01 {

    public static void main(String[] args) {
        Client01 client01 = new Client01() ;
        client01.lightCopy();
        client01.deepCopy();
    }


    /**
     * 淺複製,只能複製類,但類的屬性還是指向同一個地址
     * 
     */
    private void lightCopy(){

        User user = new User("liuxg",18);
        User uclone = (User)user.clone();
        //user.setName("liuxg2"); //重新把user的name設置爲liuxg2.發現uclone下的name也變成了liuxg2,所有user和uclone指向的同一個地址
        System.out.println(uclone.getName() + " : " + uclone.getAge());
    }


    /**
     * 深複製,除了複製類,還複雜屬性,使用的時候java的序列化和反序列化
     */
    private void deepCopy(){

        try {
            User user = new User("liuxg",18);

            //序列化
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream oos =  new ObjectOutputStream(bos);
            oos.writeObject(user);  

            //反序列化
            ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bis);
            User uclone = (User) ois.readObject();

            //user.setName("liuxg2"); //user的name變成liuxg2,uclone的name還是liuxg,說明屬性也進行不了複製,沒有指向同一個地址
            System.out.println(uclone.getName() + " : " + uclone.getAge());

            oos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

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