[Common] Head First 設(shè)計模式 (單例 + 命令 + 適配器外觀 + 封裝 + 迭代器與組合)

Chapter 5 單件模式

單例模式比全局變量好的是不用程序一開始就初始化全局變量(有的東西的初始化很費(fèi)事兒最好不要都一開始就初始化),可以用到單例的時候再初始化赶盔,主要是將構(gòu)造方法private并且只提供一個對外的getInstance實(shí)現(xiàn)只初始化一次:

public class Singleton
{
    private static Singleton uniqueInstance = null;
 
    //其他有用的實(shí)例變量
    
    //構(gòu)造方法是私有的,所以在類外不能new出多個實(shí)例
    private Singleton()
    {
        //初始化其他實(shí)例變量
    }
 
    public static Singleton getInstance()
    {
        if (uniqueInstance == null)
        {
            uniqueInstance = new Singleton();
        }
        return uniqueInstance;
    }
}

但注意哦榆浓,上面的方式會有線程問題于未,可能還是會產(chǎn)生兩個實(shí)例。

單件模式(又稱單例模式)陡鹃,確保一個類只有一個實(shí)例烘浦,并提供一個全局訪問點(diǎn)。

加鎖保證單例

Chapter 6 命令模式

設(shè)計一個家電自動化遙控器的API萍鲸。這個遙控器具有七個可編程的插槽闷叉,每個插槽都有對應(yīng)的開關(guān)按鈕,這個遙控器還具備一個整體的撤銷按鈕脊阴。希望你能夠創(chuàng)建一組控制遙控器的API握侧,讓每個插槽都能夠控制一個或一組裝置,能夠控制目前的裝置和任何未來可能出現(xiàn)的裝置嘿期,這一點(diǎn)很重要品擎。(這里有一組Java類,這些類時由多個廠商開發(fā)出來的备徐,用來控制家電自動化裝置萄传,例如點(diǎn)燈,風(fēng)扇蜜猾,熱水器盲再,音響設(shè)備和其他類似的可控制裝置西设。)

家電類們

因?yàn)槊總€家電的接口都不一樣,我們總不好先判斷是什么家電答朋,然后調(diào)用不同的接口,但是我們可以使用命令模式棠笑,把請求例如按下打開電燈按鈕封裝成一個命令對象梦碗,這樣遙控器就不需要知道電燈是怎么做的了。


這里用一個餐廳下單的例子改造舉例:

餐廳訂單

然后改成命令模式:


命令模式的餐廳

就是將菜品的制作改成實(shí)現(xiàn)了command接口蓖救,這樣廚師拿到的時候洪规,可以直接調(diào)用command.execute(),它不會管具體里面是做什么的循捺,菜品自己會執(zhí)行制作斩例。

--

遙控器的改造也是醬紫,首先定義command接口从橘,然后實(shí)現(xiàn)不同電器的command:

interface Command{
    public void execute();
}

class LightOnCommand implements Command{
    Light light;
    public LightOnCommand(Light light){
        this.light=light;
    }
    @Override
    public void execute() {
        light.on();
    }
}

假設(shè)有一個只有一個按鈕的遙控器念赶,就是醬紫的:

class SimpleRemoteControl{
    Command slot;
    public SimpleRemoteControl(){}
    public void setCommand(Command command){
        slot=command;
    }
    public void buttonWasPressed(){
        slot.execute();
    }
}

// test code
class RemoteControlTest{
    public static void main(String[] args){
        SimpleRemoteControl remote=new SimpleRemoteControl();
        Light light=new Light();
        LightOnCommand lightOn=new LightOnCommand(light);
        remote.setCommand(lightOn);
        remote.buttonWasPressed();
    }
}

命令模式:將“請求”封裝成對象,一邊使用不同的請求恰力、隊列或者日志來來參數(shù)化其他對象叉谜。命令模式也支持可撤銷的操作。

類圖

空對象

為了不用每次調(diào)用插槽command的時候都先檢查command是不是空踩萎,可以創(chuàng)建一個空command什么都不做來占位停局,這樣就可以避免了判斷null了~

public class NoCommand implements Command {
    public void execute() { }
    public void undo() { }
}

這里插一句,命令模式的優(yōu)點(diǎn)香府,如果通過讓家具們都實(shí)現(xiàn)某個接口董栽,然后直接把自己給遙控器,遙控器調(diào)用接口也可以企孩,缺點(diǎn)是:

  • 如果有一個按鈕控制兩個家具呢锭碳?(如果通過命令模式可以新建一個初始化傳入一組command,然后execute的時候調(diào)用這組command的每一個命令)
  • 如果需要增加減少功能柠硕,接口就要變工禾,每個家具類都要變
  • 如果又有個什么遙控,家具類就要再增加一套接口蝗柔,但是家具類沒有職責(zé)應(yīng)該這么做吖

命令模式在thread隊列中應(yīng)用
命令模式在死機(jī)恢復(fù)時候的應(yīng)用

Chapter 7 適配器模式與外觀模式

現(xiàn)實(shí)世界適配器

適配器模式:將一個類的接口轉(zhuǎn)換成客戶期望的另一個接口闻葵。適配器讓原本接口不相融的類可以相互合作

例如,當(dāng)我們換了一個新廠商癣丧,不能修改廠商的代碼槽畔,自己的舊代碼由于已經(jīng)提供了接口給別人也不能修改,就可以加一層適配性胁编,我們可以自己提供厢钧,也可以讓廠商提供哈

適配器
  • 設(shè)計:
    實(shí)現(xiàn)想要轉(zhuǎn)換的接口
    取得要適配的對象的引用鳞尔,作為局部變量
    用要適配的對象的方法實(shí)現(xiàn)接口中的方法

如果有兩個不同的interface分別是火雞和鴨子,但我們只有火雞卻要提供鴨子給外部:

用火雞冒充鴨子
  • 客戶使用適配器的過程:
    通過目標(biāo)接口調(diào)用適配器方法
    適配器使用被適配者的接口轉(zhuǎn)換成對被適配者的調(diào)用
    客戶端接受調(diào)用結(jié)果早直,但并未察覺適配器在中轉(zhuǎn)的作用

適配器模式一般只適配(持有)一個類寥假,如果適配多個類也可以啦,但你可以用多個適配器適配一個接口哈霞扬;如果舊接口和新接口共存糕韧,最好讓適配器同時滿足這兩種接口不要用兩套。

類圖

之前我們講的是對象適配器喻圃,而類適配器是通過多重繼承代替組合的方式調(diào)用的被適配者萤彩。

類適配器

類適配器的好處就是他不用新增一個持有的被適配對象,以及不會實(shí)現(xiàn)所有被適配者的接口斧拍,因?yàn)樗抢^承的是有默認(rèn)行為的雀扶。

這里裝飾者是不改變接口加入更多責(zé)任,而適配器是改變接口的哈


外觀模式

外觀模式提供了一個統(tǒng)一的接口肆汹,用來訪問子系統(tǒng)中的一群接口愚墓。外觀定義了一個高層接口,讓子系統(tǒng)更容易使用县踢。

外觀模式不只是簡化了接口转绷,也將客戶從組件的子系統(tǒng)中解耦。

外觀和適配器可以包裝許多類硼啤,但是外觀強(qiáng)調(diào)的是簡化接口议经,而適配器是為了將接口轉(zhuǎn)換成不同的接口。

假設(shè)我們設(shè)計了一個家庭影院谴返,類圖是下面醬紫的煞肾,然后如果我們想要看一場電影,需要打開爆米花嗓袱、打開音效籍救、打開……最后打開dvd,要做一系列的事情非常麻煩渠抹,關(guān)的時候也是要反著一系列操作蝙昙。

家庭影院類圖

外觀只是提供了一些簡化的操作,沒有把子系統(tǒng)的高級操作隔離起來梧却,依然將子系統(tǒng)完整的暴露出來奇颠,因此如果你需要更高級的操作也可以訪問子系統(tǒng)的接口

外觀并沒有實(shí)現(xiàn)新的行為,只是將子系統(tǒng)的操作合理的組合放航。一個子系統(tǒng)可以有多個外觀烈拒,并可以創(chuàng)造分層次的外觀,外觀不只簡化了接口,也將用戶從復(fù)雜的子系統(tǒng)中解耦出來荆几。

外觀vs適配器:
外觀的目的是簡化接口吓妆,適配器的目的是轉(zhuǎn)換接口滿足客戶預(yù)期,和包裝幾個類沒有關(guān)系

類圖

OO原則:最少知識

最少知識原則:只和你的密友談話吨铸。

減少對象之間的交互行拢,只留下幾個密友。不要讓太多的類耦合在一起以至于修改系統(tǒng)中的一部分會影響到其他部分诞吱。

反例:
public float getTemp() {
    return station.getThermometer().getTemperature();
}

正例:
public float getTemp() {
    return station. getTemperature();
}
  • 在對象方法內(nèi)剂陡,我們允許調(diào)用哪些對象的方法,簡單理解為以下4個小原則:
    該對象本身
    方法參數(shù)傳入對象
    方法內(nèi)實(shí)例的對象
    對象組件
最少知識原則示例

外觀模式其實(shí)幫助了我們實(shí)現(xiàn)最少知識原則狐胎。


Chapter 8 封裝算法

煮茶和咖啡

煮茶和咖啡的步驟幾乎是一致的,所以可以通過提取基類來避免重復(fù)歌馍。

public abstract class CaffeineBeverage {
    final void prepareRecipe(){
        boilWater();
        brew();
        addCondimennts();
        pourInCup();
    }
    abstract void brew();
    abstract void addCondimennts();
    public void boilWater(){
        System.out.println("把水煮沸");
    }
    public void pourInCup(){
        System.out.println("倒進(jìn)杯子");
    }
}
public class Coffee extends CaffeineBeverage{
    public void brew(){
        System.out.println("用沸水沖泡咖啡");
    }
    public void addCondimennts(){
        System.out.println("添加糖和牛奶");
    }
}
public class Tea extends CaffeineBeverage{
    public void brew(){
        System.out.println("用沸水沖泡茶");
    }
    public void addCondimennts(){
        System.out.println("添加檸檬");
    }
}

模板方法定義了一個算法的步驟握巢,并容許子類為一個或多個步驟提供突現(xiàn)。

當(dāng)我們將共同的地方抽出作為父類的時候松却,將來如果有類似的飲料就更容易拓展暴浦,減少了重復(fù)代碼。同時修改的話也只要改父類就好晓锻。

在一個方法中定義一個算法的骨架歌焦,而將一些步驟延遲到子類中。模版方法使得子類可以在不改變算法結(jié)構(gòu)的情況下砚哆,重新定義算法中的某些步驟独撇。

類圖

鉤子是一種被聲明在抽象類中的方法,但只有空的或者默認(rèn)的實(shí)現(xiàn)。鉤子的存在, 可以讓子類有能力對算法的不同點(diǎn)進(jìn)行掛鉤躁锁。要不要掛鉤,由子類自行決定纷铣。

public abstract class CaffeineBeverage {
    final void prepareRecipe(){
        boilWater();
        brew();
        pourInCup();
        /**
         * 殘們加上了一個小的條件語句,而該條件是否成立,是由一個
         * 具體方法customerWantsCondiments()決定的。
         * 如果顧客“想要”調(diào)料,有這時我們才調(diào)用addCondimennts()
         */
        if (customerWantsCondiments()){
            addCondimennts();
        }
    }
    /**
     * 殘們在這里定義了-個方法, (通常)是空的缺省實(shí)現(xiàn)战转。
     * 這個方法會返回true,不做別的事搜立。
     * 這就是一個鉤子,子類可以覆蓋這個方法,但不見得一定要這么做。
     * @return
     */
    boolean customerWantsCondiments(){
        return true;
    }
    abstract void brew();
    abstract void addCondimennts();
    public void boilWater(){
        System.out.println("把水煮沸");
    }
    public void pourInCup(){
        System.out.println("倒進(jìn)杯子");
    }
}
子類中

public class Coffee extends CaffeineBeverage{
//    用戶輸入的值
    private String answer;
    public void brew(){
        System.out.println("用沸水沖泡咖啡");
    }
    public void addCondimennts(){
        System.out.println("添加糖和牛奶");
    }
    //覆蓋鉤子槐秧,提供自己的功能
    @Override
    boolean customerWantsCondiments() {
//        讓用戶根據(jù)他們的輸入來判斷是否需要添加配料
        if (answer.toLowerCase().startsWith("y")){
            return true;
        }else {
            return false;
        }
    }
}

如果是算法中必須的一步就可以用抽象方法啄踊,如果是可選的就可以用鉤子來實(shí)現(xiàn)。鉤子是可以實(shí)現(xiàn)也可以不實(shí)現(xiàn)刁标,不強(qiáng)求的做法颠通。

可選的步驟作為鉤子的話(空或者默認(rèn)實(shí)現(xiàn))就可以讓子類減少必須實(shí)現(xiàn)的抽象方法的數(shù)量啦。

鉤子

鉤子就類似聲明周期函數(shù)感覺命雀,你可以選擇覆蓋蒜哀,也可以選擇不覆蓋。


好萊塢原則

好萊塢原則:別調(diào)用(打電話給)我們,我們會調(diào)用(打電話給)你撵儿。

好萊塢原則可以給我們一種防止“依賴腐敗”的方法乘客。

當(dāng)高層組件依賴低層組件,而低層組件又依賴高層組件淀歇,而高層組件又依賴邊側(cè)組件易核,而邊側(cè)組件又依賴低層組件時, 依賴腐敗就發(fā)生了。在這種情況下,沒有人可以輕易地搞懂系統(tǒng)是如何設(shè)計的浪默。

在好萊塢原則之下牡直,我們允許低層組件將自己掛鉤到系統(tǒng)上,但是高層組件會決定什么時候和怎樣使用這些低層組件纳决。換句話說,高層組件對待低層組件的方式是“別調(diào)用我們,我們會調(diào)用你”

模板方法里的好萊塢原則
  • 好萊塢原則和依賴倒置原則之間的關(guān)系如何?
    依賴倒置原則教我們盡量避免使用具體類碰逸,而多使用抽象。而好菜塢原則是用在創(chuàng)建框架或組件上的一種技巧阔加,好讓低層組件能夠被掛鉤進(jìn)計算中饵史,而且又不會讓高層組件依賴低層組件。兩者的目標(biāo)都是在于解耦,但是依賴倒置原則更加注重如何在設(shè)計中避免依賴胜榔。

好菜塢原則教我們一個技巧胳喷,創(chuàng)建個有彈性的設(shè)計,允許低層結(jié)構(gòu)能夠互相操作夭织,而又防止其他類太過依賴它們吭露。

低層組件結(jié)束的時候經(jīng)常會調(diào)用super的方法,這個是可以的尊惰,只是我們要避免環(huán)狀調(diào)用讲竿。


![java排序中的模板方法images.jianshu.io/upload_images/5219632-deebac020dd36180.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

策略模式會實(shí)現(xiàn)整個算法,而模板模式的子類只實(shí)現(xiàn)部分算法择浊;而且策略是不依賴上層類的戴卜,而模板胡依賴頂層父類,模板會共享一部分代碼例如共通的步驟琢岩;策略模式封裝算法的方式是組合投剥,通過持有不同的實(shí)例實(shí)現(xiàn),模板方法通過繼承封裝不同的算法担孔。

策略模式可以不繼承只是實(shí)現(xiàn)接口江锨,因?yàn)樗恍枰^承默認(rèn)的實(shí)現(xiàn),這點(diǎn)和模板模式是不一樣的糕篇。

而工程模式其實(shí)就是模板模式的一種特殊版本啄育,如果模板里面有一個createXX的方法下放到子類實(shí)現(xiàn),然后模板里直接調(diào)用生成一個instance拌消,那么其實(shí)就是工廠方法挑豌。


Chapter 9 迭代器與組合模式

假設(shè)有兩個集合類,一個是ArrayList,一個是[]氓英,那么當(dāng)一個對象需要操作這兩個集合實(shí)例的時候侯勉,需要分別用不同方式遍歷,這樣是很不方便的铝阐。

不同類型一起集合處理

所以Java才有迭代器iterator接口址貌,無論是數(shù)組還是ArrayList都可以創(chuàng)建iterator來遍歷。

迭代器接口是醬紫的:

public interface Iterator{
  boolean hasNext();  //返回一個布爾值徘键,判斷是否還有更多的元素
  Object next();   //返回下一個元素
}

我們來改寫一下print菜單這個事兒:

//實(shí)現(xiàn)迭代器接口  DinerMenu
public class DinerMenuIterator implements Iterator{
  MenuItem[] items;
  int position = 0;   //position記錄當(dāng)前數(shù)組遍歷的位置
  
  public DinerMenuIterator(MenuItem[] items){  //構(gòu)造器需要被傳入一個菜單項的數(shù)組當(dāng)作參數(shù)
    this.items=items;
  }
  
  public Object next(){  //返回數(shù)組內(nèi)的下一項练对,并遞增其位置
    MenuItem menuItem= items[position];
    position=position+1;
    return menuItem;
  }
  
  public boolean hasNext(){
    /*檢查是否已經(jīng)取得數(shù)組內(nèi)所有的元素,如果還有元素待遍歷則返回true吹害;
     由于使用的是固定長度的數(shù)組螟凭,所以不但要檢查是否超出了數(shù)組長度,也必須檢查是否下一項是null它呀,如果是null赂摆,就沒有其他項了
    */
    if(position>=items.length||items[position]==null){ 
      return false;
    }else{
      return true;
    }
  }

public class Waitress { 
    Menu dinerMenu; 
    public Waitress( Menu dinerMenu) { 
        this.dinerMenu = dinerMenu; 
    } 
    public void printMenu() {  
        Iterator dinerIterator = dinerMenu.createIterator();

        System.out.println("/nLUNCH"); 
        printMenu(dinerIterator); 
    } 
    private void printMenu(Iterator iterator) { 
        while (iterator.hasNext()) { 
            MenuItem menuItem = (MenuItem)iterator.next(); 
            System.out.print(menuItem.getName() + ", "); 
            System.out.print(menuItem.getPrice() + " -- "); 
            System.out.println(menuItem.getDescription()); 
        } 
    }

這樣以后我們的waitress就不需要知道兩種不同的菜單的具體用什么實(shí)現(xiàn)的菜單存儲了,只要調(diào)用iterator接口即可钟些,把菜單內(nèi)部對外封閉了。

迭代器模式提供一種方法順序訪問一個聚合對象中各個元素, 而又無須暴露該對象的內(nèi)部表示绊谭。


單一責(zé)任

單一責(zé)任原則:一個類應(yīng)該只有一個引起變化的原因政恍。

類的每個責(zé)任都有改變的潛在區(qū)域。超過一個責(zé)任則意味著多個改變的區(qū)域达传。該原則說明了應(yīng)該盡量讓每個類保持單一責(zé)任篙耗。


通過iterator我們改變了菜單的遍歷,讓一切看起來比較方便宪赶,但現(xiàn)在其中一家餐廳提出了子菜單(甜品)宗弯,這個時候我們就需要一個類似樹的結(jié)構(gòu)來存儲了。

子菜單

組合模式:允許將對象組合成樹形結(jié)構(gòu)來表現(xiàn)“整體/部分”層次結(jié)構(gòu)搂妻。組合能夠讓客戶以抑制的方式處理個別對象以及對象組合蒙保。

組合模式類圖

組合模式包含組件,組件有兩種:一種是單純的葉節(jié)點(diǎn)欲主,一種是持有一群孩子的組合邓厕,這些孩子可以是葉節(jié)點(diǎn)也還可以是組合。

組合&菜單

這里meneComponent接口定義了葉節(jié)點(diǎn) & 組合的方法扁瓢,相當(dāng)于有了兩種responsibility详恼,葉節(jié)點(diǎn)只要實(shí)現(xiàn)它需要的方法即可。

類似frame panel界面也有這種關(guān)系引几。

如果你還想方便一點(diǎn)也可以讓子節(jié)點(diǎn)持有parent指針

這里讓一個接口實(shí)現(xiàn)兩種(節(jié)點(diǎn)以及組合)的特性昧互,其實(shí)是用單一原則換取了透明性,也就是對用戶而言,每個節(jié)點(diǎn)都是一致的敞掘,它可以不用關(guān)心這個點(diǎn)是單純的一個葉節(jié)點(diǎn)還是一個組合的使用叽掘。

組合遍歷器

這里用stack實(shí)現(xiàn)了根葉節(jié)點(diǎn)的遍歷


  • 策略模式:封裝可互換的行為,并使用委托決定使用哪一個渐逃。

  • 適配器模式:改變一個或多個類的接口够掠。

  • 迭代器模式:提供一個方式來遍歷集合,而無需暴露集合的實(shí)現(xiàn)茄菊。

  • 外觀模式:簡化一群類的接口疯潭。

  • 組合模式:客戶可以將對象的集合以及個別的對象一視同仁。

  • 觀察者模式:當(dāng)某個狀態(tài)改變是面殖,允許一群對象能被通知到竖哩。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市脊僚,隨后出現(xiàn)的幾起案子相叁,更是在濱河造成了極大的恐慌,老刑警劉巖辽幌,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件增淹,死亡現(xiàn)場離奇詭異,居然都是意外死亡乌企,警方通過查閱死者的電腦和手機(jī)虑润,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來加酵,“玉大人拳喻,你說我怎么就攤上這事≈硗螅” “怎么了冗澈?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長陋葡。 經(jīng)常有香客問我亚亲,道長,這世上最難降的妖魔是什么腐缤? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任朵栖,我火速辦了婚禮,結(jié)果婚禮上柴梆,老公的妹妹穿的比我還像新娘陨溅。我一直安慰自己,他們只是感情好绍在,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布门扇。 她就那樣靜靜地躺著雹有,像睡著了一般。 火紅的嫁衣襯著肌膚如雪臼寄。 梳的紋絲不亂的頭發(fā)上霸奕,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天,我揣著相機(jī)與錄音吉拳,去河邊找鬼质帅。 笑死,一個胖子當(dāng)著我的面吹牛留攒,可吹牛的內(nèi)容都是我干的煤惩。 我是一名探鬼主播,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼炼邀,長吁一口氣:“原來是場噩夢啊……” “哼魄揉!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起拭宁,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤洛退,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后兵怯,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體摇零,經(jīng)...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年登渣,在試婚紗的時候發(fā)現(xiàn)自己被綠了胜茧。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片呻顽。...
    茶點(diǎn)故事閱讀 39,919評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡廊遍,死狀恐怖贩挣,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情裕便,我是刑警寧澤见咒,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布改览,位于F島的核電站,受9級特大地震影響恃疯,放射性物質(zhì)發(fā)生泄漏今妄。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一犬性、第九天 我趴在偏房一處隱蔽的房頂上張望乒裆。 院中可真熱鬧鹤耍,春花似錦验辞、人聲如沸跌造。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽首量。三九已至迎变,卻和暖如春收苏,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背愤兵。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工鹿霸, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留秆乳,地道東北人懦鼠。 一個月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓屹堰,卻偏偏與公主長得像肛冶,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子扯键,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評論 2 354

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