原型模式

spring中的scope=“prototype”,JSON.parseObject()都是一種原型模式。
原型模式適合以下場景:

  1. 類初始化消耗資源較多
  2. new一個對象很麻煩
  3. 構(gòu)造函數(shù)很復(fù)雜
  4. 循環(huán)體中產(chǎn)生大量對象

淺克隆

標(biāo)準(zhǔn)的原型模式:
接口:

public interface Prototype {
    Prototype clone();
}

需要被克隆的類:

public class ConcretePrototypeA implements Prototype {

    private int age;
    private String name;
    private List<String> hobbies;

    public int getAge() {
        return age;
    }

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

    public String getName() {
        return name;
    }

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

    public List<String> getHobbies() {
        return hobbies;
    }

    public void setHobbies(List<String> hobbies) {
        this.hobbies = hobbies;
    }

    @Override
    public Prototype clone() {
        ConcretePrototypeA concretePrototypeA = new ConcretePrototypeA();
        concretePrototypeA.setAge(this.age);
        concretePrototypeA.setName(this.name);
        concretePrototypeA.setHobbies(this.hobbies);
        return concretePrototypeA;
    }
}

clinet類:

public class Client {

    private Prototype prototype;

    public Client(Prototype prototype) {
        this.prototype = prototype;
    }

    public Prototype startClone(Prototype prototype){
        return prototype.clone();
    }

}

測試代碼:

    @Test
    public void test1() {
        ConcretePrototypeA concretePrototypeA = new ConcretePrototypeA();
        concretePrototypeA.setAge(18);
        concretePrototypeA.setName("Tom");
        concretePrototypeA.setHobbies(Arrays.asList("hob", "by"));

        // 創(chuàng)建client準(zhǔn)備克隆
        Client client = new Client(concretePrototypeA);
        ConcretePrototypeA clone = (ConcretePrototypeA) client.startClone(concretePrototypeA);
        System.out.println("clone = " + clone);
        System.out.println(concretePrototypeA.getHobbies());
        System.out.println(clone.getHobbies());
        System.out.println(concretePrototypeA.getHobbies() == clone.getHobbies());
    }

運行結(jié)果不盡人意,引用類型并沒有完全克隆,只復(fù)制了值類型。

深克隆

用序列化反序列化實現(xiàn):

@Data
public class Monkey implements Serializable {

    private int height;
    private int weight;
    public Date birthday;

}
@Data
public class JinGuBang implements Serializable {

    private float h = 100;
    private float d = 10;

    public void big() {
        this.d *= 2;
        this.h *= 2;
    }

    public void small(){
        this.d /= 2;
        this.h /= 2;
    }

}
@Data
public class QiTianDaSheng extends Monkey implements Cloneable, Serializable {

    private JinGuBang jinGuBang;

    public QiTianDaSheng() {
        this.birthday = new Date();
        this.jinGuBang = new JinGuBang();
    }

    public QiTianDaSheng(JinGuBang jinGuBang) {
        this.jinGuBang = jinGuBang;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return this.deepClone();
    }

    public Object 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);
            QiTianDaSheng copy = (QiTianDaSheng) ois.readObject();
            return copy;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

}

測試:

    @Test
    public void test() throws CloneNotSupportedException {
        QiTianDaSheng qiTianDaSheng = new QiTianDaSheng();
        QiTianDaSheng clone = (QiTianDaSheng) qiTianDaSheng.clone();
        System.out.println("深克隆 "+(qiTianDaSheng==clone));
        System.out.println("深克隆 "+(qiTianDaSheng.getJinGuBang()==clone.getJinGuBang()));
    }

結(jié)果:
引用類型指向不同的對象,成功深克?。?/p>

克隆會破壞單例模式

需要放置克隆破壞單例模式,就要重寫clone方法,在clone方法里面返回單例對象就可以了。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

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