設(shè)計(jì)模式 - 結(jié)構(gòu)性模式 代理 適配器 橋接 裝飾 外觀 享元 組合

設(shè)計(jì)模式-面相對象5個(gè)原則
設(shè)計(jì)模式-創(chuàng)造性模式 單例 原型 工廠 建造者
設(shè)計(jì)模式-設(shè)計(jì)模式 - 結(jié)構(gòu)性模式 代理 適配器 橋接 裝飾 外觀 享元 組合
設(shè)計(jì)模式-行為性模式

采用自出處http://c.biancheng.net/view/1326.html
結(jié)構(gòu)型模式描述如何將類或?qū)ο蟀茨撤N布局組成更大的結(jié)構(gòu)蜗巧。它分為類結(jié)構(gòu)型模式和對象結(jié)構(gòu)型模式吓蘑,前者采用繼承機(jī)制來組織接口和類,后者釆用組合或聚合來組合對象单绑。
由于組合關(guān)系或聚合關(guān)系比繼承關(guān)系耦合度低电抚,滿足“合成復(fù)用原則”句喷,所以對象結(jié)構(gòu)型模式比類結(jié)構(gòu)型模式具有更大的靈活性监憎。
結(jié)構(gòu)型模式分為以下 7 種:
代理(Proxy)模式:為某對象提供一種代理以控制對該對象的訪問膳叨。即客戶端通過代理間接地訪問該對象,從而限制跌穗、增強(qiáng)或修改該對象的一些特性订晌。
適配器(Adapter)模式:將一個(gè)類的接口轉(zhuǎn)換成客戶希望的另外一個(gè)接口,使得原本由于接口不兼容而不能一起工作的那些類能一起工作蚌吸。
橋接(Bridge)模式:將抽象與實(shí)現(xiàn)分離锈拨,使它們可以獨(dú)立變化。它是用組合關(guān)系代替繼承關(guān)系來實(shí)現(xiàn)的羹唠,從而降低了抽象和實(shí)現(xiàn)這兩個(gè)可變維度的耦合度奕枢。
裝飾(Decorator)模式:動(dòng)態(tài)地給對象增加一些職責(zé),即增加其額外的功能佩微。
外觀(Facade)模式:為多個(gè)復(fù)雜的子系統(tǒng)提供一個(gè)一致的接口缝彬,使這些子系統(tǒng)更加容易被訪問侮攀。
享元(Flyweight)模式:運(yùn)用共享技術(shù)來有效地支持大量細(xì)粒度對象的復(fù)用丑掺。
組合(Composite)模式:將對象組合成樹狀層次結(jié)構(gòu),使用戶對單個(gè)對象和組合對象具有一致的訪問性局雄。

代理模式

在有些情況下奶卓,一個(gè)客戶不能或者不想直接訪問另一個(gè)對象一疯,這時(shí)需要找一個(gè)中介幫忙完成某項(xiàng)任務(wù),這個(gè)中介就是代理對象夺姑。例如墩邀,購買火車票不一定要去火車站買,可以通過 12306 網(wǎng)站或者去火車票代售點(diǎn)買殖卑。又如找女朋友许起、找保姆惦积、找工作等都可以通過找中介完成。

在軟件設(shè)計(jì)中,使用代理模式的例子也很多狱窘,例如膘滨,要訪問的遠(yuǎn)程對象比較大(如視頻或大圖像等)纤勒,其下載要花很多時(shí)間。還有因?yàn)榘踩蛐枰帘慰蛻舳酥苯釉L問真實(shí)對象司训,如某單位的內(nèi)部數(shù)據(jù)庫等勾徽。

代理模式的定義與特點(diǎn)

代理模式的定義:由于某些原因需要給某對象提供一個(gè)代理以控制對該對象的訪問。這時(shí)统扳,訪問對象不適合或者不能直接引用目標(biāo)對象喘帚,代理對象作為訪問對象和目標(biāo)對象之間的中介。

代理模式的主要優(yōu)點(diǎn)有:

  • 代理模式在客戶端與目標(biāo)對象之間起到一個(gè)中介作用和保護(hù)目標(biāo)對象的作用咒钟;
  • 代理對象可以擴(kuò)展目標(biāo)對象的功能吹由;
  • 代理模式能將客戶端與目標(biāo)對象分離,在一定程度上降低了系統(tǒng)的耦合度朱嘴;

其主要缺點(diǎn)是:

  • 在客戶端和目標(biāo)對象之間增加一個(gè)代理對象倾鲫,會(huì)造成請求處理速度變慢;
  • 增加了系統(tǒng)的復(fù)雜度萍嬉;

代理模式的結(jié)構(gòu)與實(shí)現(xiàn)

代理模式的結(jié)構(gòu)比較簡單乌昔,主要是通過定義一個(gè)繼承抽象主題的代理來包含真實(shí)主題,從而實(shí)現(xiàn)對真實(shí)主題的訪問壤追,下面來分析其基本結(jié)構(gòu)和實(shí)現(xiàn)方法磕道。

1. 模式的結(jié)構(gòu)

代理模式的主要角色如下。

  1. 抽象主題(Subject)類:通過接口或抽象類聲明真實(shí)主題和代理對象實(shí)現(xiàn)的業(yè)務(wù)方法行冰。
  2. 真實(shí)主題(Real Subject)類:實(shí)現(xiàn)了抽象主題中的具體業(yè)務(wù)溺蕉,是代理對象所代表的真實(shí)對象,是最終要引用的對象悼做。
  3. 代理(Proxy)類:提供了與真實(shí)主題相同的接口疯特,其內(nèi)部含有對真實(shí)主題的引用,它可以訪問贿堰、控制或擴(kuò)展真實(shí)主題的功能辙芍。

其結(jié)構(gòu)圖如圖 1 所示。

代理模式的結(jié)構(gòu)圖

圖1 代理模式的結(jié)構(gòu)圖

代理模式的應(yīng)用實(shí)例

【例1】韶關(guān)“天街e角”公司是一家婺源特產(chǎn)公司的代理公司,用代理模式實(shí)現(xiàn)故硅。

分析:本實(shí)例中的“婺源特產(chǎn)公司”經(jīng)營許多婺源特產(chǎn)庶灿,它是真實(shí)主題,提供了顯示特產(chǎn)的 display() 方法吃衅,可以用窗體程序?qū)崿F(xiàn)(點(diǎn)此下載該實(shí)例所要顯示的圖片)往踢。而韶關(guān)“天街e角”公司是婺源特產(chǎn)公司特產(chǎn)的代理,通過調(diào)用婺源特產(chǎn)公司的 display() 方法顯示代理產(chǎn)品徘层,當(dāng)然它可以增加一些額外的處理峻呕,如包裝或加價(jià)等∪ばВ客戶可通過“天街e角”代理公司間接訪問“婺源特產(chǎn)公司”的產(chǎn)品瘦癌,圖 2 所示是公司的結(jié)構(gòu)圖。

韶關(guān)“天街e角”公園的結(jié)構(gòu)圖

以下是我寫的例子跷敬,android動(dòng)態(tài)代理的讯私,銀行接口任務(wù)

/**
 * 銀行辦理業(yè)務(wù) - 目標(biāo)接口(業(yè)務(wù))
 * Created by hcDarren on 2017/10/15.
 */

public interface IBank {
    /**
     * 申請辦卡
     */
    public void applyBank();

    /**
     * 掛失
     */
    public void lostBank();

    /**
     * 額外業(yè)務(wù)
     */
    public void extraBank();
}
/**
 * Created by hcDarren on 2017/10/15.
 * 銀行辦理業(yè)務(wù) - 被代理的對象 - 我們
 */
public class Man implements IBank {
    private String name;

    public Man(String name){
        this.name = name;
    }

    /**
     * 自己的一些操作
     */
    @Override
    public void applyBank() {
        System.out.println(name + " 申請辦卡");
    }

    @Override
    public void lostBank() {
        System.out.println(name + " 申請掛失");
    }

    @Override
    public void extraBank() {
        System.out.println(name + " 額外業(yè)務(wù)");
    }
}
/**
 * Created by hcDarren on 2017/10/15.
 * 銀行辦理業(yè)務(wù) - 動(dòng)態(tài)代理 - InvocationHandler
 */

public class BankInvocationHandler implements InvocationHandler{
    /**
     * 被代理的對象
     */
    private Object mObject;

    public BankInvocationHandler(Object object){
        this.mObject = object;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 執(zhí)行方法 ,目標(biāo)接口調(diào)用的方法都會(huì)來到這里面
        // System.out.println("methodName = "+method.getName());
        System.out.println("開始受理");
        // System.out.println("params = "+args.toString());
        // 調(diào)用被代理對象的方法,這里其實(shí)調(diào)用的就是  man 里面的 applyBank 方法
        Object voidObject = method.invoke(mObject,args);
        System.out.println("操作完畢");
        return voidObject;
    }
}
    public static void main(String[] args) {
        Man man = new Man("Yueying");

        IBank bank =
                // 返回的是 IBank 的一個(gè)實(shí)例對象西傀,這個(gè)對象是由 Java 給我們創(chuàng)建的 ,調(diào)用的是 jni
                (IBank) Proxy.newProxyInstance(
                        IBank.class.getClassLoader(), // ClassLoader
                        new Class<?>[]{IBank.class}, // 目標(biāo)接口
                        new BankInvocationHandler(man) // InvocationHandler (這個(gè)類是關(guān)鍵)
                );
        // 當(dāng)調(diào)用這個(gè)方法的時(shí)候會(huì)來到 BankInvocationHandler 的 invoke 方法
        bank.applyBank();

        bank.lostBank();

        bank.extraBank();
    }

適配器模式

在現(xiàn)實(shí)生活中斤寇,經(jīng)常出現(xiàn)兩個(gè)對象因接口不兼容而不能在一起工作的實(shí)例,這時(shí)需要第三者進(jìn)行適配拥褂。例如娘锁,講中文的人同講英文的人對話時(shí)需要一個(gè)翻譯,用直流電的筆記本電腦接交流電源時(shí)需要一個(gè)電源適配器饺鹃,用計(jì)算機(jī)訪問照相機(jī)的 SD 內(nèi)存卡時(shí)需要一個(gè)讀卡器等莫秆。

在軟件設(shè)計(jì)中也可能出現(xiàn):需要開發(fā)的具有某種業(yè)務(wù)功能的組件在現(xiàn)有的組件庫中已經(jīng)存在,但它們與當(dāng)前系統(tǒng)的接口規(guī)范不兼容悔详,如果重新開發(fā)這些組件成本又很高馏锡,這時(shí)用適配器模式能很好地解決這些問題。

模式的定義與特點(diǎn)

適配器模式(Adapter)的定義如下:將一個(gè)類的接口轉(zhuǎn)換成客戶希望的另外一個(gè)接口伟端,使得原本由于接口不兼容而不能一起工作的那些類能一起工作。適配器模式分為類結(jié)構(gòu)型模式和對象結(jié)構(gòu)型模式兩種匪煌,前者類之間的耦合度比后者高责蝠,且要求程序員了解現(xiàn)有組件庫中的相關(guān)組件的內(nèi)部結(jié)構(gòu),所以應(yīng)用相對較少些萎庭。

該模式的主要優(yōu)點(diǎn)如下霜医。

  • 客戶端通過適配器可以透明地調(diào)用目標(biāo)接口。
  • 復(fù)用了現(xiàn)存的類驳规,程序員不需要修改原有代碼而重用現(xiàn)有的適配者類肴敛。
  • 將目標(biāo)類和適配者類解耦,解決了目標(biāo)類和適配者類接口不一致的問題。

其缺點(diǎn)是:對類適配器來說医男,更換適配器的實(shí)現(xiàn)過程比較復(fù)雜砸狞。

模式的結(jié)構(gòu)與實(shí)現(xiàn)

類適配器模式可采用多重繼承方式實(shí)現(xiàn),如 C++ 可定義一個(gè)適配器類來同時(shí)繼承當(dāng)前系統(tǒng)的業(yè)務(wù)接口和現(xiàn)有組件庫中已經(jīng)存在的組件接口镀梭;Java 不支持多繼承刀森,但可以定義一個(gè)適配器類來實(shí)現(xiàn)當(dāng)前系統(tǒng)的業(yè)務(wù)接口,同時(shí)又繼承現(xiàn)有組件庫中已經(jīng)存在的組件报账。

對象適配器模式可釆用將現(xiàn)有組件庫中已經(jīng)實(shí)現(xiàn)的組件引入適配器類中研底,該類同時(shí)實(shí)現(xiàn)當(dāng)前系統(tǒng)的業(yè)務(wù)接口。現(xiàn)在來介紹它們的基本結(jié)構(gòu)透罢。

1. 模式的結(jié)構(gòu)

適配器模式(Adapter)包含以下主要角色榜晦。

  1. 目標(biāo)(Target)接口:當(dāng)前系統(tǒng)業(yè)務(wù)所期待的接口,它可以是抽象類或接口羽圃。
  2. 適配者(Adaptee)類:它是被訪問和適配的現(xiàn)存組件庫中的組件接口乾胶。
  3. 適配器(Adapter)類:它是一個(gè)轉(zhuǎn)換器,通過繼承或引用適配者的對象统屈,把適配者接口轉(zhuǎn)換成目標(biāo)接口胚吁,讓客戶按目標(biāo)接口的格式訪問適配者。

類適配器模式的結(jié)構(gòu)圖如圖 1 所示愁憔。

類適配器模式的結(jié)構(gòu)圖

圖1 類適配器模式的結(jié)構(gòu)圖

對象適配器模式的結(jié)構(gòu)圖如圖 2 所示腕扶。

對象適配器模式的結(jié)構(gòu)圖

橋接模式

在現(xiàn)實(shí)生活中,某些類具有兩個(gè)或多個(gè)維度的變化吨掌,如圖形既可按形狀分半抱,又可按顏色分。如何設(shè)計(jì)類似于 Photoshop 這樣的軟件膜宋,能畫不同形狀和不同顏色的圖形呢窿侈?如果用繼承方式,m 種形狀和 n 種顏色的圖形就有 m×n 種秋茫,不但對應(yīng)的子類很多史简,而且擴(kuò)展困難。

當(dāng)然肛著,這樣的例子還有很多圆兵,如不同顏色和字體的文字、不同品牌和功率的汽車枢贿、不同性別和職業(yè)的男女殉农、支持不同平臺和不同文件格式的媒體播放器等。如果用橋接模式就能很好地解決這些問題局荚。

橋接模式的定義與特點(diǎn)

橋接(Bridge)模式的定義如下:將抽象與實(shí)現(xiàn)分離超凳,使它們可以獨(dú)立變化愈污。它是用組合關(guān)系代替繼承關(guān)系來實(shí)現(xiàn),從而降低了抽象和實(shí)現(xiàn)這兩個(gè)可變維度的耦合度轮傍。

橋接(Bridge)模式的優(yōu)點(diǎn)是:

  • 由于抽象與實(shí)現(xiàn)分離暂雹,所以擴(kuò)展能力強(qiáng);
  • 其實(shí)現(xiàn)細(xì)節(jié)對客戶透明金麸。

缺點(diǎn)是:由于聚合關(guān)系建立在抽象層擎析,要求開發(fā)者針對抽象化進(jìn)行設(shè)計(jì)與編程,這增加了系統(tǒng)的理解與設(shè)計(jì)難度挥下。

橋接模式的結(jié)構(gòu)與實(shí)現(xiàn)

可以將抽象化部分與實(shí)現(xiàn)化部分分開揍魂,取消二者的繼承關(guān)系,改用組合關(guān)系棚瘟。

1. 模式的結(jié)構(gòu)

橋接(Bridge)模式包含以下主要角色现斋。

  1. 抽象化(Abstraction)角色:定義抽象類,并包含一個(gè)對實(shí)現(xiàn)化對象的引用偎蘸。
  2. 擴(kuò)展抽象化(Refined Abstraction)角色:是抽象化角色的子類庄蹋,實(shí)現(xiàn)父類中的業(yè)務(wù)方法,并通過組合關(guān)系調(diào)用實(shí)現(xiàn)化角色中的業(yè)務(wù)方法迷雪。
  3. 實(shí)現(xiàn)化(Implementor)角色:定義實(shí)現(xiàn)化角色的接口限书,供擴(kuò)展抽象化角色調(diào)用。
  4. 具體實(shí)現(xiàn)化(Concrete Implementor)角色:給出實(shí)現(xiàn)化角色接口的具體實(shí)現(xiàn)章咧。

其結(jié)構(gòu)圖如圖 1 所示倦西。

橋接模式的結(jié)構(gòu)圖

裝飾設(shè)計(jì)模式

在現(xiàn)實(shí)生活中,常常需要對現(xiàn)有產(chǎn)品增加新的功能或美化其外觀赁严,如房子裝修扰柠、相片加相框等。在軟件開發(fā)過程中疼约,有時(shí)想用一些現(xiàn)存的組件卤档。這些組件可能只是完成了一些核心功能。但在不改變其結(jié)構(gòu)的情況下程剥,可以動(dòng)態(tài)地?cái)U(kuò)展其功能劝枣。所有這些都可以釆用裝飾模式來實(shí)現(xiàn)。

裝飾模式的定義與特點(diǎn)

裝飾(Decorator)模式的定義:指在不改變現(xiàn)有對象結(jié)構(gòu)的情況下织鲸,動(dòng)態(tài)地給該對象增加一些職責(zé)(即增加其額外功能)的模式哨免,它屬于對象結(jié)構(gòu)型模式。

裝飾(Decorator)模式的主要優(yōu)點(diǎn)有:

  • 采用裝飾模式擴(kuò)展對象的功能比采用繼承方式更加靈活昙沦。
  • 可以設(shè)計(jì)出多個(gè)不同的具體裝飾類,創(chuàng)造出多個(gè)不同行為的組合载荔。

其主要缺點(diǎn)是:裝飾模式增加了許多子類盾饮,如果過度使用會(huì)使程序變得很復(fù)雜。

裝飾模式的結(jié)構(gòu)與實(shí)現(xiàn)

通常情況下,擴(kuò)展一個(gè)類的功能會(huì)使用繼承方式來實(shí)現(xiàn)丘损。但繼承具有靜態(tài)特征普办,耦合度高,并且隨著擴(kuò)展功能的增多徘钥,子類會(huì)很膨脹衔蹲。如果使用組合關(guān)系來創(chuàng)建一個(gè)包裝對象(即裝飾對象)來包裹真實(shí)對象,并在保持真實(shí)對象的類結(jié)構(gòu)不變的前提下呈础,為其提供額外的功能舆驶,這就是裝飾模式的目標(biāo)。下面來分析其基本結(jié)構(gòu)和實(shí)現(xiàn)方法而钞。

1. 模式的結(jié)構(gòu)

裝飾模式主要包含以下角色沙廉。

  1. 抽象構(gòu)件(Component)角色:定義一個(gè)抽象接口以規(guī)范準(zhǔn)備接收附加責(zé)任的對象。
  2. 具體構(gòu)件(Concrete Component)角色:實(shí)現(xiàn)抽象構(gòu)件臼节,通過裝飾角色為其添加一些職責(zé)撬陵。
  3. 抽象裝飾(Decorator)角色:繼承抽象構(gòu)件,并包含具體構(gòu)件的實(shí)例网缝,可以通過其子類擴(kuò)展具體構(gòu)件的功能巨税。
  4. 具體裝飾(ConcreteDecorator)角色:實(shí)現(xiàn)抽象裝飾的相關(guān)方法,并給具體構(gòu)件對象添加附加的責(zé)任粉臊。

裝飾模式的結(jié)構(gòu)圖如圖 1 所示草添。

裝飾模式的結(jié)構(gòu)圖

外觀模式

在現(xiàn)實(shí)生活中,常常存在辦事較復(fù)雜的例子维费,如辦房產(chǎn)證或注冊一家公司果元,有時(shí)要同多個(gè)部門聯(lián)系,這時(shí)要是有一個(gè)綜合部門能解決一切手續(xù)問題就好了犀盟。

軟件設(shè)計(jì)也是這樣而晒,當(dāng)一個(gè)系統(tǒng)的功能越來越強(qiáng),子系統(tǒng)會(huì)越來越多阅畴,客戶對系統(tǒng)的訪問也變得越來越復(fù)雜倡怎。這時(shí)如果系統(tǒng)內(nèi)部發(fā)生改變,客戶端也要跟著改變贱枣,這違背了“開閉原則”监署,也違背了“迪米特法則”,所以有必要為多個(gè)子系統(tǒng)提供一個(gè)統(tǒng)一的接口纽哥,從而降低系統(tǒng)的耦合度钠乏,這就是外觀模式的目標(biāo)。

圖 1 給出了客戶去當(dāng)?shù)胤慨a(chǎn)局辦理房產(chǎn)證過戶要遇到的相關(guān)部門春塌。

辦理房產(chǎn)證過戶的相關(guān)部門

圖1 辦理房產(chǎn)證過戶的相關(guān)部門

外觀模式的定義與特點(diǎn)

外觀(Facade)模式的定義:是一種通過為多個(gè)復(fù)雜的子系統(tǒng)提供一個(gè)一致的接口晓避,而使這些子系統(tǒng)更加容易被訪問的模式簇捍。該模式對外有一個(gè)統(tǒng)一接口,外部應(yīng)用程序不用關(guān)心內(nèi)部子系統(tǒng)的具體的細(xì)節(jié)俏拱,這樣會(huì)大大降低應(yīng)用程序的復(fù)雜度暑塑,提高了程序的可維護(hù)性。

外觀(Facade)模式是“迪米特法則”的典型應(yīng)用锅必,它有以下主要優(yōu)點(diǎn)事格。

  1. 降低了子系統(tǒng)與客戶端之間的耦合度,使得子系統(tǒng)的變化不會(huì)影響調(diào)用它的客戶類搞隐。
  2. 對客戶屏蔽了子系統(tǒng)組件驹愚,減少了客戶處理的對象數(shù)目,并使得子系統(tǒng)使用起來更加容易尔许。
  3. 降低了大型軟件系統(tǒng)中的編譯依賴性么鹤,簡化了系統(tǒng)在不同平臺之間的移植過程,因?yàn)榫幾g一個(gè)子系統(tǒng)不會(huì)影響其他的子系統(tǒng)味廊,也不會(huì)影響外觀對象蒸甜。

外觀(Facade)模式的主要缺點(diǎn)如下。

  1. 不能很好地限制客戶使用子系統(tǒng)類余佛。
  2. 增加新的子系統(tǒng)可能需要修改外觀類或客戶端的源代碼柠新,違背了“開閉原則”。

外觀模式的結(jié)構(gòu)與實(shí)現(xiàn)

外觀(Facade)模式的結(jié)構(gòu)比較簡單辉巡,主要是定義了一個(gè)高層接口恨憎。它包含了對各個(gè)子系統(tǒng)的引用,客戶端可以通過它訪問各個(gè)子系統(tǒng)的功能〗奸梗現(xiàn)在來分析其基本結(jié)構(gòu)和實(shí)現(xiàn)方法憔恳。

1. 模式的結(jié)構(gòu)

外觀(Facade)模式包含以下主要角色。

  1. 外觀(Facade)角色:為多個(gè)子系統(tǒng)對外提供一個(gè)共同的接口净蚤。
  2. 子系統(tǒng)(Sub System)角色:實(shí)現(xiàn)系統(tǒng)的部分功能钥组,客戶可以通過外觀角色訪問它。
  3. 客戶(Client)角色:通過一個(gè)外觀角色訪問各個(gè)子系統(tǒng)的功能今瀑。

其結(jié)構(gòu)圖如圖 2 所示程梦。

外觀模式的結(jié)構(gòu)圖

享元模式

在面向?qū)ο蟪绦蛟O(shè)計(jì)過程中,有時(shí)會(huì)面臨要?jiǎng)?chuàng)建大量相同或相似對象實(shí)例的問題橘荠。創(chuàng)建那么多的對象將會(huì)耗費(fèi)很多的系統(tǒng)資源屿附,它是系統(tǒng)性能提高的一個(gè)瓶頸。例如哥童,圍棋和五子棋中的黑白棋子挺份,圖像中的坐標(biāo)點(diǎn)或顏色,局域網(wǎng)中的路由器贮懈、交換機(jī)和集線器匀泊,教室里的桌子和凳子等影暴。這些對象有很多相似的地方,如果能把它們相同的部分提取出來共享探赫,則能節(jié)省大量的系統(tǒng)資源,這就是享元模式的產(chǎn)生背景撬呢。

享元模式的定義與特點(diǎn)

享元(Flyweight)模式的定義:運(yùn)用共享技術(shù)來有効地支持大量細(xì)粒度對象的復(fù)用伦吠。它通過共享已經(jīng)存在的又橡來大幅度減少需要?jiǎng)?chuàng)建的對象數(shù)量、避免大量相似類的開銷魂拦,從而提高系統(tǒng)資源的利用率毛仪。

享元模式的主要優(yōu)點(diǎn)是:相同對象只要保存一份,這降低了系統(tǒng)中對象的數(shù)量芯勘,從而降低了系統(tǒng)中細(xì)粒度對象給內(nèi)存帶來的壓力箱靴。

其主要缺點(diǎn)是:

  1. 為了使對象可以共享,需要將一些不能共享的狀態(tài)外部化荷愕,這將增加程序的復(fù)雜性衡怀。
  2. 讀取享元模式的外部狀態(tài)會(huì)使得運(yùn)行時(shí)間稍微變長。

享元模式的結(jié)構(gòu)與實(shí)現(xiàn)

享元模式中存在以下兩種狀態(tài):

  1. 內(nèi)部狀態(tài)安疗,即不會(huì)隨著環(huán)境的改變而改變的可共享部分抛杨;
  2. 外部狀態(tài),指隨環(huán)境改變而改變的不可以共享的部分荐类。享元模式的實(shí)現(xiàn)要領(lǐng)就是區(qū)分應(yīng)用中的這兩種狀態(tài)怖现,并將外部狀態(tài)外部化介牙。下面來分析其基本結(jié)構(gòu)和實(shí)現(xiàn)方法会放。

1. 模式的結(jié)構(gòu)

享元模式的主要角色有如下节沦。

  1. 抽象享元角色(Flyweight):是所有的具體享元類的基類陶贼,為具體享元規(guī)范需要實(shí)現(xiàn)的公共接口募狂,非享元的外部狀態(tài)以參數(shù)的形式通過方法傳入环鲤。
  2. 具體享元(Concrete Flyweight)角色:實(shí)現(xiàn)抽象享元角色中所規(guī)定的接口撞叽。
  3. 非享元(Unsharable Flyweight)角色:是不可以共享的外部狀態(tài)唇聘,它以參數(shù)的形式注入具體享元的相關(guān)方法中璧亚。
  4. 享元工廠(Flyweight Factory)角色:負(fù)責(zé)創(chuàng)建和管理享元角色讨韭。當(dāng)客戶對象請求一個(gè)享元對象時(shí),享元工廠檢査系統(tǒng)中是否存在符合要求的享元對象癣蟋,如果存在則提供給客戶透硝;如果不存在的話,則創(chuàng)建一個(gè)新的享元對象疯搅。

圖 1 是享元模式的結(jié)構(gòu)圖濒生。圖中的 UnsharedConcreteFlyweight 是與淳元角色,里面包含了非共享的外部狀態(tài)信息 info幔欧;而 Flyweight 是抽象享元角色罪治,里面包含了享元方法 operation(UnsharedConcreteFlyweight state)丽声,非享元的外部狀態(tài)以參數(shù)的形式通過該方法傳入;ConcreteFlyweight 是具體享元角色觉义,包含了關(guān)鍵字 key雁社,它實(shí)現(xiàn)了抽象享元接口;FlyweightFactory 是享元工廠角色晒骇,它逝關(guān)鍵字 key 來管理具體享元霉撵;客戶角色通過享元工廠獲取具體享元,并訪問具體享元的相關(guān)方法洪囤。

享元模式的結(jié)構(gòu)圖

享元模式與單例模式的區(qū)別

享元模式可以再次創(chuàng)建對象 也可以取緩存對象

單例模式則是嚴(yán)格控制單個(gè)進(jìn)程中只有一個(gè)實(shí)例對象

享元模式可以通過自己實(shí)現(xiàn)對外部的單例 也可以在需要的使用創(chuàng)建更多的對象

單例模式是自身控制 需要增加不屬于該對象本身的邏輯

兩者都可以實(shí)現(xiàn)節(jié)省對象創(chuàng)建的時(shí)間 ThreadPool 線程池 與數(shù)據(jù)庫連接池 都有使用享元模式

組合模式

在現(xiàn)實(shí)生活中徒坡,存在很多“部分-整體”的關(guān)系,例如瘤缩,大學(xué)中的部門與學(xué)院喇完、總公司中的部門與分公司、學(xué)習(xí)用品中的書與書包剥啤、生活用品中的衣月艮與衣柜以及廚房中的鍋碗瓢盆等锦溪。在軟件開發(fā)中也是這樣,例如铐殃,文件系統(tǒng)中的文件與文件夾海洼、窗體程序中的簡單控件與容器控件等。對這些簡單對象與復(fù)合對象的處理富腊,如果用組合模式來實(shí)現(xiàn)會(huì)很方便坏逢。

組合模式的定義與特點(diǎn)

組合(Composite)模式的定義:有時(shí)又叫作部分-整體模式,它是一種將對象組合成樹狀的層次結(jié)構(gòu)的模式赘被,用來表示“部分-整體”的關(guān)系是整,使用戶對單個(gè)對象和組合對象具有一致的訪問性。

組合模式的主要優(yōu)點(diǎn)有:

  1. 組合模式使得客戶端代碼可以一致地處理單個(gè)對象和組合對象民假,無須關(guān)心自己處理的是單個(gè)對象浮入,還是組合對象,這簡化了客戶端代碼羊异;
  2. 更容易在組合體內(nèi)加入新的對象事秀,客戶端不會(huì)因?yàn)榧尤肓诵碌膶ο蠖脑创a,滿足“開閉原則”野舶;

其主要缺點(diǎn)是:

  1. 設(shè)計(jì)較復(fù)雜易迹,客戶端需要花更多時(shí)間理清類之間的層次關(guān)系;
  2. 不容易限制容器中的構(gòu)件平道;
  3. 不容易用繼承的方法來增加構(gòu)件的新功能睹欲;

組合模式的結(jié)構(gòu)與實(shí)現(xiàn)

組合模式的結(jié)構(gòu)不是很復(fù)雜,下面對它的結(jié)構(gòu)和實(shí)現(xiàn)進(jìn)行分析。

1. 模式的結(jié)構(gòu)

組合模式包含以下主要角色窘疮。

  1. 抽象構(gòu)件(Component)角色:它的主要作用是為樹葉構(gòu)件和樹枝構(gòu)件聲明公共接口袋哼,并實(shí)現(xiàn)它們的默認(rèn)行為。在透明式的組合模式中抽象構(gòu)件還聲明訪問和管理子類的接口闸衫;在安全式的組合模式中不聲明訪問和管理子類的接口涛贯,管理工作由樹枝構(gòu)件完成。
  2. 樹葉構(gòu)件(Leaf)角色:是組合中的葉節(jié)點(diǎn)對象蔚出,它沒有子節(jié)點(diǎn)疫蔓,用于實(shí)現(xiàn)抽象構(gòu)件角色中 聲明的公共接口。
  3. 樹枝構(gòu)件(Composite)角色:是組合中的分支節(jié)點(diǎn)對象身冬,它有子節(jié)點(diǎn)。它實(shí)現(xiàn)了抽象構(gòu)件角色中聲明的接口岔乔,它的主要作用是存儲(chǔ)和管理子部件酥筝,通常包含 Add()、Remove()雏门、GetChild() 等方法嘿歌。

組合模式分為透明式的組合模式和安全式的組合模式。

(1) 透明方式:在該方式中茁影,由于抽象構(gòu)件聲明了所有子類中的全部方法宙帝,所以客戶端無須區(qū)別樹葉對象和樹枝對象,對客戶端來說是透明的募闲。但其缺點(diǎn)是:樹葉構(gòu)件本來沒有 Add()步脓、Remove() 及 GetChild() 方法,卻要實(shí)現(xiàn)它們(空實(shí)現(xiàn)或拋異常)浩螺,這樣會(huì)帶來一些安全性問題靴患。其結(jié)構(gòu)圖如圖 1 所示。

透明式的組合模式的結(jié)構(gòu)圖

圖1 透明式的組合模式的結(jié)構(gòu)圖

(2) 安全方式:在該方式中要出,將管理子構(gòu)件的方法移到樹枝構(gòu)件中鸳君,抽象構(gòu)件和樹葉構(gòu)件沒有對子對象的管理方法,這樣就避免了上一種方式的安全性問題患蹂,但由于葉子和分支有不同的接口或颊,客戶端在調(diào)用時(shí)要知道樹葉對象和樹枝對象的存在,所以失去了透明性传于。其結(jié)構(gòu)圖如圖 2 所示囱挑。

安全式的組合模式的結(jié)構(gòu)圖

圖2 安全式的組合模式的結(jié)構(gòu)圖

2. 模式的實(shí)現(xiàn)

假如要訪問集合 c0={leaf1,{leaf2,leaf3}} 中的元素,其對應(yīng)的樹狀圖如圖 3 所示格了。

集合c0的樹狀圖

備忘錄模式

每個(gè)人都有犯錯(cuò)誤的時(shí)候看铆,都希望有種“后悔藥”能彌補(bǔ)自己的過失,讓自己重新開始盛末,但現(xiàn)實(shí)是殘酷的弹惦。在計(jì)算機(jī)應(yīng)用中否淤,客戶同樣會(huì)常常犯錯(cuò)誤,能否提供“后悔藥”給他們呢棠隐?當(dāng)然是可以的石抡,而且是有必要的。這個(gè)功能由“備忘錄模式”來實(shí)現(xiàn)助泽。

其實(shí)很多應(yīng)用軟件都提供了這項(xiàng)功能啰扛,如 Word、記事本嗡贺、Photoshop隐解、Eclipse 等軟件在編輯時(shí)按 Ctrl+Z 組合鍵時(shí)能撤銷當(dāng)前操作,使文檔恢復(fù)到之前的狀態(tài)诫睬;還有在 IE 中的后退鍵煞茫、數(shù)據(jù)庫事務(wù)管理中的回滾操作、玩游戲時(shí)的中間結(jié)果存檔功能摄凡、數(shù)據(jù)庫與操作系統(tǒng)的備份操作续徽、棋類游戲中的悔棋功能等都屬于這類。

備忘錄模式能記錄一個(gè)對象的內(nèi)部狀態(tài)亲澡,當(dāng)用戶后悔時(shí)能撤銷當(dāng)前操作钦扭,使數(shù)據(jù)恢復(fù)到它原先的狀態(tài)。

模式的定義與特點(diǎn)

備忘錄(Memento)模式的定義:在不破壞封裝性的前提下床绪,捕獲一個(gè)對象的內(nèi)部狀態(tài)客情,并在該對象之外保存這個(gè)狀態(tài),以便以后當(dāng)需要時(shí)能將該對象恢復(fù)到原先保存的狀態(tài)癞己。該模式又叫快照模式裹匙。

備忘錄模式是一種對象行為型模式,其主要優(yōu)點(diǎn)如下末秃。

  • 提供了一種可以恢復(fù)狀態(tài)的機(jī)制概页。當(dāng)用戶需要時(shí)能夠比較方便地將數(shù)據(jù)恢復(fù)到某個(gè)歷史的狀態(tài)。
  • 實(shí)現(xiàn)了內(nèi)部狀態(tài)的封裝练慕。除了創(chuàng)建它的發(fā)起人之外惰匙,其他對象都不能夠訪問這些狀態(tài)信息。
  • 簡化了發(fā)起人類铃将。發(fā)起人不需要管理和保存其內(nèi)部狀態(tài)的各個(gè)備份项鬼,所有狀態(tài)信息都保存在備忘錄中,并由管理者進(jìn)行管理劲阎,這符合單一職責(zé)原則绘盟。

其主要缺點(diǎn)是:資源消耗大。如果要保存的內(nèi)部狀態(tài)信息過多或者特別頻繁,將會(huì)占用比較大的內(nèi)存資源龄毡。

模式的結(jié)構(gòu)與實(shí)現(xiàn)

備忘錄模式的核心是設(shè)計(jì)備忘錄類以及用于管理備忘錄的管理者類吠卷,現(xiàn)在我們來學(xué)習(xí)其結(jié)構(gòu)與實(shí)現(xiàn)。

1. 模式的結(jié)構(gòu)

備忘錄模式的主要角色如下沦零。

  1. 發(fā)起人(Originator)角色:記錄當(dāng)前時(shí)刻的內(nèi)部狀態(tài)信息祭隔,提供創(chuàng)建備忘錄和恢復(fù)備忘錄數(shù)據(jù)的功能,實(shí)現(xiàn)其他業(yè)務(wù)功能路操,它可以訪問備忘錄里的所有信息疾渴。
  2. 備忘錄(Memento)角色:負(fù)責(zé)存儲(chǔ)發(fā)起人的內(nèi)部狀態(tài),在需要的時(shí)候提供這些內(nèi)部狀態(tài)給發(fā)起人屯仗。
  3. 管理者(Caretaker)角色:對備忘錄進(jìn)行管理搞坝,提供保存與獲取備忘錄的功能,但其不能對備忘錄的內(nèi)容進(jìn)行訪問與修改魁袜。

備忘錄模式的結(jié)構(gòu)圖如圖 1 所示瞄沙。

備忘錄模式的結(jié)構(gòu)圖
package memento;
public class MementoPattern
{
    public static void main(String[] args)
    {
        Originator or=new Originator();
        Caretaker cr=new Caretaker();       
        or.setState("S0"); 
        System.out.println("初始狀態(tài):"+or.getState());           
        cr.setMemento(or.createMemento()); //保存狀態(tài)      
        or.setState("S1"); 
        System.out.println("新的狀態(tài):"+or.getState());        
        or.restoreMemento(cr.getMemento()); //恢復(fù)狀態(tài)
        System.out.println("恢復(fù)狀態(tài):"+or.getState());
    }
}
//備忘錄
class Memento
{ 
    private String state; 
    public Memento(String state)
    { 
        this.state=state; 
    }     
    public void setState(String state)
    { 
        this.state=state; 
    }
    public String getState()
    { 
        return state; 
    }
}
//發(fā)起人
class Originator
{ 
    private String state;     
    public void setState(String state)
    { 
        this.state=state; 
    }
    public String getState()
    { 
        return state; 
    }
    public Memento createMemento()
    { 
        return new Memento(state); 
    } 
    public void restoreMemento(Memento m)
    { 
        this.setState(m.getState()); 
    } 
}
//管理者
class Caretaker
{ 
    private Memento memento;       
    public void setMemento(Memento m)
    { 
        memento=m; 
    }
    public Memento getMemento()
    { 
        return memento; 
    }
}

解釋器模式

在軟件開發(fā)中,會(huì)遇到有些問題多次重復(fù)出現(xiàn)慌核,而且有一定的相似性和規(guī)律性。如果將它們歸納成一種簡單的語言申尼,那么這些問題實(shí)例將是該語言的一些句子垮卓,這樣就可以用“編譯原理”中的解釋器模式來實(shí)現(xiàn)了。

雖然使用解釋器模式的實(shí)例不是很多师幕,但對于滿足以上特點(diǎn)粟按,且對運(yùn)行效率要求不是很高的應(yīng)用實(shí)例,如果用解釋器模式來實(shí)現(xiàn)霹粥,其效果是非常好的灭将,本文將介紹其工作原理與使用方法。

模式的定義與特點(diǎn)

解釋器(Interpreter)模式的定義:給分析對象定義一個(gè)語言后控,并定義該語言的文法表示庙曙,再設(shè)計(jì)一個(gè)解析器來解釋語言中的句子。也就是說浩淘,用編譯語言的方式來分析應(yīng)用中的實(shí)例捌朴。這種模式實(shí)現(xiàn)了文法表達(dá)式處理的接口,該接口解釋一個(gè)特定的上下文张抄。

這里提到的文法和句子的概念同編譯原理中的描述相同砂蔽,“文法”指語言的語法規(guī)則,而“句子”是語言集中的元素署惯。例如左驾,漢語中的句子有很多,“我是中國人”是其中的一個(gè)句子,可以用一棵語法樹來直觀地描述語言中的句子诡右。

解釋器模式是一種類行為型模式安岂,其主要優(yōu)點(diǎn)如下。

  1. 擴(kuò)展性好稻爬。由于在解釋器模式中使用類來表示語言的文法規(guī)則嗜闻,因此可以通過繼承等機(jī)制來改變或擴(kuò)展文法。
  2. 容易實(shí)現(xiàn)桅锄。在語法樹中的每個(gè)表達(dá)式節(jié)點(diǎn)類都是相似的琉雳,所以實(shí)現(xiàn)其文法較為容易。

解釋器模式的主要缺點(diǎn)如下友瘤。

  1. 執(zhí)行效率較低翠肘。解釋器模式中通常使用大量的循環(huán)和遞歸調(diào)用,當(dāng)要解釋的句子較復(fù)雜時(shí)辫秧,其運(yùn)行速度很慢束倍,且代碼的調(diào)試過程也比較麻煩。
  2. 會(huì)引起類膨脹盟戏。解釋器模式中的每條規(guī)則至少需要定義一個(gè)類绪妹,當(dāng)包含的文法規(guī)則很多時(shí),類的個(gè)數(shù)將急劇增加柿究,導(dǎo)致系統(tǒng)難以管理與維護(hù)邮旷。
  3. 可應(yīng)用的場景比較少。在軟件開發(fā)中蝇摸,需要定義語言文法的應(yīng)用實(shí)例非常少婶肩,所以這種模式很少被使用到。

模式的結(jié)構(gòu)與實(shí)現(xiàn)

解釋器模式常用于對簡單語言的編譯或分析實(shí)例中貌夕,為了掌握好它的結(jié)構(gòu)與實(shí)現(xiàn)律歼,必須先了解編譯原理中的“文法、句子啡专、語法樹”等相關(guān)概念险毁。

1) 文法

文法是用于描述語言的語法結(jié)構(gòu)的形式規(guī)則。沒有規(guī)矩不成方圓们童,例如辱揭,有些人認(rèn)為完美愛情的準(zhǔn)則是“相互吸引、感情專一病附、任何一方都沒有戀愛經(jīng)歷”问窃,雖然最后一條準(zhǔn)則較苛刻,但任何事情都要有規(guī)則完沪,語言也一樣域庇,不管它是機(jī)器語言還是自然語言嵌戈,都有它自己的文法規(guī)則。例如听皿,中文中的“句子”的文法如下熟呛。

<pre class="info-box" style="margin: 6px auto; display: block; padding: 10px; font-size: 14px; line-height: 1.6em; color: rgb(68, 68, 68); white-space: pre-wrap; overflow-wrap: break-word; background: none rgb(248, 248, 248); border: 1px solid rgb(225, 225, 225); border-radius: 4px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">〈句子〉::=〈主語〉〈謂語〉〈賓語〉
〈主語〉::=〈代詞〉|〈名詞〉
〈謂語〉::=〈動(dòng)詞〉
〈賓語〉::=〈代詞〉|〈名詞〉
〈代詞〉你|我|他
〈名詞〉7大學(xué)生I筱霞I英語
〈動(dòng)詞〉::=是|學(xué)習(xí)</pre>

注:這里的符號“::=”表示“定義為”的意思,用“〈”和“〉”括住的是非終結(jié)符尉姨,沒有括住的是終結(jié)符庵朝。

2) 句子

句子是語言的基本單位,是語言集中的一個(gè)元素又厉,它由終結(jié)符構(gòu)成九府,能由“文法”推導(dǎo)出。例如覆致,上述文法可以推出“我是大學(xué)生”侄旬,所以它是句子。

3) 語法樹

語法樹是句子結(jié)構(gòu)的一種樹型表示煌妈,它代表了句子的推導(dǎo)結(jié)果儡羔,它有利于理解句子語法結(jié)構(gòu)的層次。圖 1 所示是“我是大學(xué)生”的語法樹璧诵。

句子“我是大學(xué)生”的語法樹

圖1 句子“我是大學(xué)生”的語法樹

有了以上基礎(chǔ)知識汰蜘,現(xiàn)在來介紹解釋器模式的結(jié)構(gòu)就簡單了。解釋器模式的結(jié)構(gòu)與組合模式相似之宿,不過其包含的組成元素比組合模式多族操,而且組合模式是對象結(jié)構(gòu)型模式,而解釋器模式是類行為型模式澈缺。

1. 模式的結(jié)構(gòu)

解釋器模式包含以下主要角色。

  1. 抽象表達(dá)式(Abstract Expression)角色:定義解釋器的接口炕婶,約定解釋器的解釋操作姐赡,主要包含解釋方法 interpret()。
  2. 終結(jié)符表達(dá)式(Terminal Expression)角色:是抽象表達(dá)式的子類柠掂,用來實(shí)現(xiàn)文法中與終結(jié)符相關(guān)的操作项滑,文法中的每一個(gè)終結(jié)符都有一個(gè)具體終結(jié)表達(dá)式與之相對應(yīng)。
  3. 非終結(jié)符表達(dá)式(Nonterminal Expression)角色:也是抽象表達(dá)式的子類涯贞,用來實(shí)現(xiàn)文法中與非終結(jié)符相關(guān)的操作枪狂,文法中的每條規(guī)則都對應(yīng)于一個(gè)非終結(jié)符表達(dá)式。
  4. 環(huán)境(Context)角色:通常包含各個(gè)解釋器需要的數(shù)據(jù)或是公共的功能宋渔,一般用來傳遞被所有解釋器共享的數(shù)據(jù)州疾,后面的解釋器可以從這里獲取這些值。
  5. 客戶端(Client):主要任務(wù)是將需要分析的句子或表達(dá)式轉(zhuǎn)換成使用解釋器對象描述的抽象語法樹皇拣,然后調(diào)用解釋器的解釋方法严蓖,當(dāng)然也可以通過環(huán)境角色間接訪問解釋器的解釋方法薄嫡。

解釋器模式的結(jié)構(gòu)圖如圖 2 所示。

解釋器模式的結(jié)構(gòu)圖
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末毫深,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子毒姨,更是在濱河造成了極大的恐慌,老刑警劉巖闸迷,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件泉懦,死亡現(xiàn)場離奇詭異崩哩,居然都是意外死亡巡球,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進(jìn)店門邓嘹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來酣栈,“玉大人,你說我怎么就攤上這事汹押】篌荩” “怎么了?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵棚贾,是天一觀的道長窖维。 經(jīng)常有香客問我,道長妙痹,這世上最難降的妖魔是什么铸史? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮怯伊,結(jié)果婚禮上琳轿,老公的妹妹穿的比我還像新娘。我一直安慰自己耿芹,他們只是感情好崭篡,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著吧秕,像睡著了一般琉闪。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上砸彬,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天塘偎,我揣著相機(jī)與錄音疗涉,去河邊找鬼。 笑死吟秩,一個(gè)胖子當(dāng)著我的面吹牛咱扣,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播涵防,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼闹伪,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了壮池?” 一聲冷哼從身側(cè)響起偏瓤,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎椰憋,沒想到半個(gè)月后厅克,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡橙依,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年证舟,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片窗骑。...
    茶點(diǎn)故事閱讀 38,059評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡女责,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出创译,到底是詐尸還是另有隱情褐奴,我是刑警寧澤旱眯,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布沸移,位于F島的核電站财喳,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏立砸。R本人自食惡果不足惜掖疮,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望仰禽。 院中可真熱鬧氮墨,春花似錦纺蛆、人聲如沸吐葵。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽温峭。三九已至,卻和暖如春字支,著一層夾襖步出監(jiān)牢的瞬間凤藏,已是汗流浹背奸忽。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留揖庄,地道東北人栗菜。 一個(gè)月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像蹄梢,于是被迫代替她去往敵國和親疙筹。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評論 2 345