設(shè)計(jì)模式--原型模式

目錄

本文的結(jié)構(gòu)如下:

  • 引言
  • 什么是原型模式
  • 淺克隆和深克隆
  • clone()
  • 模式的結(jié)構(gòu)
  • 典型代碼
  • 代碼示例
  • 優(yōu)點(diǎn)和缺點(diǎn)
  • 適用環(huán)境

一、引言

我是一個(gè)很幼稚的人盈厘,所以經(jīng)常會有很幼稚的想法雅采,比如击碗,有時(shí)候上著班我就在想把跨,要是我能夠影分身多好丧没,這樣鹰椒,我可以讓一號分身陪女朋友和家人,二號分身上班敲代碼骂铁,三號分身街頭賣烤串吹零,四號分身被窩玩游戲......

我的可笑想法在當(dāng)下是不現(xiàn)實(shí)的,但在軟件開發(fā)中拉庵,卻是非常務(wù)實(shí)的灿椅。設(shè)計(jì)模式中有一個(gè)模式,可以通過一個(gè)原型對象克隆出多個(gè)一模一樣的對象,該模式稱之為原型模式茫蛹。

二操刀、什么是原型模式

在使用原型模式時(shí),我們需要首先創(chuàng)建一個(gè)原型對象婴洼,再通過復(fù)制這個(gè)原型對象來創(chuàng)建更多同類型的對象。一般這個(gè)原型對象的實(shí)例化很復(fù)雜欢唾,需要消耗很多的硬件資源或者數(shù)據(jù)資源粉捻,就像引言中說的“我”礁遣,是經(jīng)過20多年的實(shí)例化,消耗了大量的糧食才構(gòu)造成功的祟霍。

原型模式(Prototype Pattern):當(dāng)創(chuàng)建給定類的實(shí)例化過程很復(fù)雜或者代價(jià)很昂貴時(shí)盈包,可以使用原型實(shí)例指定創(chuàng)建對象的種類沸呐,并且通過拷貝這些原型創(chuàng)建新的對象。原型模式是一種對象創(chuàng)建型模式呢燥。

原型模式的工作原理很簡單:將一個(gè)原型對象傳給那個(gè)要發(fā)動(dòng)創(chuàng)建的對象,這個(gè)要發(fā)動(dòng)創(chuàng)建的對象通過請求原型對象拷貝自己來實(shí)現(xiàn)創(chuàng)建過程滥朱,拷貝通常是通過克隆方法實(shí)現(xiàn)力试。原型模式是一種“另類”的創(chuàng)建型模式,創(chuàng)建克隆對象的工廠就是原型類自身缰犁,工廠方法由克隆方法來實(shí)現(xiàn)怖糊。

三伍伤、淺克隆和深克隆

需要注意的是克隆有深克隆和淺克隆之分。

淺克侣笃颉: 在淺克隆中,如果原型對象的成員變量是值類型倦淀,將復(fù)制一份給克隆對象声畏;如果原型對象的成員變量是引用類型插龄,則將引用對象的地址復(fù)制一份給克隆對象,也就是說原型對象和克隆對象的成員變量指向相同的內(nèi)存地址初斑。簡單來說膨处,在淺克隆中真椿,當(dāng)對象被復(fù)制時(shí)只復(fù)制它本身和其中包含的值類型的成員變量乎澄,而引用類型的成員對象并沒有復(fù)制。

深克陆馇 : 在深克隆中护盈,無論原型對象的成員變量是值類型還是引用類型羞酗,都將復(fù)制一份給克隆對象檀轨,深克隆將原型對象的所有引用對象也復(fù)制一份給克隆對象。簡單來說卫枝,在深克隆中讹挎,除了對象本身被復(fù)制外,對象所包含的所有成員變量也將復(fù)制衰伯。

四积蔚、clone()

4.1尽爆、clone()方法理解

clone()方法是Object中的一個(gè)方法,其源代碼如下:

protected native Object clone() throws CloneNotSupportedException;

可以發(fā)現(xiàn):

  • 第一:Object類的clone()方法是一個(gè)native方法槐雾,native方法的效率一般來說都是遠(yuǎn)高于Java中的非native方法幅狮。這也解釋了為什么要用Object中clone()方法而不是先new一個(gè)類崇摄,然后把原始對象中的信息復(fù)制到新對象中,雖然這也實(shí)現(xiàn)了clone功能鸠儿。

JNI是Java Native Interface的 縮寫进每。從Java 1.1開始命斧,Java Native Interface(JNI)標(biāo)準(zhǔn)成為java平臺的一部分冯丙,它允許Java代碼和其他語言寫的代碼進(jìn)行交互。JNI一開始是為了本地已編譯語言泞莉,尤其是C和C++而設(shè)計(jì)的鲫趁,但是它并不妨礙你使用其他語言利虫,只要調(diào)用約定受支持就可以了。使用java與本地已編譯的代碼交互疫剃,通常會喪失平臺可移植性巢价。但是,有些情況下這樣做是可以接受的城菊,甚至是必須的凌唬,比如漏麦,使用一些舊的庫撕贞,與硬件、操作系統(tǒng)進(jìn)行交互,或者為了提高程序的性能脊奋。JNI標(biāo)準(zhǔn)至少保證本地代碼能工作在任何Java虛擬機(jī)實(shí)現(xiàn)下疙描。

  • 第二:Object類中的clone()方法被protected修飾符修飾起胰。這也意味著如果要應(yīng)用clone()方法效五,必須繼承Object類,在Java中所有的類是缺省繼承Object類的脉执,也就不用關(guān)心這點(diǎn)了戒劫。然后重載clone()方法。還有一點(diǎn)要考慮的是為了讓其它類能調(diào)用這個(gè)clone類的clone()方法淘邻,重載之后要把clone()方法的屬性設(shè)置為 public湘换。
  • 第三:Object.clone()方法返回一個(gè)Object對象枚尼。必須進(jìn)行強(qiáng)制類型轉(zhuǎn)換才能得到需要的類型署恍。

4.2、Java中對象的克隆

一般需要四個(gè)步驟:

  1. 在子類中實(shí)現(xiàn)Cloneable接口袁串。
  2. 為了獲取對象的一份拷貝呼巷,我們可以利用Object類的clone方法王悍。
  3. 在子類中覆蓋clone方法压储,聲明為public。
  4. 在子類的clone方法中孕似,調(diào)用super.clone()刮刑。

Cloneable接口僅僅是一個(gè)標(biāo)志接口雷绢,而且這個(gè)標(biāo)志也僅僅是針對Object類中 clone()方法的习寸,如果clone類沒有實(shí)現(xiàn)Cloneable接口,并調(diào)用了Object的clone()方法(也就是調(diào)用了super.Clone()方法)孵滞,那么Object的clone()方法就會拋出 CloneNotSupportedException 異常坊饶。

4.3、淺克隆實(shí)例

public class Student implements Cloneable{

    private String name;

    private int age;

    private Professor professor;

    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;
    }

    public Professor getProfessor() {
        return professor;
    }

    public void setProfessor(Professor professor) {
        this.professor = professor;
    }

    @Override
    public String toString() {
        return "Student [name=" + name + ", age=" + age + ", professor="
                + professor + "]";
    }

    public Object clone() throws CloneNotSupportedException{
        return super.clone();
    }
}

public class Professor {

    private String name;

    private int 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;
    }

    @Override
    public String toString() {
        return "Professor [name=" + name + ", age=" + age + "]";
    }

}

public class ShadowCopy {

    public static void main(String[] args) {
        Professor p1 = new Professor();
        p1.setName("Professor Zhang");
        p1.setAge(30);

        Student s1 = new Student();
        s1.setName("xiao ming");
        s1.setAge(18);
        s1.setProfessor(p1);

        System.out.println(s1);

        try {
            Student s2 = (Student) s1.clone();
            Professor p2 = s2.getProfessor();
            p2.setName("Professor Li");
            p2.setAge(45);
            s2.setProfessor(p2);
            System.out.println("復(fù)制后的:s1 = " + s1);
            System.out.println("復(fù)制后的:s2 = " + s2);
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }

    }

}

測試結(jié)果會發(fā)現(xiàn)復(fù)制后打印出來的s1和s2結(jié)果是一樣的痘绎,s1和s2的導(dǎo)師都變成了45歲的Professor Li,顯然這并不是期望的結(jié)果尔苦,產(chǎn)生這個(gè)結(jié)果的原因lone()方法實(shí)現(xiàn)的是淺克隆允坚,對象引用professor只是復(fù)制了其引用蛾号,s1和s2仍是指向相同的地址塊鲜结。

4.4、深克隆實(shí)例

實(shí)現(xiàn)深克隆乐疆,可以在原clone()方法基礎(chǔ)上改進(jìn)一下,如下:

public class Student implements Cloneable{

    private String name;
    private int age;
    private Professor professor;

    public Student(String name, int age, Professor professor){
        this.name = name;
        this.age = age;
        this.professor = professor;
    }

    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;
    }

    public Professor getProfessor() {
        return professor;
    }

    public void setProfessor(Professor professor) {
        this.professor = professor;
    }

    public Object clone(){
        Student o = null;
        try {
            o = (Student)super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        o.professor = (Professor)professor.clone();
        return o;
    }

    @Override
    public String toString() {
        return "Student [name=" + name + ", age=" + age + ", professor="
                + professor + "]";
    }

}

public class Professor implements Cloneable{

    private String name;
    private int age;

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

    @Override
    public Object clone(){
        Object o = name;
        try {
            o= super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return o;
    }

    @Override
    public String toString() {
        return "Professor [name=" + name + ", age=" + age + "]";
    }

}

public class DeepClone {
    public static void main(String[] args) {
        Professor p=new Professor("wangwu",50);
        Student s1=new Student("zhangsan",18, p);
        System.out.println(s1);

        Student s2=(Student)s1.clone();
        s2.getProfessor().setName("maer");
        s2.getProfessor().setAge(40);
        System.out.println("復(fù)制后的:s1 = " + s1);
        System.out.println("復(fù)制后的:s2 = " + s2);
    }
}

也可以利用序列化反序列化來實(shí)現(xiàn)深克隆:

public class Student implements Serializable {

    private String name;
    private int age;
    private Professor professor;

    public Student(String name, int age, Professor professor){
        this.name = name;
        this.age = age;
        this.professor = professor;
    }

    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;
    }

    public Professor getProfessor() {
        return professor;
    }

    public void setProfessor(Professor professor) {
        this.professor = professor;
    }

    public Object deepClone() throws IOException, ClassNotFoundException {
        //將對象寫到流中
        ByteArrayOutputStream bo=new ByteArrayOutputStream();
        ObjectOutputStream oo=new ObjectOutputStream(bo);
        oo.writeObject(this);
        //從流中讀出來
        ByteArrayInputStream bi=new ByteArrayInputStream(bo.toByteArray());
        ObjectInputStream oi=new ObjectInputStream(bi);
        return oi.readObject();
    }

    @Override
    public String toString() {
        return "Student [name=" + name + ", age=" + age + ", professor="
                + professor + "]";
    }

}

public class Professor implements Serializable {

    private String name;
    private int age;

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

    @Override
    public String toString() {
        return "Professor [name=" + name + ", age=" + age + "]";
    }

}

public class DeepClone {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        Professor p=new Professor("wangwu",50);
        Student s1=new Student("zhangsan",18, p);
        System.out.println(s1);

        Student s2=(Student)s1.deepClone();
        s2.getProfessor().setName("maer");
        s2.getProfessor().setAge(40);
        System.out.println("復(fù)制后的:s1 = " + s1);
        System.out.println("復(fù)制后的:s2 = " + s2);
    }
}

五儿礼、模式的結(jié)構(gòu)

介紹完淺克隆和深克隆蚊夫,再回到原型模式上懦尝。

原型模式的UML類圖如下:

image

在原型模式結(jié)構(gòu)圖中包含如下幾個(gè)角色:

  • Prototype(抽象原型類):它是聲明克隆方法的接口,是所有具體原型類的公共父類伍绳,可以是抽象類也可以是接口冲杀,甚至還可以是具體實(shí)現(xiàn)類睹酌。
  • ConcretePrototype(具體原型類):它實(shí)現(xiàn)在抽象原型類中聲明的克隆方法憋沿,在克隆方法中返回自己的一個(gè)克隆對象。
  • Client(客戶類):讓一個(gè)原型對象克隆自身從而創(chuàng)建一個(gè)新的對象甥绿,在客戶類中只需要直接實(shí)例化或通過工廠方法等方式創(chuàng)建一個(gè)原型對象共缕,再通過調(diào)用該對象的克隆方法即可得到多個(gè)相同的對象士复。由于客戶類針對抽象原型類Prototype編程阱洪,因此用戶可以根據(jù)需要選擇具體原型類,系統(tǒng)具有較好的可擴(kuò)展性承璃,增加或更換具體原型類都很方便盔粹。

六程癌、典型代碼

public interface Prototype {
    Prototype clone();
    void setAttr(String attr);
}

public class ConcretePrototype implements Prototype {
    private String attr; //成員屬性

    public void setAttr(String attr) {
        this.attr = attr;
    }

    public String getAttr() {
        return this.attr;
    }

    public Prototype clone() {
        Prototype prototype = new ConcretePrototype(); //創(chuàng)建新對象
        prototype.setAttr(this.attr);
        return prototype;
        /*Object object = null;
        try {
            object = super.clone();
        } catch (CloneNotSupportedException exception) {
            System.err.println("Not support cloneable");
        }
        return (Prototype) object;*/
    }
}

clone()方法是不能直接返回this的嵌莉,相信都明白。

七可婶、代碼示例

看過仙俠小說的都知道兜蠕,修煉到高境界(肯定不是練氣熊杨,金丹的渣渣了),就可以煉制身外化身桂躏,這些化身都有自己的思想剂习,可以修煉自己的功法较沪,但卻聽從主體的命令尸曼,當(dāng)然有時(shí)候化身也會叛變,這里就以仙人化身為例:

public class Immortal implements Serializable {
    private String name;
    private int age;
    private String magicalPower;//神通
    private Wife wife;//道侶

    public Immortal(String name, int age, String magicalPower) {
        try {
            Thread.sleep(4000);//模擬仙人修煉
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        this.name = name;
        this.age = age;
        this.magicalPower = magicalPower;
    }

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

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

    public void setMagicalPower(String magicalPower) {
        this.magicalPower = magicalPower;
    }

    public void setWife(Wife wife) {
        this.wife = wife;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public String getMagicalPower() {
        return magicalPower;
    }

    public Wife getWife() {
        return wife;
    }

    //使用序列化實(shí)現(xiàn)深克隆
    public Immortal deepClone() throws IOException, ClassNotFoundException {
        //將對象寫入流中
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(this);

        //將對象從流中取出
        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bis);
        return (Immortal) ois.readObject();
    }

    public String toString() {
        return "仙人 [姓名=" + name + ", 年齡=" + age + ", 神通="
                + magicalPower + ",道侶=" + wife.getName() + "]";
    }
}

public class Wife implements Serializable{
    private String name;
    private int age;

    public Wife(String name, int age){
        this.name = name;
        this.age = age;
    }

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

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

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public String toString(){
        return "道侶 [姓名=" + name + ", 年齡=" + age + "]";
    }
}

public class Client {
    public static void main(String[] args) {
        Wife yushiqie = new Wife("雨師妾", 3000);
        Immortal immortal = new Immortal("拓拔野", 2985, "天元訣茬射,剎那芳華");
        immortal.setWife(yushiqie);
        System.out.println(immortal);

        try {
            //故事最后拓跋陪我最愛的雨師妾?dú)w隱在抛,但姑射仙子卻沒了歸宿,這里假設(shè)拓跋分出一個(gè)分身
            Immortal incarnation = immortal.deepClone();
            Wife guyexianzi = incarnation.getWife();
            System.out.println(immortal.getWife() == incarnation.getWife()); //false
            guyexianzi.setName("姑射仙子");
            guyexianzi.setAge(2985);
            System.out.println(incarnation);
            incarnation.setWife(guyexianzi);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

八档悠、優(yōu)點(diǎn)和缺點(diǎn)

8.1、優(yōu)點(diǎn)

原型模式的主要優(yōu)點(diǎn)如下:

  • 當(dāng)創(chuàng)建新的對象實(shí)例較為復(fù)雜時(shí)磨德,使用原型模式可以簡化對象的創(chuàng)建過程典挑,通過復(fù)制一個(gè)已有實(shí)例可以提高新實(shí)例的創(chuàng)建效率。
  • 擴(kuò)展性較好拙寡,由于在原型模式中提供了抽象原型類琳水,在客戶端可以針對抽象原型類進(jìn)行編程在孝,而將具體原型類寫在配置文件中,增加或減少產(chǎn)品類對原有系統(tǒng)都沒有任何影響始赎。
  • 原型模式提供了簡化的創(chuàng)建結(jié)構(gòu)造垛,工廠方法模式常常需要有一個(gè)與產(chǎn)品類等級結(jié)構(gòu)相同的工廠等級結(jié)構(gòu)五辽,而原型模式就不需要這樣厕隧,原型模式中產(chǎn)品的復(fù)制是通過封裝在原型類中的克隆方法實(shí)現(xiàn)的吁讨,無須專門的工廠類來創(chuàng)建產(chǎn)品。
  • 可以使用深克隆的方式保存對象的狀態(tài)排龄,使用原型模式將對象復(fù)制一份并將其狀態(tài)保存起來橄维,以便在需要的時(shí)候使用(如恢復(fù)到某一歷史狀態(tài))争舞,可輔助實(shí)現(xiàn)撤銷操作澈灼。

8.2、缺點(diǎn)

原型模式的主要缺點(diǎn)如下:

  • 需要為每一個(gè)類配備一個(gè)克隆方法床牧,而且該克隆方法位于一個(gè)類的內(nèi)部遭贸,當(dāng)對已有的類進(jìn)行改造時(shí)壕吹,需要修改源代碼算利,違背了“開閉原則”。
  • 在實(shí)現(xiàn)深克隆時(shí)需要編寫較為復(fù)雜的代碼暂吉,而且當(dāng)對象之間存在多重的嵌套引用時(shí)慕的,為了實(shí)現(xiàn)深克隆肮街,每一層對象對應(yīng)的類都必須支持深克隆判导,實(shí)現(xiàn)起來可能會比較麻煩。

九绕辖、適用環(huán)境

在以下情況下可以考慮使用原型模式:

  • 創(chuàng)建新對象成本較大(如初始化需要占用較長的時(shí)間仪际,占用太多的CPU資源或網(wǎng)絡(luò)資源)树碱,新的對象可以通過原型模式對已有對象進(jìn)行復(fù)制來獲得变秦,如果是相似對象蹦玫,則可以對其成員變量稍作修改。
  • 一個(gè)對象需要提供給其他對象訪問,而且各個(gè)調(diào)用者可能都需要修改其值時(shí)歧焦,可以考慮使用原型模式拷貝多個(gè)對象供調(diào)用者使用,即保護(hù)性拷貝肚医。
  • 需要避免使用分層次的工廠類來創(chuàng)建分層次的對象绢馍,并且類的實(shí)例對象只有一個(gè)或很少的幾個(gè)組合狀態(tài),通過復(fù)制原型對象得到新實(shí)例可能比使用構(gòu)造函數(shù)創(chuàng)建一個(gè)新實(shí)例更加方便肠套。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末舰涌,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子你稚,更是在濱河造成了極大的恐慌瓷耙,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件刁赖,死亡現(xiàn)場離奇詭異,居然都是意外死亡宇弛,警方通過查閱死者的電腦和手機(jī)鸡典,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來枪芒,“玉大人彻况,你說我怎么就攤上這事【俗伲” “怎么了纽甘?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長硫朦。 經(jīng)常有香客問我贷腕,道長,這世上最難降的妖魔是什么咬展? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任泽裳,我火速辦了婚禮,結(jié)果婚禮上破婆,老公的妹妹穿的比我還像新娘涮总。我一直安慰自己,他們只是感情好祷舀,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布瀑梗。 她就那樣靜靜地躺著烹笔,像睡著了一般。 火紅的嫁衣襯著肌膚如雪抛丽。 梳的紋絲不亂的頭發(fā)上谤职,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天,我揣著相機(jī)與錄音亿鲜,去河邊找鬼允蜈。 笑死,一個(gè)胖子當(dāng)著我的面吹牛蒿柳,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播妓蛮,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼蛤克,長吁一口氣:“原來是場噩夢啊……” “哼咖耘!你這毒婦竟也來了儿倒?” 一聲冷哼從身側(cè)響起呜笑,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤叫胁,失蹤者是張志新(化名)和其女友劉穎驼鹅,沒想到半個(gè)月后输钩,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年肴焊,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了娶眷。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片届宠。...
    茶點(diǎn)故事閱讀 38,622評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡席揽,死狀恐怖谓厘,靈堂內(nèi)的尸體忽然破棺而出竟稳,到底是詐尸還是另有隱情他爸,我是刑警寧澤诊笤,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布讨跟,位于F島的核電站晾匠,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏薪寓。R本人自食惡果不足惜向叉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一植康、第九天 我趴在偏房一處隱蔽的房頂上張望销睁。 院中可真熱鬧,春花似錦睡毒、人聲如沸冗栗。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽涕蚤。三九已至万栅,卻和暖如春烦粒,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背邮偎。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工禾进, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留泻云,地道東北人宠纯。 一個(gè)月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓层释,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子丑念,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評論 2 348

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