ddd初探--落地實(shí)踐

一.前言

ddd出現(xiàn)的意義在于從業(yè)務(wù)的角度而不是技術(shù)的角度去解決軟件的復(fù)雜性茂契,正如某位大師所言:“program is logic and control”,所有的程序本質(zhì)上就是兩件事:邏輯和控制,而邏輯則是決定了復(fù)雜性的下限望薄。舉個(gè)例子槽驶,商品交易的業(yè)務(wù)邏輯復(fù)雜性天然就勝過(guò)im聊天的業(yè)務(wù)邏輯,這種時(shí)候無(wú)論怎樣拆解蚯瞧,它的業(yè)務(wù)復(fù)雜性就擺在這里嘿期,而控制是我們盡可能用最優(yōu)的手段去實(shí)現(xiàn)我們的邏輯,這里有點(diǎn)類似于面向?qū)ο笾新窈希涌诤蛯?shí)現(xiàn)的感覺(jué)备徐,但又不局限于此。

對(duì)于開(kāi)發(fā)人員來(lái)說(shuō)甚颂,我們接收到現(xiàn)實(shí)世界中的需求之后蜜猾,基本上是以下的套路來(lái)解決問(wèn)題:

1.確認(rèn)現(xiàn)實(shí)問(wèn)題秀菱;

2.將問(wèn)題映射到腦海中的概念模型;

3.用模型來(lái)解決問(wèn)題蹭睡;

4.編碼

我自身之前所有學(xué)到的具體的技術(shù)或者思想其實(shí)核心都是在做第三步和第四步衍菱,即如何用最優(yōu)的技術(shù)方案和最好的編碼方案,包括我們各種高大上的架構(gòu)肩豁,各種代碼上的tricky寫(xiě)法脊串,各種算法的應(yīng)用等等,這些本質(zhì)上都是在做實(shí)現(xiàn)層面的事情清钥。

但有的時(shí)候總會(huì)在想洪规,我們?cè)O(shè)計(jì)出來(lái)的模型真的能夠表達(dá)清楚我們的真實(shí)業(yè)務(wù)嗎?未來(lái)隨著業(yè)務(wù)的變更循捺,我們的底層模型和設(shè)計(jì)真的能夠支撐這種變更嗎斩例?

如果不能,那即便我的代碼設(shè)計(jì)多么優(yōu)雅合理从橘,可能也只是當(dāng)時(shí)的一時(shí)感動(dòng)罷了念赶,每一次的需求變更都依然可能會(huì)引發(fā)復(fù)雜的代碼變更,也給自己帶來(lái)了許多的叫苦不迭恰力。

所以叉谜,ddd的目的更偏向于解決第一步和第二步,即依據(jù)業(yè)務(wù)領(lǐng)域模型為核心來(lái)驅(qū)動(dòng)我們的系統(tǒng)設(shè)計(jì)踩萎。即抽象到更高層來(lái)理解的話停局,如何定義清楚問(wèn)題和模型,而后續(xù)的實(shí)現(xiàn)方案其實(shí)是由它來(lái)驅(qū)動(dòng)的香府。

正如上面所說(shuō)的董栽,問(wèn)題和模型決定了邏輯復(fù)雜性的下限,舉個(gè)例子企孩,之前在做商品的評(píng)價(jià)服務(wù)時(shí)锭碳,產(chǎn)品需求是這樣的:用戶只允許在訂單的流轉(zhuǎn)狀態(tài)中的某幾個(gè)狀態(tài)時(shí)(拼單成功,待發(fā)貨勿璃,待退款等等)發(fā)表評(píng)價(jià)擒抛,此時(shí)展示為待評(píng)價(jià)狀態(tài),而評(píng)價(jià)完成后則訂單扭轉(zhuǎn)為已評(píng)價(jià)狀態(tài)补疑。

這個(gè)需求乍一看歧沪,我們的第一反應(yīng)是在訂單的狀態(tài)機(jī)中添加兩個(gè)狀態(tài),待評(píng)價(jià)和已評(píng)價(jià)莲组,但后來(lái)會(huì)發(fā)現(xiàn)诊胞,無(wú)論怎樣推演,加入了評(píng)價(jià)的兩個(gè)狀態(tài)之后胁编,訂單的狀態(tài)機(jī)流轉(zhuǎn)都會(huì)變得非常復(fù)雜厢钧,因?yàn)闊o(wú)論是訂單的正向還是逆向流程中,都可能會(huì)有評(píng)論的狀態(tài)的加入和退出嬉橙。那我們退一步來(lái)思考早直,雖然產(chǎn)品需求是將訂單的原狀態(tài)列表中添加是否允許評(píng)價(jià)和是否已經(jīng)評(píng)價(jià)的狀態(tài),但我們仔細(xì)拆解就會(huì)發(fā)現(xiàn)市框,評(píng)價(jià)的狀態(tài)和訂單的狀態(tài)本質(zhì)上就是兩個(gè)事情霞扬。從核心領(lǐng)域的劃分上,也是兩個(gè)領(lǐng)域枫振,一個(gè)是訂單領(lǐng)域喻圃,一個(gè)是評(píng)輪領(lǐng)域,而獲取訂單的評(píng)論狀態(tài)本質(zhì)上是屬于評(píng)論領(lǐng)域而非訂單領(lǐng)域的工作粪滤。這樣事情一下子變得簡(jiǎn)單了斧拍,一個(gè)訂單能否被評(píng)價(jià)以及是否已經(jīng)被評(píng)價(jià)過(guò)了,完全交由評(píng)論領(lǐng)域來(lái)判斷杖小,訂單無(wú)需也不該維護(hù)和添加這么一個(gè)狀態(tài)肆汹。


所以使用ddd,是為了很好地解決領(lǐng)域模型到設(shè)計(jì)模型的同步予权、演化昂勉,最后再將反映了領(lǐng)域的設(shè)計(jì)模型轉(zhuǎn)為實(shí)際的代碼。

二.ddd的基本概念

官方的解釋是這樣的:領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)(Domain-driven design扫腺,縮寫(xiě) DDD)是一種通過(guò)將實(shí)現(xiàn)連接到持續(xù)進(jìn)化的模型來(lái)滿足復(fù)雜需求的軟件開(kāi)發(fā)方法岗照。這個(gè)說(shuō)起來(lái)實(shí)在是有點(diǎn)太虛無(wú)縹緲了,還記得上文中提到的解決問(wèn)題的四個(gè)步驟笆环,那現(xiàn)在如果用ddd的思路來(lái)指導(dǎo)攒至,應(yīng)該是怎樣的呢?

1.確認(rèn)現(xiàn)實(shí)問(wèn)題躁劣;---和領(lǐng)域?qū)<遥óa(chǎn)品經(jīng)理等)一起嗓袱,通過(guò)多次的拆解,交流和溝通习绢,構(gòu)建一套整個(gè)項(xiàng)目統(tǒng)一的領(lǐng)域語(yǔ)言渠抹,并用這些領(lǐng)域語(yǔ)言定義清楚具體的原型,操作和邏輯闪萄。

2.將問(wèn)題映射到腦海中的概念模型梧却;----基于上述的統(tǒng)一語(yǔ)言,構(gòu)建出ddd中的領(lǐng)域模型败去,包括領(lǐng)域?qū)嶓w放航,上下文的邊界,領(lǐng)域事件圆裕,聚合等等广鳍;

3.用模型來(lái)解決問(wèn)題荆几;----在ddd的思路下劃分微服務(wù),設(shè)計(jì)包結(jié)構(gòu)赊时,分層設(shè)計(jì)吨铸,定義接口,定義聚合根等等

4.編碼祖秒;----編碼實(shí)現(xiàn)


三.用ddd的思路做方案設(shè)計(jì)

以我最近一段時(shí)間做的津貼系統(tǒng)為例诞吱,來(lái)看下如何做具體的方案設(shè)計(jì)與拆解;

1.首先竭缝,明確產(chǎn)品需求和用例:

在用戶側(cè)房维,分三個(gè)操作:

收入:要能夠做到津貼能夠以多種形式和渠道來(lái)發(fā)放和領(lǐng)取,同時(shí)要保證每一筆津貼收入都有有效期的概念(包括開(kāi)始生效和結(jié)束生效)抬纸,同時(shí)要求這個(gè)時(shí)間必須十分精準(zhǔn)咙俩,比如在大促時(shí),要求大促期間生效的津貼必須在定點(diǎn)失效和生效湿故。

支出:要求支出的時(shí)候可以合并支出暴浦,并且能夠按照有效期快失效的先支出;

退還:要求支持退還的操作晓锻,但已經(jīng)失效的則不再退還歌焦;

在平臺(tái)側(cè):

創(chuàng)建津貼:制定特定規(guī)則的津貼,比如有效期等砚哆;

發(fā)放津貼:通過(guò)各種各樣的形式發(fā)放給用戶独撇;

2.確認(rèn)各個(gè)業(yè)務(wù)核心領(lǐng)域的邊界劃分:

首先我們可以發(fā)現(xiàn),津貼的領(lǐng)取其實(shí)是由上層系統(tǒng)所驅(qū)動(dòng)的躁锁,最終經(jīng)過(guò)一定的規(guī)則之后發(fā)放到用戶的個(gè)人津貼賬戶上纷铣,通過(guò)大量的討論和梳理之后,我們會(huì)在這里發(fā)生第一次的業(yè)務(wù)領(lǐng)域劃分战转,我們將領(lǐng)取劃分為了四個(gè)子業(yè)務(wù)領(lǐng)域:

1.上層的發(fā)放渠道搜立,比如紅包領(lǐng)域,任務(wù)領(lǐng)域等等槐秧,這里負(fù)責(zé)計(jì)算用戶是否滿足了某些條件啄踊,然后可以自由組合并決定給用戶的發(fā)放金額。

2.津貼控制領(lǐng)域:這里負(fù)責(zé)津貼規(guī)則的制定刁标,以及如何發(fā)放颠通,比如津貼的有效期,津貼的領(lǐng)取個(gè)數(shù)限制膀懈,防重入的控制等等(由于時(shí)間關(guān)系顿锰,一部分限額限次數(shù)等邏輯目前移交給上層渠道做了,但應(yīng)該有這么個(gè)領(lǐng)域存在);

3.個(gè)人津貼賬戶領(lǐng)域:這里是最終發(fā)放到的個(gè)人賬戶上硼控,負(fù)責(zé)管理用戶的津貼賬戶刘陶,包括收入,支出和退還等等牢撼;

4.支付與核銷領(lǐng)域:負(fù)責(zé)用戶真正使用津貼支付的邏輯匙隔,比如與財(cái)務(wù)的核銷,平臺(tái)側(cè)資金的支出與商戶的資金收入等等浪默;

這里核心領(lǐng)域劃分清楚之后牡直,其實(shí)就有點(diǎn)映射到了我們微服務(wù)的劃分缀匕,也對(duì)應(yīng)到了人員的劃分纳决,這時(shí)候任務(wù)就開(kāi)始拆解了,我們會(huì)發(fā)現(xiàn)其實(shí)上層的發(fā)放渠道與津貼其實(shí)是基本無(wú)關(guān)的乡小,那就從我們的核心領(lǐng)域移除了出去阔加,我們目前重點(diǎn)關(guān)心了一個(gè)領(lǐng)域,個(gè)人賬戶满钟;

以個(gè)人賬戶領(lǐng)域?yàn)槔だ疲俏覀兊臉I(yè)務(wù)領(lǐng)域核心目前就比較聚合了,只關(guān)注津貼的入賬和出帳湃番,以及內(nèi)部的生效和失效夭织,其他的都無(wú)需關(guān)注。

3.確認(rèn)核心領(lǐng)域中的模型與邊界上下文:

1.為了滿足產(chǎn)品設(shè)計(jì)中津貼支出時(shí)能夠一次性的合并支付吠撮,因此我們定義了用戶總賬戶的概念尊惰,即每個(gè)用戶用擁有一個(gè)個(gè)人的總賬戶,支持在下單時(shí)扣減這個(gè)總額泥兰,所以是津貼實(shí)體匯總在一起之后有個(gè)總賬戶弄屡;

2.為了滿足有效性的需求(尤其是準(zhǔn)時(shí)準(zhǔn)點(diǎn)的生效失效),我們將每個(gè)用戶總帳戶又分為三個(gè)部分鞋诗,預(yù)生效(當(dāng)晚23:59:59秒開(kāi)始生效)膀捷,預(yù)失效(當(dāng)晚23:59:59秒開(kāi)始失效),普通(生效期內(nèi)可直接扣減)削彬,這樣即使更新腳本不及時(shí)全庸,也可以通過(guò)這三個(gè)子賬戶決定可以支出的總金額;

3.為了滿足退還有效性的需求融痛,我們定義了津貼實(shí)體和支付訂單的概念糕篇,用來(lái)標(biāo)示每一筆聚合的支出包含了哪些具體的津貼實(shí)體的支出,用來(lái)做將來(lái)的退還酌心。

4.為了保障數(shù)據(jù)的可追溯和可恢復(fù)拌消,我們定義了用戶流水的概念,包括收入流水,支出流水墩崩,退款流水氓英,更新流水等。

所以在我們的模型設(shè)計(jì)中鹦筹,通過(guò)流水可以重放出每一筆津貼實(shí)體铝阐,每一筆津貼實(shí)體聚合起來(lái)可以導(dǎo)出用戶總額。

而在這個(gè)領(lǐng)域下铐拐,所有的模型定義都是在我們這個(gè)邊界下是明確且獨(dú)立的徘键,比如說(shuō)對(duì)于上層的紅包系統(tǒng)來(lái)說(shuō),它所謂的發(fā)"一筆津貼"遍蟋,實(shí)質(zhì)上是對(duì)應(yīng)我們這里的津貼實(shí)體吹害。對(duì)于上層的交易系統(tǒng)來(lái)說(shuō),它所謂的支付"一筆津貼"虚青,對(duì)應(yīng)的其實(shí)是我們的總額它呀。所以即便是同一個(gè)名詞,在不同的核心領(lǐng)域下棒厘,也是映射著不同的含義纵穿。


接下來(lái),我們看下如何ddd如何指導(dǎo)我們做具體的代碼編寫(xiě)

四.用ddd的思路編寫(xiě)代碼

1.分層設(shè)計(jì):

如下圖所示:

如果我們只是簡(jiǎn)單的增刪改查奢人,其實(shí)是不需要這么麻煩的谓媒,甚至我們完全可以不需要這么多層,只需要把業(yè)務(wù)邏輯退化為一個(gè)sql腳本就可以支持了何乎,但如果業(yè)務(wù)邏輯比較復(fù)雜的情況下句惯,我們一定必不可少的要做的事情就是關(guān)注點(diǎn)的分離,但在分離的同時(shí)也要保證內(nèi)部的交互關(guān)系宪赶。這其中宗弯,領(lǐng)域?qū)邮钦麄€(gè)模型的精髓,


那在golang里面是怎樣的呢搂妻?目前我們的分包設(shè)計(jì)是這樣的:

---ao:負(fù)責(zé)編排do和對(duì)外界的協(xié)議防腐層

---infra:基礎(chǔ)設(shè)施層蒙保,

? ? --dao:數(shù)據(jù)庫(kù)層,封裝了基本的數(shù)據(jù)庫(kù)實(shí)現(xiàn)欲主,比如各個(gè)表的增刪改查邓厕,數(shù)據(jù)庫(kù)的事務(wù)實(shí)現(xiàn)等等;

? ? --integration:第三方接口扁瓢,包括rpc接口详恼,mq的producer等;

---do:核心領(lǐng)域?qū)?/p>

---impl:核心領(lǐng)域?qū)訉?shí)現(xiàn)

? ? beanfatory:impl下的文件引几,負(fù)責(zé)所有的實(shí)例化昧互,包括單個(gè)do的build,以及一些單例的dao和service的構(gòu)建

---service:對(duì)外接口層,包括rpc接口和mq的consumer等等敞掘;


2.領(lǐng)域?qū)釉O(shè)計(jì):

正如我們前面所說(shuō)叽掘,一切以領(lǐng)域驅(qū)動(dòng),那我們編寫(xiě)代碼的時(shí)候也是玖雁,先想清楚自己的系統(tǒng)功能以及邊界更扁,那第一步是設(shè)計(jì)對(duì)外的協(xié)議,第二步就是定義我們的領(lǐng)域?qū)幽P停?/p>

目前我這邊把領(lǐng)域?qū)拥膁o分為了三類:

a: 實(shí)體類do:

這類模型是擁有真實(shí)的實(shí)體赫冬,能夠被定義成實(shí)體的模型有一個(gè)最大的特點(diǎn):具有唯一標(biāo)識(shí)性浓镜。即在我們當(dāng)前的系統(tǒng)上下文內(nèi),它需要能夠通過(guò)這個(gè)唯一標(biāo)識(shí)被追溯到劲厌。通常這類實(shí)體還會(huì)有一些自身的方法膛薛,與貧血模型相對(duì)的,我們更希望實(shí)體自身能夠表達(dá)自己的屬性和動(dòng)作脊僚,而不是把自己的領(lǐng)域邏輯散落在其他地方相叁;

b:聚合類do:

有很多情況下遵绰,是需要將實(shí)體和值對(duì)象們組合到一起做服務(wù)的辽幌,設(shè)計(jì)聚合的最大原則在于,要滿足聚合的一致性邊界椿访;

舉個(gè)例子乌企,我們系統(tǒng)對(duì)外要提供用戶的收入服務(wù),那這個(gè)核心的領(lǐng)域模型就需要針對(duì)一筆入賬成玫,要做三件事情加酵,第一,插入一筆收入流水哭当,第二:插入一條津貼實(shí)體猪腕;第三,更新用戶的總額度钦勘。

這個(gè)聚合的一致性原則在于:

這三件事情陋葡,要么同時(shí)發(fā)生,要么直接失敵共伞腐缤;其實(shí)就是一個(gè)事務(wù)操作

那很明顯,在這種情況下肛响,單一的實(shí)體總額度或者津貼實(shí)體都不能直接在自己的實(shí)體方法中執(zhí)行修改操作岭粤,因?yàn)檫@樣會(huì)造成整體的不一致,那這種時(shí)候特笋,我們是這樣處理的:

首先是三個(gè)實(shí)體:

type AllowanceEntity{

EnttyId uint64

UID uint64

Amount uint64

xxxx...

}

type AllowanceIncomeRecord{

RecordId uint64

UID uint64

Amount uint64

xxxx...

}

tyoe TotalAmountEntity{

UID uint64

Amount uint64

}

然后是聚合:

type IncomeAggregate struct{

TotalAmountEntity TotalAmountEntity

allowanceIncomeRecord AllowanceIncomeRecord

allowanceEntity AllowanceEntity

}

注意剃浇,這里很明顯,這個(gè)聚合,外界能夠訪問(wèn)到它的聚合根也就是總額度虎囚,但是無(wú)法訪問(wèn)到其他的對(duì)象臼寄,因?yàn)槠渌麑?duì)象可以看作是它的私有屬性,不對(duì)外暴露溜宽,這一點(diǎn)我覺(jué)得golang通過(guò)大小寫(xiě)區(qū)分有點(diǎn)容易分不清吉拳。

然后對(duì)于聚合來(lái)說(shuō),聚合根是可以被外界訪問(wèn)到的,所以如果從封裝的角度出發(fā)适揉,按照golang的思路這里其實(shí)應(yīng)該作為一個(gè)子包存在留攒,但這樣總覺(jué)得有點(diǎn)太細(xì)粒度,所以還在探索中嫉嘀。

最后炼邀,津貼總額提供一個(gè)cqs查詢方法,將寫(xiě)操作轉(zhuǎn)換為一個(gè)讀操作剪侮,保證了實(shí)體沒(méi)有被修改拭宁,我自己實(shí)踐后認(rèn)為,這樣的好處在于瓣俯,在項(xiàng)目里有一大堆代碼的時(shí)候杰标,我可以很清楚的知道,只要是有返回值的方法彩匕,就一定不會(huì)對(duì)原來(lái)的實(shí)例有任何的修改腔剂,這樣可以很好的節(jié)省我們的思考成本。

func (s*TotalAmountEntity) afterIncome(ctx context.context,entity AllowanceEntity) TotalAmountEntity{

copy:=s.copy()

copy.amount+=entity.amount;

return copy

}

津貼實(shí)體提供一個(gè)init方法:

津貼記錄提供一個(gè)init方法:

最終在聚合中是一個(gè)類似如下的函數(shù):

func(s*Aggregate) Income(ctx context.context,params xxxx){

//創(chuàng)建流水

s.record:=initRecord()

//創(chuàng)建津貼實(shí)體

s.entity:=initEntity()

//更新總額度

s.total=s.total.afterIncome(ctx,s.entity)

//持久化聚合內(nèi)的全部實(shí)體

persist(s.record,s.entity,s.total)

}

那這就是一個(gè)聚合驼仪,聚合的最大特點(diǎn)在于掸犬,在聚合的邊界內(nèi)保證數(shù)據(jù)的一致性,也就是說(shuō)绪爸,在上面那個(gè)income方法里湾碎,這三者的變更是一致的,不存在產(chǎn)生了流水奠货,卻沒(méi)有插入津貼實(shí)體這種事情存在介褥。

c:service方法

其實(shí)就是有點(diǎn)像膠水代碼,本身并沒(méi)有太多的復(fù)雜業(yè)務(wù)邏輯仇味,只是用來(lái)做一些do或者聚合的生成以及使用呻顽,這類方法都是無(wú)狀態(tài)的。


3.基礎(chǔ)設(shè)施層:

這一層其實(shí)是基礎(chǔ)設(shè)施的封裝丹墨,這一層是與我們的領(lǐng)域模型無(wú)關(guān)的廊遍,只是單純的基礎(chǔ)設(shè)施,比如一個(gè)xxxDAO,那它的實(shí)現(xiàn)可以是單表的mysql贩挣,也可以是分庫(kù)分表后的mysql喉前,也可以是redis緩存没酣,又或者是local cache,所以這里是完全與業(yè)務(wù)無(wú)關(guān)的卵迂,所以我這邊的實(shí)現(xiàn)方案是設(shè)計(jì)成接口裕便,然后讓領(lǐng)域?qū)右蕾囘@個(gè)接口,但不依賴具體的實(shí)現(xiàn)见咒,實(shí)現(xiàn)可以做自由的更改和替換偿衰。



五.用ddd的思路反哺

這一點(diǎn)是我最近一段時(shí)間慢慢感受到的,在和產(chǎn)品討論需求時(shí)改览,其實(shí)很多時(shí)候也是一種大家共同摸索共同討論的狀態(tài)下翎,因此一個(gè)好的方法論其實(shí)不只是可以幫助到自身,也可以反哺到團(tuán)隊(duì)中的其他同學(xué)宝当,同樣的视事,在面臨產(chǎn)品需求時(shí)超营,用ddd的思路做產(chǎn)品的需求定義和模塊拆解渔期,這種反而會(huì)比單純的實(shí)現(xiàn)更考驗(yàn)功力。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末痘系,一起剝皮案震驚了整個(gè)濱河市订晌,隨后出現(xiàn)的幾起案子虏辫,更是在濱河造成了極大的恐慌,老刑警劉巖腾仅,帶你破解...
    沈念sama閱讀 212,454評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件乒裆,死亡現(xiàn)場(chǎng)離奇詭異套利,居然都是意外死亡推励,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)肉迫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)验辞,“玉大人,你說(shuō)我怎么就攤上這事喊衫〉欤” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,921評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵族购,是天一觀的道長(zhǎng)壳贪。 經(jīng)常有香客問(wèn)我,道長(zhǎng)寝杖,這世上最難降的妖魔是什么违施? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,648評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮瑟幕,結(jié)果婚禮上磕蒲,老公的妹妹穿的比我還像新娘留潦。我一直安慰自己,他們只是感情好辣往,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布兔院。 她就那樣靜靜地躺著,像睡著了一般站削。 火紅的嫁衣襯著肌膚如雪坊萝。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,950評(píng)論 1 291
  • 那天许起,我揣著相機(jī)與錄音屹堰,去河邊找鬼。 笑死街氢,一個(gè)胖子當(dāng)著我的面吹牛扯键,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播珊肃,決...
    沈念sama閱讀 39,090評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼荣刑,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了伦乔?” 一聲冷哼從身側(cè)響起厉亏,我...
    開(kāi)封第一講書(shū)人閱讀 37,817評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎烈和,沒(méi)想到半個(gè)月后爱只,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,275評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡招刹,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評(píng)論 2 327
  • 正文 我和宋清朗相戀三年恬试,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片疯暑。...
    茶點(diǎn)故事閱讀 38,724評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡训柴,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出妇拯,到底是詐尸還是另有隱情幻馁,我是刑警寧澤,帶...
    沈念sama閱讀 34,409評(píng)論 4 333
  • 正文 年R本政府宣布越锈,位于F島的核電站仗嗦,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏甘凭。R本人自食惡果不足惜稀拐,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評(píng)論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望对蒲。 院中可真熱鬧钩蚊,春花似錦贡翘、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,815評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至蝠咆,卻和暖如春踊东,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背刚操。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,043評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工闸翅, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人菊霜。 一個(gè)月前我還...
    沈念sama閱讀 46,503評(píng)論 2 361
  • 正文 我出身青樓坚冀,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親鉴逞。 傳聞我的和親對(duì)象是個(gè)殘疾皇子记某,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評(píng)論 2 350