原型模式

《大話設(shè)計(jì)模式》閱讀筆記和總結(jié)双吆。原書是C#編寫的,本人用Java實(shí)現(xiàn)了一遍蕉拢,包括每種設(shè)計(jì)模式的UML圖實(shí)現(xiàn)和示例代碼實(shí)現(xiàn)眯牧。
目錄:設(shè)計(jì)模式
Github地址:DesignPattern

說明

定義:原型模式(Prototype),用原型實(shí)例指定創(chuàng)建對(duì)象的種類外恕,并且通過拷貝這些原型創(chuàng)建新的對(duì)象杆逗。

UML圖:

原型模式UML圖.png

代碼實(shí)現(xiàn):

原型類

我們這里使用java api中Cloneable接口

具體原型類

class ConcretePrototype1 implements Cloneable{

    private String id;
    public ConcretePrototype1(String id){
        this.id = id;
    }

    public String getId(){
        return id;
    }

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

客戶端代碼

public class PrototypePattern {
    public static void main(String[] args) throws CloneNotSupportedException {
        ConcretePrototype1 p1 = new ConcretePrototype1("I");
        ConcretePrototype1 c1 = (ConcretePrototype1) p1.clone();
        System.out.println("Cloned():"+c1.getId());
    }
}

運(yùn)行結(jié)果

Cloned():I

示例

例子:用程序模擬寫簡(jiǎn)歷,要求有一個(gè)簡(jiǎn)歷類鳞疲,必要有姓名罪郊,可以設(shè)置性別和年齡,可以設(shè)置工作經(jīng)歷尚洽,最終需要三份簡(jiǎn)歷悔橄。

UML圖:

原型模式示例UML圖.png

代碼實(shí)現(xiàn):

工作經(jīng)歷類

public class WorkExperence implements Serializable {
    private String workDate;
    private String company;

    public String getWorkDate() {
        return workDate;
    }

    public void setWorkDate(String workDate) {
        this.workDate = workDate;
    }

    public String getCompany() {
        return company;
    }

    public void setCompany(String company) {
        this.company = company;
    }
}

簡(jiǎn)歷類

public class Resume implements Cloneable,Serializable{
    private String name;
    private String sex;
    private int age;

    private WorkExperence workExperence;

    public Resume(){
        workExperence = new WorkExperence();
    }

    public void display() {
        System.out.println(this.getName() + " " + this.getSex() + " "
                + this.getAge() + "\n工作經(jīng)歷: "
                + this.getWorkExperence().getWorkDate() + " "
                + this.getWorkExperence().getCompany());
    }

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

    public String getName() {
        return name;
    }

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

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

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

    public WorkExperence getWorkExperence() {
        return workExperence;
    }

    public void setWorkExperence(String workDate,String company) {
        workExperence.setCompany(company);
        workExperence.setWorkDate(workDate);
    }
}

客戶端調(diào)用

public class Main {
    public static void main(String[] args) throws CloneNotSupportedException, IOException, ClassNotFoundException {
        copy();
    }

    public static void copy() throws CloneNotSupportedException {
        Resume resumeA = new Resume();
        resumeA.setName("大鳥");
        resumeA.setAge(25);
        resumeA.setSex("男");
        resumeA.setWorkExperence("2015-2016","A公司");

        Resume resumeB = (Resume) resumeA.clone();
        resumeB.setWorkExperence("2016-2017","B公司");

        Resume resumeC = (Resume) resumeA.clone();
        resumeC.setWorkExperence("2017-2018","C公司");

        resumeA.display();
        resumeB.display();
        resumeC.display();
    }
}

運(yùn)行結(jié)果

大鳥 男 25
工作經(jīng)歷: 2017-2018 C公司
大鳥 男 25
工作經(jīng)歷: 2017-2018 C公司
大鳥 男 25
工作經(jīng)歷: 2017-2018 C公司

我們發(fā)現(xiàn),設(shè)置的工作經(jīng)歷并沒有正確的顯示翎朱。原因是:如果復(fù)制的字段是值類型的橄维,則對(duì)該字段執(zhí)行逐位復(fù)制,如果字段是引用類型拴曲,則復(fù)制引用但不復(fù)制引用的對(duì)象争舞,因此原始對(duì)象及其復(fù)本引用同一對(duì)象。

深拷貝實(shí)現(xiàn)

UML圖:

原型模式示例深拷貝UML圖.png

代碼實(shí)現(xiàn):

簡(jiǎn)歷類增加deepClone()方法

public class Resume implements Cloneable,Serializable{
    // ……
    public Object deepClone() throws IOException, ClassNotFoundException {
        // 將對(duì)象寫入流內(nèi)
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(this);

        // 從流內(nèi)讀出對(duì)象
        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));
        return ois.readObject();
    }
}

客戶端代碼

public class Main {
    public static void main(String[] args) throws CloneNotSupportedException, IOException, ClassNotFoundException {
        copy();
        
        System.out.println("==============");

        deepCopy();
    }

    public static void copy() throws CloneNotSupportedException {
        Resume resumeA = new Resume();
        resumeA.setName("大鳥");
        resumeA.setAge(25);
        resumeA.setSex("男");
        resumeA.setWorkExperence("2015-2016","A公司");

        Resume resumeB = (Resume) resumeA.clone();
        resumeB.setWorkExperence("2016-2017","B公司");

        Resume resumeC = (Resume) resumeA.clone();
        resumeC.setWorkExperence("2017-2018","C公司");

        resumeA.display();
        resumeB.display();
        resumeC.display();
    }

    public static void deepCopy() throws IOException, ClassNotFoundException {
        Resume resumeA = new Resume();
        resumeA.setName("大鳥");
        resumeA.setAge(25);
        resumeA.setSex("男");
        resumeA.setWorkExperence("2015-2016","A公司");

        Resume resumeB = (Resume) resumeA.deepClone();
        resumeB.setWorkExperence("2016-2017","B公司");

        Resume resumeC = (Resume) resumeA.deepClone();
        resumeC.setWorkExperence("2017-2018","C公司");

        resumeA.display();
        resumeB.display();
        resumeC.display();
    }
}

運(yùn)行結(jié)果:

大鳥 男 25
工作經(jīng)歷: 2017-2018 C公司
大鳥 男 25
工作經(jīng)歷: 2017-2018 C公司
大鳥 男 25
工作經(jīng)歷: 2017-2018 C公司
==============
大鳥 男 25
工作經(jīng)歷: 2015-2016 A公司
大鳥 男 25
工作經(jīng)歷: 2016-2017 B公司
大鳥 男 25
工作經(jīng)歷: 2017-2018 C公司
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末澈灼,一起剝皮案震驚了整個(gè)濱河市竞川,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌叁熔,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,496評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件荣回,死亡現(xiàn)場(chǎng)離奇詭異遭贸,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)心软,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門壕吹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來著蛙,“玉大人,你說我怎么就攤上這事耳贬√けぃ” “怎么了?”我有些...
    開封第一講書人閱讀 162,632評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵咒劲,是天一觀的道長(zhǎng)顷蟆。 經(jīng)常有香客問我,道長(zhǎng)腐魂,這世上最難降的妖魔是什么帐偎? 我笑而不...
    開封第一講書人閱讀 58,180評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮挤渔,結(jié)果婚禮上肮街,老公的妹妹穿的比我還像新娘。我一直安慰自己判导,他們只是感情好嫉父,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著眼刃,像睡著了一般绕辖。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上擂红,一...
    開封第一講書人閱讀 51,165評(píng)論 1 299
  • 那天仪际,我揣著相機(jī)與錄音,去河邊找鬼昵骤。 笑死树碱,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的变秦。 我是一名探鬼主播成榜,決...
    沈念sama閱讀 40,052評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼蹦玫!你這毒婦竟也來了赎婚?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,910評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤樱溉,失蹤者是張志新(化名)和其女友劉穎称龙,沒想到半個(gè)月后跳夭,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,324評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡牢贸,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評(píng)論 2 332
  • 正文 我和宋清朗相戀三年谈火,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,711評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖向瓷,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情舰涌,我是刑警寧澤,帶...
    沈念sama閱讀 35,424評(píng)論 5 343
  • 正文 年R本政府宣布你稚,位于F島的核電站瓷耙,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏刁赖。R本人自食惡果不足惜搁痛,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望宇弛。 院中可真熱鬧鸡典,春花似錦、人聲如沸枪芒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽舅踪。三九已至纽甘,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間抽碌,已是汗流浹背悍赢。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留货徙,地道東北人左权。 一個(gè)月前我還...
    沈念sama閱讀 47,722評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像痴颊,于是被迫代替她去往敵國(guó)和親赏迟。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容