22.狀態(tài)模式(行為型)

狀態(tài)模式(行為型)

原書(shū)鏈接設(shè)計(jì)模式(劉偉)

在軟件系統(tǒng)中老充,有些對(duì)象也像水一樣具有多種狀態(tài)簿寂,這些狀態(tài)在某些情況下能夠相互轉(zhuǎn)換啦鸣,而且對(duì)象在不同的狀態(tài)下也將具有不同的行為涣狗。為了更好地對(duì)這些具有多種狀態(tài)的對(duì)象進(jìn)行設(shè)計(jì)袜匿,我們可以使用一種被稱之為狀態(tài)模式的設(shè)計(jì)模式進(jìn)行系統(tǒng)設(shè)計(jì)更啄。

一、相關(guān)概述

1). 概述

狀態(tài)模式用于解決系統(tǒng)中復(fù)雜對(duì)象的狀態(tài)轉(zhuǎn)換以及不同狀態(tài)下行為的封裝問(wèn)題居灯。當(dāng)系統(tǒng)中某個(gè)對(duì)象存在多個(gè)狀態(tài)祭务,這些狀態(tài)之間可以進(jìn)行轉(zhuǎn)換,而且對(duì)象在不同狀態(tài)下行為不相同時(shí)可以使用狀態(tài)模式穆壕。狀態(tài)模式將一個(gè)對(duì)象的狀態(tài)從該對(duì)象中分離出來(lái)待牵,封裝到專門(mén)的狀態(tài)類中,使得對(duì)象狀態(tài)可以靈活變化喇勋,對(duì)于客戶端而言缨该,無(wú)須關(guān)心對(duì)象狀態(tài)的轉(zhuǎn)換以及對(duì)象所處的當(dāng)前狀態(tài),無(wú)論對(duì)于何種狀態(tài)的對(duì)象川背,客戶端都可以一致處理贰拿。

  • 狀態(tài)模式(State Pattern):允許一個(gè)對(duì)象在其內(nèi)部狀態(tài)改變時(shí)改變它的行為,對(duì)象看起來(lái)似乎修改了它的類熄云。其別名為狀態(tài)對(duì)象(Objects for States)膨更,狀態(tài)模式是一種對(duì)象行為型模式。

狀態(tài)模式.png

2). 相關(guān)角色

  1. Context(環(huán)境類):環(huán)境類又稱為上下文類缴允,它是擁有多種狀態(tài)的對(duì)象荚守。由于環(huán)境類的狀態(tài)存在多樣性且在不同狀態(tài)下對(duì)象的行為有所不同珍德,因此將狀態(tài)獨(dú)立出去形成單獨(dú)的狀態(tài)類。在環(huán)境類中維護(hù)一個(gè)抽象狀態(tài)類State的實(shí)例矗漾,這個(gè)實(shí)例定義當(dāng)前狀態(tài)锈候,在具體實(shí)現(xiàn)時(shí),它是一個(gè)State子類的對(duì)象敞贡。
  2. State(抽象狀態(tài)類):它用于定義一個(gè)接口以封裝與環(huán)境類的一個(gè)特定狀態(tài)相關(guān)的行為泵琳,在抽象狀態(tài)類中聲明了各種不同狀態(tài)對(duì)應(yīng)的方法,而在其子類中實(shí)現(xiàn)類這些方法誊役,由于不同狀態(tài)下對(duì)象的行為可能不同获列,因此在不同子類中方法的實(shí)現(xiàn)可能存在不同,相同的方法可以寫(xiě)在抽象狀態(tài)類中蛔垢。
  3. ConcreteState(具體狀態(tài)類):它是抽象狀態(tài)類的子類击孩,每一個(gè)子類實(shí)現(xiàn)一個(gè)與環(huán)境類的一個(gè)狀態(tài)相關(guān)的行為,每一個(gè)具體狀態(tài)類對(duì)應(yīng)環(huán)境的一個(gè)具體狀態(tài)啦桌,不同的具體狀態(tài)類其行為有所不同溯壶。

3). 典型代碼

  1. 抽象狀態(tài)類
/**
 * 抽象狀態(tài)類
 */
abstract class State {
    // 聲明抽象業(yè)務(wù)方法不同的具體狀態(tài)類可以不同的實(shí)現(xiàn)
    public abstract void handle();

    // 【可選】在狀態(tài)類中根據(jù)環(huán)境類屬性值進(jìn)行狀態(tài)轉(zhuǎn)換:當(dāng)然也可以寫(xiě)在環(huán)境類中。
    public void changeState(Context ctx) {
        // 狀態(tài)轉(zhuǎn)換邏輯
    }
}

抽象狀態(tài)類中可以實(shí)現(xiàn)通用的方法

  1. 環(huán)境類
/**
 * 環(huán)境類
 */
class Context {
    // 維持一個(gè)對(duì)抽象狀態(tài)的引用
    private State state;

    // 其他屬性值甫男,該屬性值的變化可能會(huì)導(dǎo)致對(duì)象狀態(tài)發(fā)生變化
    private int value;

    // 設(shè)置對(duì)象狀態(tài)
    public void steState(State state) {
        this.state = state;
    }

    // 環(huán)境類中且改,根據(jù)屬性值進(jìn)行狀態(tài)轉(zhuǎn)換:當(dāng)然,也可以在狀態(tài)類中實(shí)現(xiàn)
    public void changeState() {
        // 判斷轉(zhuǎn)換代碼
    }

    public void request() {
        // 其他代碼

        // 調(diào)用狀態(tài)對(duì)象的業(yè)務(wù)方法
        state.handle();

        // 其他代碼
    }
}

在實(shí)際使用時(shí)板驳,它們之間可能存在更為復(fù)雜的關(guān)系又跛,State與Context之間可能也存在依賴或者關(guān)聯(lián)關(guān)系。

  1. 具體狀態(tài)類
/**
 * 狀態(tài)實(shí)例類
 */
class ConcreteState extends State {

    @Override
    public void handle() {
        // 方法具體實(shí)現(xiàn)代碼
    }

}

二若治、案例需求演示

1). 需求描述

Sunny軟件公司欲為某銀行開(kāi)發(fā)一套信用卡業(yè)務(wù)系統(tǒng)慨蓝,銀行賬戶(Account)是該系統(tǒng)的核心類之一,通過(guò)分析端幼,Sunny軟件公司開(kāi)發(fā)人員發(fā)現(xiàn)在該系統(tǒng)中礼烈,賬戶存在三種狀態(tài),且在不同狀態(tài)下賬戶存在不同的行為婆跑,具體說(shuō)明如下:

  1. 如果賬戶中余額大于等于0此熬,則賬戶的狀態(tài)為正常狀態(tài)(Normal State),此時(shí)用戶既可以向該賬戶存款也可以從該賬戶取款滑进;
  2. 如果賬戶中余額小于0犀忱,并且大于-2000,則賬戶的狀態(tài)為透支狀態(tài)(Overdraft State)扶关,此時(shí)用戶既可以向該賬戶存款也可以從該賬戶取款阴汇,但需要按天計(jì)算利息;
  3. 如果賬戶中余額等于-2000节槐,那么賬戶的狀態(tài)為受限狀態(tài)(Restricted State)搀庶,此時(shí)用戶只能向該賬戶存款拐纱,不能再?gòu)闹腥】睿瑫r(shí)也將按天計(jì)算利息哥倔;
  4. 根據(jù)余額的不同戳玫,以上三種狀態(tài)可發(fā)生相互轉(zhuǎn)換。

2). 類圖設(shè)計(jì)


狀態(tài)模式賬戶.png

3). 完整代碼

  1. 環(huán)境類
/**
 * 環(huán)境類:銀行賬戶
 */
public class Account {

    // 維持一個(gè)對(duì)抽象狀態(tài)對(duì)象的引用
    private AccountState state;

    // 開(kāi)戶名
    private String owner;

    // 賬戶余額
    private Long balance = 0L;

    public Account (String owner, Long balance) {
        this.owner = owner;
        this.balance = balance;
        // 設(shè)置初始狀態(tài)
        this.state = new NormalState(this);

        System.out.println(this.owner + "開(kāi)戶未斑,初始金額為" + this.balance + "\n---------------------------------------------");
    }

    public Long getBalance() {
        return this.balance;
    }

    public void setBalance(Long balance) {
        this.balance = balance;
    }

    public void setState(AccountState state) {
        this.state = state;
    }

    // 存款
    public void deposit(Long amount) {
        System.out.println(this.owner + "存款" + amount);
        state.deposit(amount); // 調(diào)用狀態(tài)對(duì)象的deposit()方法
        System.out.println("現(xiàn)在余額為"+ this.balance);
        System.out.println("現(xiàn)在帳戶狀態(tài)為"+ this.state.getClass().getName() + "\n---------------------------------------------");
    }

    // 取款
    public void withdraw(Long amount) {
        System.out.println(this.owner + "取款" + amount);
        state.withdraw(amount); //調(diào)用狀態(tài)對(duì)象的withdraw()方法
        System.out.println("現(xiàn)在余額為"+ this.balance);
        System.out.println("現(xiàn)在帳戶狀態(tài)為"+ this. state.getClass().getName() + "\n---------------------------------------------");
    }

    // 計(jì)算利息
    public void computeInterest() {
        state.computeInterest(); //調(diào)用狀態(tài)對(duì)象的computeInterest()方法
    }
}
  1. 抽象狀態(tài)類
/**
 * 抽象狀態(tài)類
 */
public abstract class AccountState {
    protected Account acc; // 維持一個(gè)賬戶的引用,子類可以訪問(wèn)
    public abstract void deposit(Long amount); // 存款
    public abstract void withdraw(Long amount); // 取款
    public abstract void computeInterest(); // 計(jì)算利息
    public abstract void stateCheck(); // 檢查狀態(tài)
}
  1. 具體狀態(tài)類
/**
 * 正常狀態(tài):具體狀態(tài)類
 */
public class NormalState extends AccountState {

    public NormalState(Account acc) { this.acc = acc; }

    public NormalState(AccountState state) { this.acc = state.acc; }

    // 存錢(qián)
    public void deposit(Long amount) {
        acc.setBalance(acc.getBalance() + amount);
        stateCheck();
    }

    // 取款
    public void withdraw(Long amount) {
        Long tempBalance = acc.getBalance() - amount;

        if (tempBalance < -2000) {
            System.out.println("取款額度超過(guò)上限币绩,請(qǐng)重新輸入金額蜡秽!");
            return;
        }

        acc.setBalance(tempBalance);
        stateCheck();
    }

    // 計(jì)算利息
    public void computeInterest() {
        System.out.println("正常狀態(tài),無(wú)須支付利息缆镣!");
    }

    // 狀態(tài)轉(zhuǎn)換
    public void stateCheck() {

        if (acc.getBalance() > -2000 && acc.getBalance() <= 0) {
            acc.setState(new OverdraftState(this));
        } else if (acc.getBalance() == -2000) {
            acc.setState(new RestrictedState(this));
        } else if (acc.getBalance() < -2000) {
            System.out.println("操作受限芽突!");
        }
    }
}


/**
 * 透支狀態(tài):具體狀態(tài)類
 */
public class OverdraftState extends AccountState {
    public OverdraftState(AccountState state) { this.acc = state.acc; }

    // 存錢(qián)
    public void deposit(Long amount) {
        acc.setBalance(acc.getBalance() + amount);
        stateCheck();
    }

    // 取錢(qián)
    public void withdraw(Long amount) {
        Long tempBalance = acc.getBalance() - amount;

        if (tempBalance < -2000) {
            System.out.println("取款額度超過(guò)上限,請(qǐng)重新輸入金額董瞻!");
            return;
        }

        acc.setBalance(tempBalance);
        stateCheck();
    }

    // 計(jì)算利息
    public void computeInterest() {
        System.out.println("計(jì)算利息寞蚌!");
    }

    //狀態(tài)轉(zhuǎn)換
    public void stateCheck() {

        if (acc.getBalance() > 0) {
            acc.setState(new NormalState(this));
        } else if (acc.getBalance() == -2000) {
            acc.setState(new RestrictedState(this));
        } else if (acc.getBalance() < -2000) {
            System.out.println("操作受限!");
        }
    }
}


/**
 * 受限狀態(tài):具體狀態(tài)類
 */
public class RestrictedState extends AccountState {
    public RestrictedState(AccountState state) { this.acc = state.acc; }

    // 存錢(qián)
    public void deposit(Long amount) {
        acc.setBalance(acc.getBalance() + amount);
        stateCheck();
    }

    // 取款
    public void withdraw(Long amount) {
        System.out.println("帳號(hào)受限钠糊,取款失敗");
    }

    // 計(jì)算利息
    public void computeInterest() {
        System.out.println("計(jì)算利息挟秤!");
    }

    //狀態(tài)轉(zhuǎn)換
    public void stateCheck() {
        if(acc.getBalance() > 0) {
            acc.setState(new NormalState(this));
        } else if(acc.getBalance() > -2000) {
            acc.setState(new OverdraftState(this));
        }
    }
}
  1. 客戶端測(cè)試類
/**
 * @author Liucheng
 * @since 2019-09-13
 */
public class Client {
    public static void main(String[] args) {
        Account acc = new Account("段譽(yù)",0L);
        acc.deposit(1000L);
        acc.withdraw(2000L);
        acc.deposit(3000L);
        acc.withdraw(4000L);
        acc.withdraw(1000L);
        acc.computeInterest();
    }
}

三、拓展

1). 共享狀態(tài)

在有些情況下抄伍,多個(gè)環(huán)境對(duì)象可能需要共享同一個(gè)狀態(tài)艘刚,如果希望在系統(tǒng)中實(shí)現(xiàn)多個(gè)環(huán)境對(duì)象共享一個(gè)或多個(gè)狀態(tài)對(duì)象,那么需要將這些狀態(tài)對(duì)象定義為環(huán)境類的靜態(tài)成員對(duì)象截珍。

  1. 案例需求描述

某系統(tǒng)要求兩個(gè)開(kāi)關(guān)對(duì)象要么都處于開(kāi)的狀態(tài)攀甚,要么都處于關(guān)的狀態(tài),在使用時(shí)它們的狀態(tài)必須保持一致岗喉,開(kāi)關(guān)可以由開(kāi)轉(zhuǎn)換到關(guān)秋度,也可以由關(guān)轉(zhuǎn)換到開(kāi)。

  1. 類圖設(shè)計(jì)

狀態(tài)模式開(kāi)關(guān).png
  1. 完整代碼
/**
 * 環(huán)境類
 */
public class Switch {

    //定義三個(gè)靜態(tài)的狀態(tài)對(duì)象,用于對(duì)象共享
    private static State state;
    private static State onState;
    private static State offState;

    private String name;

    public Switch(String name) {
        this.name = name;
        onState = new OnState();
        offState = new OffState();
        this.state = onState;
    }

    public void setState(State state) {
        this.state = state;
    }

    public static State getState(String type) {
        if (type.equalsIgnoreCase("on")) {
            return onState;
        }
        else {
            return offState;
        }
    }

    //打開(kāi)開(kāi)關(guān)
    public void on() {
        System.out.print(name);
        state.on(this);
    }

    //關(guān)閉開(kāi)關(guān)
    public void off() {
        System.out.print(name);
        state.off(this);
    }

}
/**
 * 抽象狀態(tài)類
 */
public abstract class State {
    public abstract void on(Switch s);
    public abstract void off(Switch s);
}


/**
 * 打開(kāi)狀態(tài)
 */
public class OnState extends State {
    public void on(Switch s) {
        System.out.println("已經(jīng)打開(kāi)钱床!");
    }
    public void off(Switch s) {
        System.out.println("關(guān)閉荚斯!");
        s.setState(Switch.getState("off"));
    }
}


/**
 * 關(guān)閉狀態(tài)
 */
public class OffState extends State {

    public void on(Switch s) {
        System.out.println("打開(kāi)!");
        s.setState(Switch.getState("on"));
    }

    public void off(Switch s) {
        System.out.println("已經(jīng)關(guān)閉诞丽!");
    }
}

/**
 * @author Liucheng
 * @since 2019-09-14
 */
public class Client {

    public static void main(String[] args) {
        Switch s1 = new Switch("開(kāi)關(guān)1");
        Switch s2 = new Switch("開(kāi)關(guān)2");

        s1.on();
        s2.on();

        s1.off();
        s2.off();

        s2.on();
        s1.on();
    }
}

2). 使用環(huán)境類實(shí)現(xiàn)狀態(tài)轉(zhuǎn)換

  1. 需求描述
    用戶單擊“放大鏡”按鈕之后屏幕將放大一倍鲸拥,再點(diǎn)擊一次“放大鏡”按鈕屏幕再放大一倍,第三次點(diǎn)擊該按鈕后屏幕將還原到默認(rèn)大小僧免。

  2. 類圖設(shè)計(jì)


放大鏡.png
  1. 完整代碼
/**
 * 環(huán)境類:屏幕類
 */
public class Screen {
    // 枚舉所有的狀態(tài)刑赶,currentState表示當(dāng)前狀態(tài)
    private State currentState;
    private State normalState;
    private State largerState;
    private State largestState;

    public Screen() {
        this.normalState = new NormalState(); // 創(chuàng)建正常狀態(tài)對(duì)象
        this.largerState = new LargerState(); // 創(chuàng)建二倍放大狀態(tài)對(duì)象
        this.largestState = new LargestState(); // 創(chuàng)建四倍放大狀態(tài)對(duì)象
        this.currentState = normalState; // 設(shè)置初始狀態(tài)
        this.currentState.display();
    }

    public void setState(State state) { this.currentState = state; }

    // 單擊事件處理方法,封轉(zhuǎn)了對(duì)狀態(tài)類中業(yè)務(wù)方法的調(diào)用和狀態(tài)的轉(zhuǎn)換
    public void onClick() {
        if (this.currentState == normalState) {
            this.setState(largerState);
            this.currentState.display();
        } else if (this.currentState == largerState) {
            this.setState(largestState);
            this.currentState.display();
        } else if (this.currentState == largestState) {
            this.setState(normalState);
            this.currentState.display();
        }
    }
}
/**
 * 抽象狀態(tài)類
 */
public abstract class State {
    public abstract void display();
}

/**
 * 正常狀態(tài)類
 */
public class NormalState extends State{
    public void display() {
        System.out.println("正常大卸谩撞叨!");
    }
}

/**
 * 二倍狀態(tài)類
 */
public class LargerState extends State{
    public void display() {
        System.out.println("二倍大薪鹱佟!");
    }
}

/**
 * 四倍狀態(tài)類
 */
public class LargestState extends State{
    public void display() {
        System.out.println("四倍大星7蟆胡岔!");
    }
}
/**
 * 客戶端測(cè)試
 * @author Liucheng
 * @since 2019-09-14
 */
public class Client {

    public static void main(String[] args) {
        Screen screen = new Screen();
        screen.onClick();
        screen.onClick();
        screen.onClick();
    }
}

四、總結(jié)

狀態(tài)模式將一個(gè)對(duì)象在不同狀態(tài)下的不同行為封裝在一個(gè)個(gè)狀態(tài)類中枷餐,通過(guò)設(shè)置不同的狀態(tài)對(duì)象可以讓環(huán)境對(duì)象擁有不同的行為靶瘸,而狀態(tài)轉(zhuǎn)換的細(xì)節(jié)對(duì)于客戶端而言是透明的,方便了客戶端的使用毛肋。在實(shí)際開(kāi)發(fā)中怨咪,狀態(tài)模式具有較高的使用頻率,在工作流和游戲開(kāi)發(fā)中狀態(tài)模式都得到了廣泛的應(yīng)用润匙,例如公文狀態(tài)的轉(zhuǎn)換诗眨、游戲中角色的升級(jí)等。

1). 優(yōu)點(diǎn)

  1. 封裝了狀態(tài)的轉(zhuǎn)換規(guī)則孕讳,在狀態(tài)模式中可以將狀態(tài)的轉(zhuǎn)換代碼封裝在環(huán)境類或者具體狀態(tài)類中匠楚,可以對(duì)狀態(tài)轉(zhuǎn)換代碼進(jìn)行集中管理,而不是分散在一個(gè)個(gè)業(yè)務(wù)方法中厂财。
  2. 將所有與某個(gè)狀態(tài)有關(guān)的行為放到一個(gè)類中芋簿,只需要注入一個(gè)不同的狀態(tài)對(duì)象即可使環(huán)境對(duì)象擁有不同的行為。
  3. 允許狀態(tài)轉(zhuǎn)換邏輯與狀態(tài)對(duì)象合成一體璃饱,而不是提供一個(gè)巨大的條件語(yǔ)句塊益咬,狀態(tài)模式可以讓我們避免使用龐大的條件語(yǔ)句來(lái)將業(yè)務(wù)方法和狀態(tài)轉(zhuǎn)換代碼交織在一起。
  4. 可以讓多個(gè)環(huán)境對(duì)象共享一個(gè)狀態(tài)對(duì)象帜平,從而減少系統(tǒng)中對(duì)象的個(gè)數(shù)幽告。

2). 缺點(diǎn)

  1. 狀態(tài)模式的使用必然會(huì)增加系統(tǒng)中類和對(duì)象的個(gè)數(shù),導(dǎo)致系統(tǒng)運(yùn)行開(kāi)銷(xiāo)增大裆甩。
  2. 狀態(tài)模式的結(jié)構(gòu)與實(shí)現(xiàn)都較為復(fù)雜冗锁,如果使用不當(dāng)將導(dǎo)致程序結(jié)構(gòu)和代碼的混亂,增加系統(tǒng)設(shè)計(jì)的難度嗤栓。
  3. 狀態(tài)模式對(duì)“開(kāi)閉原則”的支持并不太好冻河,增加新的狀態(tài)類需要修改那些負(fù)責(zé)狀態(tài)轉(zhuǎn)換的源代碼,否則無(wú)法轉(zhuǎn)換到新增狀態(tài)茉帅;而且修改某個(gè)狀態(tài)類的行為也需修改對(duì)應(yīng)類的源代碼叨叙。

3). 適用場(chǎng)景

  1. 對(duì)象的行為依賴于它的狀態(tài)(如某些屬性值),狀態(tài)的改變將導(dǎo)致行為的變化堪澎。
  2. 在代碼中包含大量與對(duì)象狀態(tài)有關(guān)的條件語(yǔ)句擂错,這些條件語(yǔ)句的出現(xiàn),會(huì)導(dǎo)致代碼的可維護(hù)性和靈活性變差樱蛤,不能方便地增加和刪除狀態(tài)钮呀,并且導(dǎo)致客戶類與類庫(kù)之間的耦合增強(qiáng)剑鞍。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市爽醋,隨后出現(xiàn)的幾起案子蚁署,更是在濱河造成了極大的恐慌,老刑警劉巖蚂四,帶你破解...
    沈念sama閱讀 222,378評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件光戈,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡遂赠,警方通過(guò)查閱死者的電腦和手機(jī)田度,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,970評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)解愤,“玉大人,你說(shuō)我怎么就攤上這事乎莉∷徒玻” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,983評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵惋啃,是天一觀的道長(zhǎng)哼鬓。 經(jīng)常有香客問(wèn)我,道長(zhǎng)边灭,這世上最難降的妖魔是什么异希? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,938評(píng)論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮绒瘦,結(jié)果婚禮上称簿,老公的妹妹穿的比我還像新娘。我一直安慰自己惰帽,他們只是感情好憨降,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,955評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著该酗,像睡著了一般授药。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上呜魄,一...
    開(kāi)封第一講書(shū)人閱讀 52,549評(píng)論 1 312
  • 那天悔叽,我揣著相機(jī)與錄音,去河邊找鬼爵嗅。 笑死娇澎,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的睹晒。 我是一名探鬼主播九火,決...
    沈念sama閱讀 41,063評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼赚窃,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了岔激?” 一聲冷哼從身側(cè)響起勒极,我...
    開(kāi)封第一講書(shū)人閱讀 39,991評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎虑鼎,沒(méi)想到半個(gè)月后辱匿,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,522評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡炫彩,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,604評(píng)論 3 342
  • 正文 我和宋清朗相戀三年匾七,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片江兢。...
    茶點(diǎn)故事閱讀 40,742評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡昨忆,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出杉允,到底是詐尸還是另有隱情邑贴,我是刑警寧澤,帶...
    沈念sama閱讀 36,413評(píng)論 5 351
  • 正文 年R本政府宣布叔磷,位于F島的核電站拢驾,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏改基。R本人自食惡果不足惜繁疤,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,094評(píng)論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望秕狰。 院中可真熱鬧稠腊,春花似錦、人聲如沸鸣哀。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,572評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)诺舔。三九已至鳖昌,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間低飒,已是汗流浹背许昨。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,671評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留褥赊,地道東北人糕档。 一個(gè)月前我還...
    沈念sama閱讀 49,159評(píng)論 3 378
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親速那。 傳聞我的和親對(duì)象是個(gè)殘疾皇子俐银,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,747評(píng)論 2 361

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