設(shè)計模式 | 詳解設(shè)計模式的七大原則

一羊初、設(shè)計模式的目的

編寫軟件的過程中,程序員面臨著來自耦合性舶衬,內(nèi)聚性以及可維護(hù)性埠通,可擴(kuò)展性,重用性逛犹,靈活性等多方面的挑戰(zhàn)端辱,設(shè)計模式是為了讓程序具有更好的:

  • 代碼重用性(即相同功能的代碼,不用多次編寫)
  • 可讀性(即編程規(guī)范性虽画,便于其他程序員的閱讀和理解)
  • 可擴(kuò)展性(即當(dāng)需要增加新功能時舞蔽,非常方便,稱為可維護(hù))
  • 可靠性(即當(dāng)我們增加新的功能后码撰,對原來的功能沒有影響)
  • 使程序呈現(xiàn)高內(nèi)聚渗柿,低耦合的特性

二、設(shè)計模式七大原則

設(shè)計模式的七大原則有:

  • 單一職責(zé)原則
  • 接口隔離原則
  • 依賴倒轉(zhuǎn)原則
  • 里氏替換原則
  • 開閉原則
  • 迪米特法則
  • 合成復(fù)用原則

1脖岛、單一職責(zé)原則

概念:對類來說朵栖,即一個類應(yīng)該只負(fù)責(zé)一項職責(zé)

如類A負(fù)責(zé)兩個不同職責(zé):職責(zé)1柴梆、職責(zé)2陨溅。當(dāng)職責(zé)1需求變更而改變A類時,可能造成職責(zé)2執(zhí)行錯誤绍在,因此要將類A的粒度分解為A1门扇、A2。

單一職責(zé)原則的注意事項

  • 降低類的復(fù)雜性偿渡,一個類只負(fù)責(zé)一項職責(zé)
  • 提高類的可讀性臼寄,可維護(hù)性
  • 降低變更引起的風(fēng)險
  • 通常情況下,我們應(yīng)當(dāng)遵守單一職責(zé)原則溜宽,只有邏輯足夠簡單脯厨,才可以在代碼級違反單一職責(zé)原則(只有類中方法數(shù)量足夠少,才可以在方法級別保持單一職責(zé)原則坑质。即把“降低類的復(fù)雜性”同個分解為多個方法來實現(xiàn))合武。

2、接口隔離原則

概念:客戶端不應(yīng)該依賴它不需要的接口涡扼,即一個類對另一個類的依賴應(yīng)該建立在最小的接口上稼跳。

通俗一點來說就是一個類通過接口去依賴另一個類時,這個接口不應(yīng)該存在太多多余的方法吃沪√郎疲可以將大的接口拆分成多個小的接口

示例

我們現(xiàn)在有一個接口票彪,接口里面有五個方法红淡,然后有一個類B和類D分別實現(xiàn)了該接口。然后類A和類C分別通過這個接口去依賴類B和類D降铸,但是他們只會用到接口的部分方法在旱,第一種寫法如下:

package com.cxc.principle.segregation;

/**
 * 實現(xiàn):類B和類D分別去實現(xiàn)接口1
 *      然后類A通過接口1依賴類B(使用了1,2,3方法)
 *      類C通過接口1依賴類D(使用了1,4,5方法)
 */
public class Segregation1 {

    public static void main(String[] args) {
        A a = new A();
        a.depend1(new B()); //類A通過接口去依賴類B
    }
}

/**
 * 接口1
 */
interface Interface1{
    void operation1();
    void operation2();
    void operation3();
    void operation4();
    void operation5();
}

class B implements Interface1{
    @Override
    public void operation1() {
        System.out.println("B 實現(xiàn)了operation1");
    }

    @Override
    public void operation2() {
        System.out.println("B 實現(xiàn)了operation2");
    }

    @Override
    public void operation3() {
        System.out.println("B 實現(xiàn)了operation3");
    }

    @Override
    public void operation4() {
        System.out.println("B 實現(xiàn)了operation4");
    }

    @Override
    public void operation5() {
        System.out.println("B 實現(xiàn)了operation5");
    }
}

class D implements Interface1{
    @Override
    public void operation1() {
        System.out.println("D 實現(xiàn)了operation1");
    }

    @Override
    public void operation2() {
        System.out.println("D 實現(xiàn)了operation2");
    }

    @Override
    public void operation3() {
        System.out.println("D 實現(xiàn)了operation3");
    }

    @Override
    public void operation4() {
        System.out.println("D 實現(xiàn)了operation4");
    }

    @Override
    public void operation5() {
        System.out.println("D 實現(xiàn)了operation5");
    }
}

/**
 * A類通過Interface1依賴B類,但是只會用到1,2,3方法
 */
class A{
    public void depend1(Interface1 i){
        i.operation1();
    }
    public void depend2(Interface1 i){
        i.operation2();
    }
    public void depend3(Interface1 i){
        i.operation3();
    }
}
/**
 * C類通過Interface1依賴D類推掸,但是只會用到1,4,5方法
 */
class C{
    public void depend1(Interface1 i){
        i.operation1();
    }
    public void depend4(Interface1 i){
        i.operation4();
    }
    public void depend5(Interface1 i){
        i.operation5();
    }
}

上面這種代碼實現(xiàn)的話桶蝎,就不符合我們的接口隔離原則,接口隔離原則中強(qiáng)調(diào)我們要將接口依賴降低到最小接口谅畅,而不論是類A還是類C登渣,依賴時都并沒有使用到接口的全部方法。

因此我們要進(jìn)行改進(jìn)毡泻,將大接口分解成小接口胜茧,在此我們將接口1分為接口1,接口2和接口3:

interface Interface1{
    void operation1();
}
interface Interface2{
    void operation2();
    void operation3();
}
interface Interface3{
    void operation4();
    void operation5();
}

改進(jìn)后的實現(xiàn)如下:

package com.cxc.principle.segregation.improve;

public class Segregation1 {

    public static void main(String[] args) {
        A a = new A();
        a.depend1(new B()); //A類通過接口去依賴B類
        a.depend2(new B());
        a.depend3(new B());

        C c = new C();
        c.depend1(new D());
        c.depend4(new D());
        c.depend5(new D());
    }
}

interface Interface1{
    void operation1();
}

interface Interface2{
    void operation2();
    void operation3();
}

interface Interface3{
    void operation4();
    void operation5();
}

class B implements Interface1,Interface2 {
    @Override
    public void operation1() {
        System.out.println("B 實現(xiàn)了operation1");
    }

    @Override
    public void operation2() {
        System.out.println("B 實現(xiàn)了operation2");
    }

    @Override
    public void operation3() {
        System.out.println("B 實現(xiàn)了operation3");
    }

}

class D implements Interface1,Interface3 {
    @Override
    public void operation1() {
        System.out.println("D 實現(xiàn)了operation1");
    }

    @Override
    public void operation4() {
        System.out.println("D 實現(xiàn)了operation4");
    }

    @Override
    public void operation5() {
        System.out.println("D 實現(xiàn)了operation5");
    }
}

/**
 * A類通過Interface1依賴B類仇味,但是只會用到1,2,3方法
 */
class A{
    public void depend1(Interface1 i){
        i.operation1();
    }
    public void depend2(Interface2 i){
        i.operation2();
    }
    public void depend3(Interface2 i){
        i.operation3();
    }
}

/**
 * C類通過Interface1依賴D類呻顽,但是只會用到1,4,5方法
 */
class C{
    public void depend1(Interface1 i){
        i.operation1();
    }
    public void depend4(Interface3 i){
        i.operation4();
    }
    public void depend5(Interface3 i){
        i.operation5();
    }
}

這樣實現(xiàn)就遵守了接口隔離原則,使依賴接口降低到最小接口邪铲。

3芬位、依賴倒轉(zhuǎn)原則

依賴倒轉(zhuǎn)原則是指:

  • 高層模塊不應(yīng)該依賴低層模塊,二者都應(yīng)該依賴其抽象
  • 抽象不應(yīng)該依賴細(xì)節(jié)带到,細(xì)節(jié)應(yīng)該依賴抽象
  • 依賴倒轉(zhuǎn)的中心思想是面向接口編程
  • 依賴倒轉(zhuǎn)原則是基于這樣的設(shè)計理念:相對于細(xì)節(jié)的多變性昧碉,抽象的東西要穩(wěn)定得多。以抽象為基礎(chǔ)搭建的架構(gòu)比以細(xì)節(jié)為基礎(chǔ)的架構(gòu)要穩(wěn)定得多揽惹。在Java中被饿,抽象指的是接口或抽象類,細(xì)節(jié)就是具體的實現(xiàn)類
  • 使用接口或抽象類的目的就是制定好規(guī)范搪搏,而不涉及任何具體的操作狭握,把具體細(xì)節(jié)的任務(wù)交給他們的實現(xiàn)類去完成

依賴倒轉(zhuǎn)原則的注意事項和細(xì)節(jié)

  • 低層模塊盡量都要有抽象類或接口,或者兩者都有疯溺,程序穩(wěn)定性更好
  • 變量的聲明類型盡量是抽象類或接口论颅,這樣我們的變量引用和實際對象間哎垦,就存在一個緩沖層,利于程序擴(kuò)展和優(yōu)化
  • 繼承時遵循里氏替換原則

依賴關(guān)系傳遞的三種方式

  • 接口傳遞
  • 構(gòu)造方法傳遞
  • setter方式傳遞

示例

我們要實現(xiàn)一個簡單的用戶接收消息的功能

package com.cxc.principle.inversion;
/**
 * 方式1問題
 *      1.簡單恃疯,比較容易想到
 *      2.如果我們獲取的對象是微信漏设,短信等,則需要新增類今妄,同時Person也要增加響應(yīng)的接收方法
 *      3.解決思路:引入一個抽象的接口IReceiver郑口,表示接收者,這樣Person類與接口發(fā)現(xiàn)依賴盾鳞。
 *                 因為Email犬性,Weixin都屬于接收的范圍,他們各自實現(xiàn)IReceiver接口就可以了腾仅,就符合了依賴倒轉(zhuǎn)原則
 */
public class DependecyInversion {
    public static void main(String[] args) {
        new Person().receive(new Email());
    }
}
class Email{
    public String getInfo(){
        return "電子郵件信息:hello,world";
    }
}

//完成person接受消息的功能
class Person{
    public void receive(Email email){
        System.out.println(email.getInfo());
    }
}

上述方式中乒裆,在Person類的接收消息方法中,直接傳入了一個Email類攒砖,這樣的話如果以后有其他方式比如微信缸兔、短信等消息方式還需要多寫幾個方法。不符合依賴倒轉(zhuǎn)原則吹艇,我們可以作如下更改:將這個類替換為一個接口惰蜜,實現(xiàn)如下:

package com.cxc.principle.inversion.improve;
public class DependecyInversion {
    public static void main(String[] args) {
        Person person = new Person();
        person.receive(new Email());
        person.receive(new WeiXin());
    }
}
/**
 * 接口
 */
interface IReceiver{
    public String getInfo();
}

/**
 * 實現(xiàn)類1
 */
class Email implements IReceiver{
    public String getInfo(){
        return "電子郵件信息:hello,world";
    }
}

/**
 * 實現(xiàn)類2
 */
class WeiXin implements IReceiver{
    @Override
    public String getInfo() {
        return "微信消息:hello,ok";
    }
}
//完成person接受消息的功能
class Person{
    public void receive(IReceiver receiver){
        System.out.println(receiver.getInfo());
    }
}

4、里氏替換原則

OO中的繼承性的思考和說明

  • 繼承包含這樣一層含義:父類中凡是已經(jīng)實現(xiàn)好的方法受神,實際上是在設(shè)定規(guī)范和契約抛猖,雖然它不強(qiáng)制要求所有的子類必須遵循這些契約,但是如果子類對這些已經(jīng)實現(xiàn)的方法任意修改鼻听,就會對整個繼承體系造成破壞财著。
  • 繼承在給程序設(shè)計帶來便利的同時,也帶來了弊端撑碴。比如使用繼承會給程序帶來侵入性撑教,程序的可移植性降低,增加對象間的耦合性醉拓,如果一個類被其他的類所繼承伟姐,則當(dāng)這個類需要修改時,必須考慮到所有的子類亿卤,并且父類修改后愤兵,所有涉及到子類的功能都有可能產(chǎn)生故障。

里氏替換原則

  • 如果對每個類型為T1的對象o1排吴,都有類型為T2的對象o2秆乳,使得以T1定義的所有程序P在所有的對象o1都代換成o2時,程序P的行為沒有發(fā)生變化,那么類型T2是類型T1的子類型屹堰。換句話說肛冶,所有引用基類的地方必須能透明的使用其子類的對象。
  • 在使用繼承時双藕,遵循里氏替換原則淑趾,在子類中盡量不要重寫父類的方法。
  • 里氏替換原則告訴我們忧陪,繼承實際上讓兩個類耦合性增強(qiáng)了,在適當(dāng)?shù)那闆r下近范,可以通過聚合嘶摊,組合,依賴來解決問題评矩。
  • 我們可以讓原來的父類和子類都繼承一個更通俗的基類叶堆,原有的繼承關(guān)系去掉,采用依賴斥杜,聚合虱颗,組合燈關(guān)系代替。

5蔗喂、開閉原則

  • 開閉原則是編程中最基礎(chǔ)忘渔、最重要的設(shè)計原則。
  • 一個軟件實體如類缰儿,模塊和函數(shù)應(yīng)該對外擴(kuò)展開放(對提供方)畦粮,對修改關(guān)閉(對使用方)。用抽象構(gòu)建框架乖阵,用實現(xiàn)擴(kuò)展細(xì)節(jié)宣赔。
  • 當(dāng)軟件需要變化時,盡量通過擴(kuò)展軟件實體的行為來實現(xiàn)變化瞪浸,而不是通過修改已有的代碼來實現(xiàn)變化儒将。
  • 編程中遵循其它原則,以及使用涉及模式的目的就是遵循開閉原則对蒲。

示例

有一個畫圖類如下:

package com.cxc.principle.ocp;

public class Ocp {

    public static void main(String[] args) {
        GraphicEditor graphicEditor = new GraphicEditor();
        graphicEditor.drawShape(new Rectangle());
        graphicEditor.drawShape(new Circle());
        graphicEditor.drawShape(new Triangle());
    }

}
class GraphicEditor {
    public void drawShape(Shape s) {
        if (s.m_type == 1)
            drawRectangle(s);
        else if (s.m_type == 2)
            drawCircle(s);
        else if (s.m_type == 3)
            drawTriangle(s);
    }

    //三角形
    public void drawRectangle(Shape r) {
        System.out.println("三角形 ");
    }
    //圓形
    public void drawCircle(Shape r) {
        System.out.println(" 圓形 ");
    }
    //矩形
    public void drawTriangle(Shape r) {
        System.out.println(" 矩形 ");
    }
}

class Shape {
    int m_type;
}
class Rectangle extends Shape {
    Rectangle() {
        super.m_type = 1;
    }
}
class Circle extends Shape {
    Circle() {
        super.m_type = 2;
    }
}
class Triangle extends Shape {
    Triangle() {
        super.m_type = 3;
    }
}

上述例子中钩蚊,如果要新增一個其他的圖形類,那么在GraphicEditor類中也要更改代碼來加上掉這個圖形類的處理齐蔽,不滿足開閉原則两疚。因此我們應(yīng)該修改為:把Shape做成抽象類,并提供一個抽象的draw方法含滴,讓子類去實現(xiàn):

package com.cxc.principle.ocp.improve;
public class Ocp {
    public static void main(String[] args) {

        GraphicEditor graphicEditor = new GraphicEditor();
        graphicEditor.drawShape(new Rectangle());
        graphicEditor.drawShape(new Circle());
        graphicEditor.drawShape(new Triangle());
        graphicEditor.drawShape(new OtherGraphic());
    }
}
class GraphicEditor {
    public void drawShape(Shape s) {
        s.draw();
    }
    
}

//抽象類
abstract class Shape {
    int m_type;
    
    public abstract void draw();
}

class Rectangle extends Shape {
    Rectangle() {
        super.m_type = 1;
    }

    @Override
    public void draw() {
        // TODO Auto-generated method stub
        System.out.println(" 三角形 ");
    }
}

class Circle extends Shape {
    Circle() {
        super.m_type = 2;
    }
    @Override
    public void draw() {
        // TODO Auto-generated method stub
        System.out.println(" 圓形 ");
    }
}


class Triangle extends Shape {
    Triangle() {
        super.m_type = 3;
    }
    @Override
    public void draw() {
        // TODO Auto-generated method stub
        System.out.println(" 矩形 ");
    }
}
class OtherGraphic extends Shape {
    OtherGraphic() {
        super.m_type = 4;
    }

    @Override
    public void draw() {
        // TODO Auto-generated method stub
        System.out.println(" 其他圖形 ");
    }
}

改進(jìn)后诱渤,如果想加入其他圖形類,直接繼承抽象類然后實現(xiàn)抽象方法即可谈况,不用去更改抽象類勺美。做到了對外擴(kuò)展開放(對提供方)递胧,對修改關(guān)閉(對使用方)

6、迪米特法則

  • 一個對象應(yīng)該對其他對象保持最少的了解
  • 類與類關(guān)系越密切赡茸,耦合度越大
  • 迪米特法則又叫最少知道原則缎脾,即一個類對自己依賴的類知道的越少越好,也就是說占卧,對于被依賴的類不管多么復(fù)雜遗菠,都盡量將邏輯封裝在類的內(nèi)部,對外除了提供的public方法华蜒,不對外泄露任何信息
  • 迪米特法則還有個更簡單的定義:只與直接的朋友通信
  • 直接的朋友:每個對象都會與其他對象有耦合關(guān)系辙纬,只要兩個對象之間有耦合關(guān)系,我們就說這兩個對象之間是朋友關(guān)系叭喜,耦合的方式很多贺拣,依賴,關(guān)聯(lián)捂蕴,組合譬涡,聚合等。其中啥辨,我們稱出現(xiàn)成員變量涡匀,方法參數(shù),方法返回值中的類為直接的朋友委可,而出現(xiàn)在局部變量中的類不是直接的朋友渊跋。也就是說,陌生的類最好不要以全局變量的形式出現(xiàn)在類的內(nèi)部着倾。

示例

有一個學(xué)校拾酝,下屬有各個學(xué)院和總部,現(xiàn)要求打印出學(xué)锌ㄕ撸總部員工id和學(xué)院員工id蒿囤。

package com.cxc.principle.demeter;

import java.util.ArrayList;
import java.util.List;
public class Demeter1 {

    public static void main(String[] args) {
        SchoolManager schoolManager = new SchoolManager();
        schoolManager.printAllEmployee(new CollegeManager());

    }

}
//學(xué)校總部員工類
class Employee {
    private String id;

    public void setId(String id) {
        this.id = id;
    }

    public String getId() {
        return id;
    }
}
//學(xué)院員工
class CollegeEmployee {
    private String id;

    public void setId(String id) {
        this.id = id;
    }

    public String getId() {
        return id;
    }
}

//管理學(xué)院員工的管理類
class CollegeManager {
    //返回學(xué)院的所有員工
    public List<CollegeEmployee> getAllEmployee() {
        List<CollegeEmployee> list = new ArrayList<CollegeEmployee>();
        for (int i = 0; i < 10; i++) {
            CollegeEmployee emp = new CollegeEmployee();
            emp.setId("學(xué)院員工id= " + i);
            list.add(emp);
        }
        return list;
    }
}

//學(xué)校管理類
//分析 SchoolManager的直接朋友: Employee崇决、CollegeManager
//CollegeEmployee 不是直接朋友材诽,這樣違背了迪米特法則
class SchoolManager {
    //返回學(xué)校總部的員工
    public List<Employee> getAllEmployee() {
        List<Employee> list = new ArrayList<Employee>();
        
        for (int i = 0; i < 5; i++) {
            Employee emp = new Employee();
            emp.setId("學(xué)泻闵担總部的員工id= " + i);
            list.add(emp);
        }
        return list;
    }

    //輸入學(xué)校員工和學(xué)院員工信息
    void printAllEmployee(CollegeManager sub) {
        
        //分析問題
        //1. 這里的 CollegeEmployee 不是  SchoolManager的直接朋友
        //2. CollegeEmployee 是以局部變量方式出現(xiàn)在 SchoolManager
        //3. 違反了迪米特法則
        
        //獲取到學(xué)院員工
        List<CollegeEmployee> list1 = sub.getAllEmployee();
        System.out.println("------------學(xué)院員工------------");
        for (CollegeEmployee e : list1) {
            System.out.println(e.getId());
        }
        //獲取到學(xué)辛辰模總部員工
        List<Employee> list2 = this.getAllEmployee();
        System.out.println("------------學(xué)校總部員工------------");
        for (Employee e : list2) {
            System.out.println(e.getId());
        }
    }
}

上述示例違反了迪米特法則盈厘,那么應(yīng)該如何改進(jìn)呢睁枕?
printAllEmployee方法里面輸出學(xué)院員工的代碼封裝到學(xué)院員工管理類CollegeManager中:

//管理學(xué)院員工的管理類
class CollegeManager {
    //返回學(xué)院的所有員工
    public List<CollegeEmployee> getAllEmployee() {
        List<CollegeEmployee> list = new ArrayList<CollegeEmployee>();
        for (int i = 0; i < 10; i++) {
            CollegeEmployee emp = new CollegeEmployee();
            emp.setId("學(xué)院員工id= " + i);
            list.add(emp);
        }
        return list;
    }

    //輸出學(xué)院員工的信息
    public void printEmployee(){
        List<CollegeEmployee> list1 = getAllEmployee();
        System.out.println("------------學(xué)院員工------------");
        for (CollegeEmployee e : list1) {
            System.out.println(e.getId());
        }
    }
}

對應(yīng)的printAllEmployee方法調(diào)用我們封裝的方法即可:

//輸入學(xué)校員工和學(xué)院員工信息
    void printAllEmployee(CollegeManager sub) {
        //輸出學(xué)院的員工
        sub.printEmployee();

        //獲取到學(xué)校總部員工
        List<Employee> list2 = this.getAllEmployee();
        System.out.println("------------學(xué)校總部員工------------");
        for (Employee e : list2) {
            System.out.println(e.getId());
        }
    }

迪米特法則注意事項和細(xì)節(jié)

  • 迪米特法則的核心是降低類之間的耦合
  • 但是注意:由于每個類都減少了不必要的依賴外遇,因此迪米特法則只是要求降低類間(對象間)的耦合關(guān)系注簿,并不是要求完全沒有依賴關(guān)系

7、合成復(fù)用原則

  • 原則是盡量使用合成/聚合的方式跳仿,而不是使用繼承



    上圖中的1就是使用繼承诡渴,這樣就會增強(qiáng)類的耦合性,而2,3,4使用的是組合/合成/聚合的方式菲语,這樣就可以降低類的耦合性妄辩。

設(shè)計原則核心思想

其實歸結(jié)到底就是要注意以下幾點:

  • 找出應(yīng)用中可能需要變化之處,把他們獨立出來
  • 針對接口編程山上,而不是針對實現(xiàn)編程
  • 為了交互對象之間的松耦合設(shè)計而努力
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末恩袱,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子胶哲,更是在濱河造成了極大的恐慌,老刑警劉巖潭辈,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鸯屿,死亡現(xiàn)場離奇詭異,居然都是意外死亡把敢,警方通過查閱死者的電腦和手機(jī)寄摆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來修赞,“玉大人婶恼,你說我怎么就攤上這事“馗保” “怎么了勾邦?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長割择。 經(jīng)常有香客問我眷篇,道長,這世上最難降的妖魔是什么荔泳? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任蕉饼,我火速辦了婚禮,結(jié)果婚禮上玛歌,老公的妹妹穿的比我還像新娘昧港。我一直安慰自己,他們只是感情好支子,可當(dāng)我...
    茶點故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布创肥。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪瓤的。 梳的紋絲不亂的頭發(fā)上休弃,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天,我揣著相機(jī)與錄音圈膏,去河邊找鬼塔猾。 笑死,一個胖子當(dāng)著我的面吹牛稽坤,可吹牛的內(nèi)容都是我干的丈甸。 我是一名探鬼主播,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼尿褪,長吁一口氣:“原來是場噩夢啊……” “哼睦擂!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起杖玲,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤顿仇,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后摆马,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體臼闻,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年囤采,在試婚紗的時候發(fā)現(xiàn)自己被綠了述呐。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,094評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡蕉毯,死狀恐怖乓搬,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情代虾,我是刑警寧澤进肯,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站褐着,受9級特大地震影響坷澡,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜含蓉,卻給世界環(huán)境...
    茶點故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一频敛、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧馅扣,春花似錦斟赚、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽任洞。三九已至,卻和暖如春发侵,著一層夾襖步出監(jiān)牢的瞬間交掏,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工刃鳄, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留盅弛,地道東北人。 一個月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓叔锐,卻偏偏與公主長得像挪鹏,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子愉烙,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,828評論 2 345