面向?qū)ο蟮牧笤瓌t——讓代碼更優(yōu)美

導(dǎo)語

讓你的代碼更加優(yōu)美。

主要內(nèi)容

  • 單一職責(zé)原則——優(yōu)化代碼的第一步
  • 開閉原則——讓程序更穩(wěn)定靈活
  • 里氏替換原則——構(gòu)建擴(kuò)展性更好的系統(tǒng)
  • 依賴倒置原則——讓項(xiàng)目擁有變化的能力
  • 接口隔離原則——讓系統(tǒng)有更高的靈活性
  • 迪米特原則——更好的可擴(kuò)展性

具體內(nèi)容

單一職責(zé)原則

單一職責(zé)原則的英文名名稱是Single Responsibility Principle,縮寫是SRP。SRP的定義是:就一個(gè)類而言稚补,應(yīng)該僅有一個(gè)引起它變化的原因性穿。簡(jiǎn)單來說,一個(gè)類中應(yīng)該是一組相關(guān)性很高的函數(shù)鹉胖、數(shù)據(jù)的封裝所宰。

比如Pear是一家電子產(chǎn)品商绒尊,它要生產(chǎn)pad,phone仔粥,watch等設(shè)備婴谱,但是有一些重復(fù)的功能,如果分別設(shè)計(jì)一套,很顯然并不劃算勘究,那么接口定義上我們就可以根據(jù)功能劃分設(shè)定單一職責(zé)的接口:

接口的定義

//可以撥打電話
interface Callable{
    void call ();
}

//可以觸摸控制
interface Touchable{
    void touch();
}

//可以消息提醒
interface MessagePromptable{
    void prompt();
}

//可以接入鍵盤
interface KeyBoardMatchable{
    void match();
}

實(shí)現(xiàn)接口的類依舊單一職責(zé)

class StandardCall implements Callable{

    @Override
    public void call() {
        System.out.println("Call to somebody!");
    }
}

class StandardTouch implements Touchable{

    @Override
    public void touch() {
        System.out.println("touch to press the button!");
    }
}

class StandardPromt implements MessagePromptable{

    @Override
    public void prompt() {
        System.out.println(" someone contact to you,sir!");
    }
}

class StandardMatch implements KeyBoardMatchable{

    @Override
    public void match() {
        System.out.println("The keyBoard is ready to work!");
    }
}

產(chǎn)品的生產(chǎn)
我們?nèi)绻谖覀儸F(xiàn)有的技術(shù)生產(chǎn)一部手機(jī),那么我們需要它能打電話斟冕,觸屏控制和消息提醒:

//在聲明這臺(tái)手機(jī)時(shí)我們就明確知道了它的功能
class MyPhone implements Callable, MessagePromptable, Touchable{

    //無需重復(fù)研發(fā)已有的技術(shù)口糕,直接裝載即可
    private Callable caller = new StandardCall();
    private MessagePromptable prompter = new StandardPromt();
    private Touchable toucher = new StandardTouch();

    @Override
    public void call() {
        caller.call();
    }

    @Override
    public void prompt() {
        prompter.prompt();
    }

    @Override
    public void touch() {
        toucher.touch();
    }
}

public class SRPTest {
    public static void main ( String [] args ){
        MyPhone phone = new MyPhone();
        phone.call();
        phone.prompt();
        phone.touch();
    }
}

假如我們需要出一款新的手機(jī),但是我們只是擁有了新的呼叫技術(shù)磕蛇,那么只需要在實(shí)現(xiàn)這項(xiàng)技術(shù)時(shí)繼承Callable接口景描,然后在之前手機(jī)new的Callable的具體實(shí)例換成新的技術(shù)即可,只需要修改一行代碼秀撇,是不是感覺棒棒的超棺。職責(zé)的單一,對(duì)于我們對(duì)于現(xiàn)有類的修改造成的影響有了約束呵燕。

那么如果我想生產(chǎn)一個(gè)Pad呢棠绘,同理啊,只需要在已有技術(shù)上裝載即可啊再扭,Pad類依舊只是單一的整合技術(shù)形成產(chǎn)品的職責(zé)氧苍,整合成產(chǎn)品和研發(fā)出技術(shù)的職責(zé)分離,為我們的類的拓展帶來了方便泛范。

class MyPad implements Touchable,KeyBoardMatchable{

    Touchable toucher = new StandardTouch();
    KeyBoardMatchable matcher = new StandardMatch();

    @Override
    public void match() {
        toucher.touch();
    }

    @Override
    public void touch() {
        matcher.match();
    }
}

下面一個(gè)例子让虐,我們的接口依舊單一職責(zé),但是接聽和撥打電話的功能往往是不可分的罢荡,他們會(huì)同時(shí)發(fā)生變化赡突,所以我們可以提供一個(gè)同時(shí)繼承兩個(gè)接口的實(shí)現(xiàn)類。

class CallAndPrompt implements Callable,MessagePromptable{

    @Override
    public void call() {
        System.out.println("Hello, I have some thing to tell you!");
    }

    @Override
    public void prompt() {
        System.out.println("Hello,what do you want to tell me!");
    }
}

//在聲明這臺(tái)手機(jī)時(shí)我們就明確知道了它的功能
class MyPhone implements Callable,MessagePromptable,Touchable{

    //無需重復(fù)研發(fā)已有的技術(shù)区赵,直接裝載即可
    private Callable caller = new CallAndPrompt();
    //不同的接口調(diào)用同一個(gè)實(shí)現(xiàn)類的不同功能
    private MessagePromptable prompter = (MessagePromptable)caller;
    private Touchable toucher = new StandardTouch();

    @Override
    public void call() {
        caller.call();
    }

    @Override
    public void prompt() {
        prompter.prompt();
    }

    @Override
    public void touch() {
        toucher.touch();
    }
}

開閉原則

開閉原則的英文全稱是Open Close Principle惭缰,縮寫是OCP,它是Java世界里最基礎(chǔ)的設(shè)計(jì)原則笼才,它指導(dǎo)我們?nèi)绾谓⒁粋€(gè)穩(wěn)定的从媚、靈活的系統(tǒng)。開閉原則的定義是:軟件中的對(duì)象(類患整、模塊拜效、函數(shù)等)應(yīng)該對(duì)于擴(kuò)展是開放的,但是各谚,對(duì)于修改是封閉的紧憾。

優(yōu)點(diǎn):按照OCP原則設(shè)計(jì)出來的系統(tǒng),降低了程序各部分之間的耦合性昌渤,其適應(yīng)性赴穗、靈活性、穩(wěn)定性都比較好。當(dāng)已有軟件系統(tǒng)需要增加新的功能時(shí)般眉,不需要對(duì)作為系統(tǒng)基礎(chǔ)的抽象層進(jìn)行修改了赵,只需要在原有基礎(chǔ)上附加新的模塊就能實(shí)現(xiàn)所需要添加的功能。增加的新模塊對(duì)原有的模塊完全沒有影響或影響很小甸赃,這樣就無須為原有模塊進(jìn)行重新測(cè)試柿汛。

如何實(shí)現(xiàn)“開-閉”原則
在面向?qū)ο笤O(shè)計(jì)中,不允許更改的是系統(tǒng)的抽象層埠对,而允許擴(kuò)展的是系統(tǒng)的實(shí)現(xiàn)層络断。換言之,定義一個(gè)一勞永逸的抽象設(shè)計(jì)層项玛,允許盡可能多的行為在實(shí)現(xiàn)層被實(shí)現(xiàn)貌笨。
解決問題關(guān)鍵在于抽象化,抽象化是面向?qū)ο笤O(shè)計(jì)的第一個(gè)核心本質(zhì)襟沮。
對(duì)一個(gè)事物抽象化锥惋,實(shí)質(zhì)上是在概括歸納總結(jié)它的本質(zhì)。抽象讓我們抓住最最重要的東西开伏,從更高一層去思考净刮。這降低了思考的復(fù)雜度,我們不用同時(shí)考慮那么多的東西硅则。換言之淹父,我們封裝了事物的本質(zhì),看不到任何細(xì)節(jié)怎虫。
在面向?qū)ο缶幊讨惺钊希ㄟ^抽象類及接口,規(guī)定了具體類的特征作為抽象層大审,相對(duì)穩(wěn)定蘸际,不需更改,從而滿足“對(duì)修改關(guān)閉”徒扶;而從抽象類導(dǎo)出的具體類可以改變系統(tǒng)的行為粮彤,從而滿足“對(duì)擴(kuò)展開放”。
對(duì)實(shí)體進(jìn)行擴(kuò)展時(shí)姜骡,不必改動(dòng)軟件的源代碼或者二進(jìn)制代碼导坟。關(guān)鍵在于抽象。

接口的定義

public interface ImageCache {
    public Bitmap get(String url);
    public void put(String url, Bitmap bmp);
}

實(shí)現(xiàn)接口

// 內(nèi)存緩存MemoryCache類
public class MemoryCache implements ImageCache {
    private LruCache<String, Bitmap> mMemeryCache;

    public MemoryCache() {
        // 初始化LRU緩存
    }
    
    @Override
    public Bitmap get(String url) {
        return mMemeryCache.get(url);
    }

    @Override
    public void put(String url, Bitmap bmp) {
        mMemeryCache.put(url, bmp);
    }
}

// SD卡緩存DiskCache類
public class DiskCache implements ImageCache {
    @Override
    public Bitmap get(String url) {
        // 改為從本地文件獲取圖片
        return null;
    }

    @Override
    public void put(String url, Bitmap bmp) {
        // 將Bitmap寫入文件中
    }
}

// 雙緩存DoubleCache類
public class DoubleCache implements ImageCache {
    ImageCache mMemoryCache = new MemoryCache();
    ImageCache mDiskCache = new mDiskCache();

    // 先從內(nèi)存中獲取圖片圈澈,如果沒有再?gòu)腟D卡中獲取
    public Bitmap get(String url) {
        public Bitmap bitmap = mMemoryCache.get(url);
        if(bitmap == null) {
            bitmap = mDiskCache.get(url);
        }
        return bitmap;
    }

    // 將圖片緩存到內(nèi)存和SD卡中
    public void put(String url, Bitmap bmp) {
        mMemoryCache.put(url, bmp);
        mDiskCache.put(url, bmp);
    }
}

實(shí)現(xiàn)圖片加載器類

public class ImageLoader {
    // 圖片緩存惫周,并設(shè)置了內(nèi)存緩存為默認(rèn)方式
    private ImageCache mImageCache = new MemoryCache();

    // 注入緩存實(shí)現(xiàn)  利用了向上轉(zhuǎn)型
    public void setImageCache(ImageCache imageCache) {
        mImageCache = imageCache;
    }

    public void displayImage(String imageUrl, ImageView imageView) {
        Bitmap bitmap = mImageCache.get(imageUrl);
        if(bitmap != null) {
            imageView.setImageBitmap(bitmap);
            return;
        }
        // 圖片沒有緩存,提交到線程池中下載圖片
        submitLoadRequest(imageUrl, imageView)
    }

    public void submitLoadRequest(final String imageUrl, final ImageView imageView) {
        // 下載圖片
        // 緩存
        mImageCache.put(imageUrl, bitmap);
     }

    // 省略其他成員變量和方法
}

調(diào)用方法

//  使用方法  只是通過傳入不同實(shí)現(xiàn)就可以切換緩存方式
ImageLoader loader = new ImageLoader();
loader.setImageCache(new MemoryCache());  // 使用內(nèi)存緩存
loader.setImageCache(new DiskCache());  // 使用SD卡緩存
loader.setImageCache(new DoubleCache());  // 使用雙緩存

// 使用自定義的圖片緩存實(shí)現(xiàn)
loader.setImageCache(new ImageCache() {
    @Override
    public Bitmap get(String url) {
        // 改為從本地文件獲取圖片
        return null;
    }

    @Override
    public void put(String url, Bitmap bmp) {
        // 將Bitmap寫入文件中
    }
    });

我們看得到通過setImageCache(ImageCache imageCache) 方式注入不同的緩存實(shí)現(xiàn)康栈,使得ImageLoader代碼變得更簡(jiǎn)單递递,健壯喷橙,提升高了它的靈活性和可擴(kuò)展性,如果還有還有新的緩存方式登舞,只需要去實(shí)現(xiàn)ImageCachej接口就可以使用了贰逾。

所以當(dāng)需求發(fā)生變化時(shí),應(yīng)該盡量通過擴(kuò)展的方式來實(shí)現(xiàn)變化菠秒,而不是通過修改已有代碼來實(shí)現(xiàn)疙剑,但要做到開閉原則,首先我們應(yīng)該先寫出更易擴(kuò)展的代碼稽煤。

里氏替換原則

里氏替換原則英文全稱是Liskov Substitution Principle,縮寫是LSP囚戚。LSP的第一種定義是:如果對(duì)每一個(gè)類型為S的對(duì)象O1酵熙,都有類型為T的對(duì)象O2,使得以T定義的所有程序P在所有的對(duì)象O1都代換成O2時(shí)驰坊,程序P的行為沒有發(fā)生變化匾二,那么類型S是類型T的子類型。
或者說是:所有引用基類的地方必須能透明地使用其子類的對(duì)象拳芙。

就像開閉原則中舉的例子察藐,創(chuàng)建了一個(gè)ImageCache,而其他緩存類都是他的實(shí)現(xiàn)類舟扎,而setImageCache(ImageCache imageCache) 需要的就是ImageCache類型分飞,這時(shí)候我們就可以使用MemoryCache,DiskCache睹限,DoubleCache來替換ImageCache的工作譬猫。ImageCache確定了規(guī)范,而新的緩存需求都可以通過實(shí)現(xiàn)它然后替換ImageCache來工作羡疗,從而保證了可擴(kuò)展性染服。

也可以看一下系統(tǒng)代碼

// 窗口類
public class Window {
    public void show(View child) {
        child.draw();
    }
}

// 建立視圖抽象,測(cè)量視圖寬高為公用代碼叨恨,繪制實(shí)現(xiàn)交給具體的子類
public abstract class View {
    public abstract void draw();
    public void measure(int width, int height) {
        // 測(cè)量視圖大小
    }
}

// 按鈕類的具體實(shí)現(xiàn)
public class Button extends View {
    public void draw() {
        // 繪制按鈕
    }
}

// TextView的具體實(shí)現(xiàn)
public class TextView extends View {
    public void draw() {
        // 繪制文本
    }
}

故里氏替換原則就是通過建立抽象柳刮,建立規(guī)范,然后在運(yùn)行時(shí)通過具體實(shí)現(xiàn)來替換掉抽象痒钝,從而保證了系統(tǒng)的擴(kuò)展性和靈活性秉颗。可見送矩,在開發(fā)過程中運(yùn)用抽象是走向代碼優(yōu)化的重要一步站宗。

開閉原則和里氏替換原則往往都是一同出現(xiàn)的,通過里氏替換原則達(dá)到對(duì)擴(kuò)展的開發(fā)益愈,對(duì)修改關(guān)閉的效果梢灭。

依賴倒置原則

依賴倒置原則英文全稱是Dependence Inversion Principle夷家,縮寫是DIP。依賴倒置原則指代了一種特定的解耦形式敏释,使得高層次的模塊不依賴于低層次的模塊的實(shí)現(xiàn)細(xì)節(jié)的目的库快,依賴模塊被顛倒了。

依賴倒置原則的三個(gè)關(guān)鍵點(diǎn):

  1. 高層次模塊不應(yīng)該依賴于底層模塊钥顽,兩者都應(yīng)該依賴其抽象义屏。
  2. 抽象不應(yīng)依賴細(xì)節(jié)。
  3. 細(xì)節(jié)應(yīng)該依賴抽象蜂大。

抽象就是指接口或者抽象類闽铐;細(xì)節(jié)就是實(shí)現(xiàn)類;高層模塊就是調(diào)用端奶浦,低層模塊就是具體實(shí)現(xiàn)類兄墅。

依賴倒置原則在Java中表現(xiàn)就是:模塊間依賴是通過抽象發(fā)生的,實(shí)現(xiàn)類之間并不產(chǎn)生直接依賴關(guān)系澳叉,其依賴關(guān)系是通過接口或抽象類產(chǎn)生的隙咸。
一句話概括:面向接口編程,或者說面向抽象編程成洗。

我們依然可以通過上面的例子繼續(xù)說明五督,代碼如下:

//  如果在ImageLoader中直接這樣寫的話
//  就是直接依賴于細(xì)節(jié)(直接依賴實(shí)現(xiàn)類)
private DoubleCache mCache = new DoubleCache();
public void setImageCache(DoublieCache cache) {
    mCache = cache;
}

而我們的代碼卻直接完成1.2.3.4這四個(gè)原則

//  依賴于抽象,通過向上轉(zhuǎn)型瓶殃,有一個(gè)默認(rèn)的實(shí)現(xiàn)類
private ImageCache mImageCache = new MemoryCache();

//  設(shè)置緩存策略充包,依賴于抽象
public void setImageCache(ImageCache imageCache) {
    mImageCache = imageCache;
}

依賴于抽象,依賴于基類遥椿,這樣當(dāng)需求發(fā)生變化误证,只需要實(shí)現(xiàn)ImageCache或者繼承已實(shí)現(xiàn)的之類都可以完成緩存功能,然后將實(shí)現(xiàn)注入到setImageCache(ImageCache imageCache)就可以了修壕。

接口隔離原則

接口隔離原則英文全稱是InterfaceSegregation Principles愈捅,縮寫是ISP。ISP的定義是:客戶端不應(yīng)該依賴它不需要的接口慈鸠±督鳎或者說類的依賴關(guān)系應(yīng)該將在最小的接口上。

接口隔離的目的是系統(tǒng)接口耦合青团,從而容易重構(gòu)譬巫、更改和重新部署。一句話:讓客戶端依賴的接口盡可能小督笆。

舉一個(gè)例子芦昔,當(dāng)我們?cè)谑褂昧鞯臅r(shí)候我們需要在finally中判斷是否為空,如果不為空需要close()它娃肿,但每次使用流咕缎,都這么寫珠十,也會(huì)讓代碼變得不優(yōu)美,這個(gè)時(shí)候我們考慮借助外力凭豪,就比如Java為我們提供了一個(gè)Closeable接口焙蹭,而它有100多個(gè)實(shí)現(xiàn)類,所以那些類都可以使用它嫂伞,代碼如下:

//  這就是修改之前的代碼 try/catch中還有try/catch
FileOutputStream fileOutputStream = null;
try {
//  邏輯省略
} catch (Exception e) {
        e.printStackTrace();
} finally {
        if (fileOutputStream != null) {
                try {
                        fileOutputStream.close();
               } catch (IOException e) {
                        e.printStackTrace();
               }
        }
}

//  寫了個(gè)CloseUtil類孔厉,然后西面提供這個(gè)靜態(tài)方法,所有實(shí)現(xiàn)了Closeable的類都可以調(diào)用這個(gè)方法
 public static void closeQuietly (Closeable closeable) {
        if (closeable != null) {
            try {
                closeable.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
}

//  我們只需要在finally中調(diào)用這一句話就好了
CloseUtil.closeQuietly(xxx);

不僅讓代碼的可讀性增加了帖努,還保證了它的重用性撰豺,這里也用到了依賴倒置原則,closeQuietly()方法的參數(shù)就一個(gè)抽象拼余,做到了我只需要知道這個(gè)對(duì)象是可關(guān)閉的污桦,其他一概不管辛,也就是作者所說的接口隔離原則姿搜。

迪米特原則

迪米特原則英文全稱為L(zhǎng)aw of Demeter寡润,縮寫是LOD捆憎,也稱為最少知識(shí)原則(Least Knowledge Principle)舅柜。LOD的定義是:一個(gè)對(duì)象應(yīng)該對(duì)其他對(duì)象有最少的了解。

通俗的講躲惰,一個(gè)類應(yīng)該對(duì)自己需要耦合或者調(diào)用的類知道的最少致份,類的內(nèi)部如何實(shí)現(xiàn)與調(diào)用者或者依賴者沒有關(guān)系,只需要知道它需要的方法即可础拨,其他的一概不管氮块,類與類之間的關(guān)系越密切,耦合度也就越大诡宗。

迪米特原則還有一個(gè)英文解釋:Only talk to your immediate friends.翻譯過來也就是說之與直接朋友進(jìn)行通信滔蝉。

還是前面的ImageLoder,緩存這塊是已經(jīng)搞定了塔沃。假如在某次加載圖片中,蝠引,緩存沒找到就需要聯(lián)網(wǎng)去服務(wù)器拿圖片,并且需要存到緩存中以備下次直接從緩存加載蛀柴,ok螃概,很快可以寫出這樣的代碼:

public class ImageLoder {
    private ImageCache mImageCache = new DoubleCache();
    //...
    public void dispalyImage(String url, ImageView imageView) {
        Bitmap bitmap = mImageCache.get(url);
        if (bitmap != null) {
            imageView.setImageBitmap(bitmap);
            return;
        }
        HttpImage4Service.down4Service(url, imageView, mImageCache);
    }
}

HttpImage4Service下載類中從網(wǎng)絡(luò)中加載圖片方法:

public static void down4Service(String url, ImageView imageView, ImageCache imageCache) {
        //...從網(wǎng)絡(luò)拉取圖片
        //回調(diào)↓
        imageView.setImageBitmap(bitmap4Service);//顯示圖片
        imageCache.put(url, bitmap4Service);//存到緩存中
    }

分析下這樣設(shè)計(jì)的耦合情況,

  • ImageLoder調(diào)用ImageCache和HttpImage4Service。
  • HttpImage4Service調(diào)用ImageCache鸽疾。

三個(gè)類之間是否知道的最少吊洼?試想一下,從網(wǎng)絡(luò)拉取圖片跟緩存這樣兩個(gè)類應(yīng)該有關(guān)聯(lián)嗎制肮?實(shí)際上是沒必要的冒窍,根據(jù)最少知識(shí)原則递沪,改進(jìn)之后應(yīng)該是下面這樣的:

public class ImageLoder {
    private ImageCache mImageCache = new DoubleCache();
    //...
    public void dispalyImage(String url, ImageView imageView) {
        Bitmap bitmap = mImageCache.get(url);
        if (bitmap != null) {
            imageView.setImageBitmap(bitmap);
            return;
        }
        bitmap=HttpImage4Service.down4Service(url);//只負(fù)責(zé)下載圖片
        imageView.setImageBitmap(bitmap);
        imageCache.put(url, bitmap);//存到緩存中
    }
}

改進(jìn)后三個(gè)類中只有ImageLoder調(diào)用HttpImage4Service和ImageCache中的方法,其余沒有任何調(diào)用關(guān)系超燃,耦合度降低区拳。

在MVP中,View層和Model層拒絕通信意乓,也是符合最少知識(shí)原則的樱调,達(dá)到降低耦合效果,同時(shí)可擴(kuò)展性會(huì)大大增加届良。

總結(jié)

應(yīng)用開發(fā)笆凌,最難的不是完成開發(fā)工作,而是維護(hù)和升級(jí)士葫。為了后續(xù)能夠很好的維護(hù)和升級(jí)乞而,我們的系統(tǒng)需要在滿足穩(wěn)定性的前提下保持以下三個(gè)特性:

  • 高可擴(kuò)展性
  • 高內(nèi)聚
  • 低耦合

更多內(nèi)容戳這里(整理好的各種文集)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市慢显,隨后出現(xiàn)的幾起案子爪模,更是在濱河造成了極大的恐慌,老刑警劉巖荚藻,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件屋灌,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡应狱,警方通過查閱死者的電腦和手機(jī)共郭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來疾呻,“玉大人除嘹,你說我怎么就攤上這事“段希” “怎么了尉咕?”我有些...
    開封第一講書人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)璃岳。 經(jīng)常有香客問我年缎,道長(zhǎng),這世上最難降的妖魔是什么矾睦? 我笑而不...
    開封第一講書人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任晦款,我火速辦了婚禮,結(jié)果婚禮上枚冗,老公的妹妹穿的比我還像新娘缓溅。我一直安慰自己,他們只是感情好赁温,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開白布坛怪。 她就那樣靜靜地躺著淤齐,像睡著了一般。 火紅的嫁衣襯著肌膚如雪袜匿。 梳的紋絲不亂的頭發(fā)上更啄,一...
    開封第一講書人閱讀 49,031評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音居灯,去河邊找鬼祭务。 笑死,一個(gè)胖子當(dāng)著我的面吹牛怪嫌,可吹牛的內(nèi)容都是我干的义锥。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼岩灭,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼拌倍!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起噪径,我...
    開封第一講書人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤柱恤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后找爱,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體梗顺,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年缴允,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了荚守。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片珍德。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡练般,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出锈候,到底是詐尸還是另有隱情薄料,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布泵琳,位于F島的核電站摄职,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏获列。R本人自食惡果不足惜谷市,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望击孩。 院中可真熱鬧迫悠,春花似錦、人聲如沸巩梢。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至胶逢,卻和暖如春姥闪,著一層夾襖步出監(jiān)牢的瞬間瘾蛋,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工秒梳, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人箕速。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓端幼,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親弧满。 傳聞我的和親對(duì)象是個(gè)殘疾皇子婆跑,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

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