原型模式

概念:該模式有一個樣板實例,這個被克隆的實例就是我們說的“原型”。說白了就是有一個對象A,我們要操作的時候拷貝A得到一個A的副本B,這個A就稱之爲原型。我們操作的時候是對B做操作,這樣就不會影響到原型A。

應用場景:

  1. 類初始化的時候需要消耗的資源比較多,這些資源包括數據、硬件等資源,通過原型拷貝可以避免這些消耗。
  2. 通過new產生一個對象需要非常繁瑣的數據準備或者權限,這時可以使用原型模式。
  3. 一個對象需要供給其他對象訪問,而且各個對象可能都需要修改其值時,可以考慮使用原型模式拷貝多個對象供調用者使用,即保護性拷貝。

拷貝:

  1. 淺拷貝:只拷貝基本類型,不會拷貝引用類型,引用類型複製之後,還是共同引用,但是String類型除外,因爲String是被final修飾的,所以各個對象之間互不影響。
  2. 深拷貝:會在計算機中開闢一個新的內存地址,所以深拷貝對象都是新的對象。

原型模式demo:

public class Book implements Cloneable{
    //名稱
    private String title;
    //圖片
    private ArrayList<String> listImg = new ArrayList<>();

    public void addImg(String imgName){
        listImg.add(imgName);
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public List<String> getListImg() {
        return listImg;
    }

    public void setListImg(ArrayList<String> listImg) {
        this.listImg = listImg;
    }

    public void showBook(){
        System.out.println("..................start......................");
        System.out.println("title:" + title);
        listImg.stream().forEach(img -> System.out.println("img name" + img));
        System.out.println("..................end......................");
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        //淺克隆  默認淺克隆
        Book book = (Book)super.clone();
        //深克隆
        book.listImg = (ArrayList<String>) this.listImg.clone();//這個方法在ArrayList類中,List接口沒有這個clone()方法
        return book;
    }
}

public class Client {
    public static void main(String[] args) throws CloneNotSupportedException {
        Book book1 = new Book();
        book1.setTitle("圖書1");
        book1.addImg("圖片1");
        book1.showBook();
        //以原型方式進行復制
        Book cloneBook = (Book) book1.clone();
        book1.setTitle("圖書2");
        book1.addImg("圖片2");
        cloneBook.showBook();
        book1.showBook();
    }
}

輸出結果:

..................start......................
title:圖書1
img name圖片1
..................end......................

..................start......................
title:圖書1
img name圖片1
..................end......................

..................start......................
title:圖書2
img name圖片1
img name圖片2
..................end......................

上述代碼,定義了一本書,有名稱和圖片兩個屬性,標題是String類型的,圖片是ArrayList集合,通過淺克隆克隆String類型的title,深克隆克隆ArrayList類型的圖片,這樣就可以克隆出一個新的對象出來,然後進行賦值比較。通過輸出結果可以看出,book1賦值圖書1和圖片1之後拷貝一個cloneBook對象,然後再對book1對象進行修改,但是此時並不會對cloneBook有影響,也就是說已經是兩個不同的對象了。如果使用淺克隆對Arraylist進行操作的話,cloneBook對象的輸出應該是:“圖書1,圖片1,圖片2”(只要將“  book.listImg = (ArrayList<String>) this.listImg.clone();” 這句註釋即可,可以私下去驗證一下)。

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