Java 原型模式-學姐最終還是被我征服了......讓你以最生動的例子記住原型模式


原型模式

原型模式屬於創建型模式,用原型實例指定待創建對象的類型,並且通過複製這個原型來創建新的對象!(但是學姐是不可複製的哦,只有我這裏有,還不趕快關注我的 Java精選頻道


小故事引入

自上篇繼續講故事

我向學姐請教了建造者模式,她以很生動的例子給我講了一下!讓我理解地很透徹,我們一起學習到了了很晚!“憶難弟弟,我們一起把攔精靈用了吧!”,學姐說道!我便委婉的點點頭!緊接着,學姐慢慢的把我按在牀上,仔細的看着我的臉,此時觀察學姐,那兩顆小虎牙襯托出學姐的呆萌,溼潤的嘴脣確實好看,軟軟的,恨不得去咬一下…

“好了,先去洗澡了!”,我對學姐說道。學姐從我身上慢慢的起開,“一起嗎?”,“好呀!”,我們的對話變得奇怪了起來!接着我準備了兩套睡衣,因爲沒有女生的睡衣,所以只能讓學姐穿我的,可能有點大吧!學姐要先換上睡衣,我扭過去頭!等學姐換好之後,我讓學姐先去,我換上睡衣隨後就到。學姐拿上“攔精靈”就先往洗浴間去了。我家的洗浴間還是那種比較大的,有兩個浴缸,所以,是可以同時兩個人洗澡的。我換上睡衣之後,便去了洗浴間把熱水放開,撒上玫瑰花瓣,別有一番格調!水溫剛剛好,這可能是很舒服的一個晚上…

學姐脫下睡衣,看着學姐的性感後背,身形苗條,皮膚如雪,腦後露出一頭烏雲般的秀髮,再加上那煙霧繚繞的白氣襯托,真是差點讓人失去理智!

因爲我們的手機都不防水,此時此刻,“攔精靈”就起到作用了!正好有兩個,我們便把“攔精靈”套在手機上,這樣就起到了防水的作用,可以邊泡澡邊玩手機了。“我們來下象棋吧!”,我說道,接着我們倆邊泡澡邊下起了象棋。其實有一次,我邊泡澡邊用手機下象棋,不小心把手機掉進水裏了!但是這次不一樣,有了“攔精靈”的保護,再也不怕手機進水!

哈哈,學姐的棋藝雖然高超,但是還是缺乏一些理智的“戰術”,最終,學姐還是被我征服了!學姐哪有那麼容易認輸,接着我們又接二連三玩了幾把,但是學姐依舊沒有贏。泡的差不多了,這把象棋還玩在一半,於是,我讓這點學姐,讓她贏了一把,以便改改我這個“直男”的性格!當學姐贏了以後,開心的笑了起來!泡澡泡的很舒服,泡完澡後,我打開了一瓶紅酒,拿出兩個酒杯,倒上了酒。邊下象棋邊喝紅酒,估計也只有我倆能幹的出來了!

唉,這篇故事又要結束了,來講講原型模式吧!收起聽故事的小心思,和我一起來看看原型模式!下篇接着這篇劇情講故事、講技術!

下篇文章:Java 適配器模式-難道學姐這是喫醋了麼?…讓你以最生動的例子記住適配器模式


原型模式Demo

下了幾次棋,學弟把學姐征服了多少次?這裏是以次爲單位,我們需要把這個樞紐創建出來,爲下棋計單位!

/**
 * 樞紐:單位,次
 */
public class Hinge {

    private String unit;

    public String getUnit() {
        return unit;
    }

    public void setUnit(String unit) {
        this.unit = unit;
    }
}


接着學姐和學弟下棋來舉例,先來個學弟和學姐的下棋類,並實現Cloneable接口!
Cloneable其實就是一個標記接口,只有實現這個接口後,然後在類中重寫Object中的clone方法,然後通過類調用clone方法才能克隆成功,如果不實現這個接口,則會拋出 CloneNotSupportedException 異常。

/**
 * 學弟和學姐的下棋類
 */
public class PlayChess implements Cloneable {

    //和漂亮學姐下棋的次數
    private int num;

    //和漂亮學姐下棋的單位
    private Hinge hinge;

    public PlayChess(int num, Hinge hinge) {
        this.num = num;
        this.hinge = hinge;
    }

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }

    public Hinge getHinge() {
        return hinge;
    }

    public void setHinge(Hinge hinge) {
        this.hinge = hinge;
    }

    /**
     * 重寫clone方法
     *
     * @return
     * @throws CloneNotSupportedException
     */
    @Override
    protected PlayChess clone() throws CloneNotSupportedException {
        return (PlayChess) super.clone();
    }
}


該具備的都具備了,現在就可以下棋了!


/**
 * 學姐的原型模式
 *
 * @author CSDN程憶難
 * @link https://myhub.blog.csdn.net
 */
public class Prototype {

    public static void main(String[] args) {

        //單位
        Hinge hinge = new Hinge();
        hinge.setUnit("次");

        //這是第一次和學姐下棋
        PlayChess money = new PlayChess(1, hinge);

        for (int i = 0; i < 20; i++) {

            try {
				//克隆
                PlayChess playChess = money.clone();
                playChess.setNum(i + 1);
                System.out.println("這是學弟和學姐 第 " + playChess.getNum() + " " + playChess.getHinge().getUnit() + "下棋 學姐輸了 | 學姐被學弟 征服了 " + playChess.getNum() + " " + playChess.getHinge().getUnit());

            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }

        }
    }
}

程序結構是這樣的:
在這裏插入圖片描述


好了,開始下棋,讓學弟征服學姐吧!!!

在這裏插入圖片描述

這就是原型模式的基本使用


使用原型模式的好處

  • 提高性能;
  • 不用頻繁new對象;
  • 消耗的資源少。

淺克隆和深克隆

介紹一下淺克隆和深克隆!

淺克隆

下棋和征服不僅僅可以用次數來表示,還可以通過局這個單位,來舉個例子!我在第24行,將單位改成了局!

/**
 * 學姐的原型模式
 *
 * @author CSDN程憶難
 * @link https://myhub.blog.csdn.net
 */
public class Prototype {

    public static void main(String[] args) {

        //單位
        Hinge hinge = new Hinge();
        hinge.setUnit("次");

        //這是第一次和學姐下棋
        PlayChess money = new PlayChess(1, hinge);

        for (int i = 0; i < 20; i++) {

            try {
                PlayChess playChess = money.clone();
                playChess.setNum(i + 1);

                hinge.setUnit("局");

                System.out.println("這是學弟和學姐 第 " + playChess.getNum() + " " + playChess.getHinge().getUnit() + "下棋 學姐輸了 | 學姐被學弟 征服了 " + playChess.getNum() + " " + playChess.getHinge().getUnit());

            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }

        }
    }
}

然後看到運行結果全部改成了局
在這裏插入圖片描述

仔細觀察代碼你會發現,只是把原型的單位改了一下,但克隆的實例也跟着改變了!!!
這是因爲實例對象指向了同一個內存地址,這其實就是淺克隆!


深克隆

實現深克隆,需要修改兩處,保證指向的不是同一個內存地址就可以!
讓樞紐也實現Cloneable接口:

/**
 * 樞紐:單位,次
 */
public class Hinge implements Cloneable {

    private String unit;

    public String getUnit() {
        return unit;
    }

    public void setUnit(String unit) {
        this.unit = unit;
    }

    @Override
    protected Hinge clone() throws CloneNotSupportedException {
        return (Hinge) super.clone();
    }
}


修改一下下棋方法,下棋的時候增加克隆Hinge類

/**
 * 學弟和學姐的下棋類
 */
public class PlayChess implements Cloneable {

    //和漂亮學姐下棋的次數
    private int num;

    //和漂亮學姐下棋的單位
    private Hinge hinge;

    public PlayChess(int num, Hinge hinge) {
        this.num = num;
        this.hinge = hinge;
    }

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }

    public Hinge getHinge() {
        return hinge;
    }

    public void setHinge(Hinge hinge) {
        this.hinge = hinge;
    }

    /**
     * 重寫clone方法
     *
     * @return
     * @throws CloneNotSupportedException
     */
    @Override
    protected PlayChess clone() throws CloneNotSupportedException {
        PlayChess playChess = (PlayChess) super.clone();
        playChess.hinge = this.hinge.clone();
        return playChess;
    }

}


之後再次運行就會發現:
在這裏插入圖片描述

這就是深克隆!!!

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