如何保證同事的代碼不會(huì)腐爛娩梨?一文帶你了解 Alibaba COLA 架構(gòu)

本文開(kāi)始前慰枕,問(wèn)大家一個(gè)問(wèn)題诉濒,你覺(jué)得一份業(yè)務(wù)代碼醇份,尤其是互聯(lián)網(wǎng)業(yè)務(wù)代碼松蒜,都有哪些特點(diǎn)岳遥?

我能想到的有這幾點(diǎn):

  • 互聯(lián)網(wǎng)業(yè)務(wù)迭代快丢氢,工期緊傅联,導(dǎo)致代碼結(jié)構(gòu)混亂,幾乎沒(méi)有代碼注釋和文檔疚察。
  • 互聯(lián)網(wǎng)人員變動(dòng)頻繁蒸走,很容易接手別人的老項(xiàng)目,新人根本沒(méi)時(shí)間吃透代碼結(jié)構(gòu)貌嫡,緊迫的工期又只能讓屎山越堆越大比驻。
  • 多人一起開(kāi)發(fā),每個(gè)人的編碼習(xí)慣不同岛抄,工具類代碼各用個(gè)的别惦,業(yè)務(wù)命名也經(jīng)常沖突,影響效率夫椭。
  • 大部分團(tuán)隊(duì)幾乎沒(méi)有時(shí)間做代碼重構(gòu)掸掸,任由代碼腐爛。

每當(dāng)我們新啟動(dòng)一個(gè)代碼倉(cāng)庫(kù),都是信心滿滿扰付,結(jié)構(gòu)整潔堤撵。但是時(shí)間越往后,代碼就變得腐敗不堪悯周,技術(shù)債務(wù)越來(lái)越龐大粒督。

這種情況有解決方案嗎?也是有的:

  1. 小組內(nèi)定期做代碼重構(gòu)禽翼,解決技術(shù)債務(wù)屠橄。
  2. 組內(nèi)設(shè)計(jì)完善的應(yīng)用架構(gòu),讓代碼的腐爛來(lái)得慢一些闰挡。(當(dāng)然很難做到完全不腐爛)
  3. 設(shè)計(jì)盡量簡(jiǎn)單锐墙,讓不同層級(jí)的開(kāi)發(fā)都能快速看懂并上手開(kāi)發(fā),而不是在一堆復(fù)雜的沒(méi)人看懂的代碼上堆更多的屎山长酗。

而COLA溪北,我們今天的主角,就是為了提供一個(gè)可落地的業(yè)務(wù)代碼結(jié)構(gòu)規(guī)范夺脾,讓你的代碼腐爛的盡可能慢一些之拨,讓團(tuán)隊(duì)的開(kāi)發(fā)效率盡可能快一些。

COLA是什么

COLA是由阿里大佬張建飛所提出的一種業(yè)務(wù)代碼架構(gòu)的最佳實(shí)踐咧叭,并且已經(jīng)在阿里云腳手架代碼生成器中作為一個(gè)可選項(xiàng)蚀乔,可見(jiàn)其已經(jīng)擁有了一定影響力。

image.png

COLA 是 Clean Object-Oriented and Layered Architecture的縮寫(xiě)菲茬,代表“整潔面向?qū)ο蠓謱蛹軜?gòu)”吉挣。

在COLA 4.0,也就是目前最新的版本中婉弹,作者將COLA拆分為COLA架構(gòu)(Archetype)和COLA組件(Components)兩個(gè)部分:

  • COLA架構(gòu):COLA應(yīng)用的代碼模板睬魂。
  • COLA組件:提供一些非常有用的通用組件,這些組件可以幫助我們提升研發(fā)效率镀赌。

兩者互不干擾氯哮,可以獨(dú)立使用。

COLA整體架構(gòu)

首先主要談?wù)凜OLA架構(gòu)商佛,COLA的官方博文中是這么介紹的:

在平時(shí)我們的業(yè)務(wù)開(kāi)發(fā)中蛙粘,大部分的系統(tǒng)都需要:

  • 接收request,響應(yīng)response威彰;
  • 做業(yè)務(wù)邏輯處理,像校驗(yàn)參數(shù)穴肘,狀態(tài)流轉(zhuǎn)歇盼,業(yè)務(wù)計(jì)算等等;
  • 和外部系統(tǒng)有聯(lián)動(dòng)评抚,像數(shù)據(jù)庫(kù)豹缀,微服務(wù)伯复,搜索引擎等;

正是有這樣的共性存在邢笙,才會(huì)有很多普適的架構(gòu)思想出現(xiàn)啸如,比如分層架構(gòu)、六邊形架構(gòu)氮惯、洋蔥圈架構(gòu)叮雳、整潔架構(gòu)(Clean Architecture)、DDD架構(gòu)等等妇汗。

這些應(yīng)用架構(gòu)思想雖然很好帘不,但我們很多同學(xué)還是“不講Co德,明白了很多道理杨箭,可還是過(guò)不好這一生”寞焙。問(wèn)題就在于缺乏實(shí)踐和指導(dǎo)。COLA的意義就在于互婿,他不僅是思想捣郊,還提供了可落地的實(shí)踐。應(yīng)該是為數(shù)不多的應(yīng)用架構(gòu)層面的開(kāi)源軟件慈参。

COLA提供了一整套代碼架構(gòu)呛牲,拿來(lái)即用。 其中包含了很多架構(gòu)設(shè)計(jì)思想懂牧,包括討論度很高的領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)DDD等侈净。

注意:每個(gè)人對(duì)于架構(gòu)設(shè)計(jì)都有著自己的理解。所以對(duì)于COLA的架構(gòu)僧凤,本篇文章也僅僅只是我自己對(duì)于COLA的粗淺理解畜侦,大家可以批判看待。

COLA分層架構(gòu)

先來(lái)看兩張官方介紹圖


image.png
image.png

其次躯保,還有一個(gè)官方的表格旋膳,介紹了COLA中每個(gè)層的命名和含義:

層次 包名 功能 必選
Adapter層 web 處理頁(yè)面請(qǐng)求的Controller
Adapter層 wireless 處理無(wú)線端的適配
Adapter層 wap 處理wap端的適配
App層 executor 處理request,包括command和query
App層 consumer 處理外部message
App層 scheduler 處理定時(shí)任務(wù)
Domain層 model 領(lǐng)域模型
Domain層 ability 領(lǐng)域能力途事,包括DomainService
Domain層 gateway 領(lǐng)域網(wǎng)關(guān)验懊,解耦利器
Infra層 gatewayimpl 網(wǎng)關(guān)實(shí)現(xiàn)
Infra層 mapper ibatis數(shù)據(jù)庫(kù)映射
Infra層 config 配置信息
Client SDK api 服務(wù)對(duì)外透出的API
Client SDK dto 服務(wù)對(duì)外的DTO

這兩張圖和一個(gè)表格已經(jīng)把整個(gè)COLA架構(gòu)的絕大部分內(nèi)容展現(xiàn)給了大家,但是一下子這么多信息量可能很難消化尸变。

既然整個(gè)示例架構(gòu)項(xiàng)目是一個(gè)Maven父子結(jié)構(gòu)义图,那我們就從父模塊一個(gè)個(gè)好好過(guò)一遍。

首先父模塊的pom.xml包含了如下子模塊:

<modules>
  <module>demo-web-client</module>
  <module>demo-web-adapter</module>
  <module>demo-web-app</module>
  <module>demo-web-domain</module>
  <module>demo-web-infrastructure</module>
  <module>start</module>
</modules>

start層

該模塊作為整個(gè)應(yīng)用的啟動(dòng)模塊(通常是一個(gè)SpringBoot應(yīng)用)召烂,只承擔(dān)啟動(dòng)項(xiàng)目和全局相關(guān)配置項(xiàng)的存放職責(zé)碱工。代碼目錄如下:

image.png

將啟動(dòng)獨(dú)立出來(lái),好處是清晰簡(jiǎn)潔,也能讓新人一眼就看出如何運(yùn)行項(xiàng)目怕篷,以及項(xiàng)目的一些基礎(chǔ)依賴历筝。

adapter層

接下來(lái)我們按照之前架構(gòu)圖從上到下的順序,一個(gè)個(gè)看廊谓。

首先是demo-web-adapter模塊梳猪,這名字是不是很新鮮?但其實(shí)蒸痹,可以理解為平時(shí)我們用的controller層(對(duì)于Web應(yīng)用來(lái)說(shuō))春弥,換湯不換藥。

在COLA官方博客中电抚,也能找到如下的描述:

Controller這個(gè)名字主要是來(lái)自于MVC惕稻,因?yàn)槭荕VC,所以自帶了Web應(yīng)用的烙印蝙叛。然而俺祠,隨著mobile的興起,現(xiàn)在很少有應(yīng)用僅僅只支持Web端借帘,通常的標(biāo)配是Web蜘渣,Mobile,WAP三端都要支持肺然。

image.png

cilent層

有了我們說(shuō)的“controller”層蔫缸,接下來(lái)有的小伙伴肯定就會(huì)想,是不是service層啦际起。

是拾碌,也不是。

傳統(tǒng)的Web應(yīng)用中街望,完全可以只有一個(gè)service層給controller層調(diào)用校翔,但是作為一個(gè)業(yè)務(wù)應(yīng)用,除非你真的只是個(gè)前端頁(yè)面的無(wú)情吐數(shù)據(jù)機(jī)器灾前,否則很大可能性你的應(yīng)用會(huì)有很多其他上下游調(diào)用方防症,并且你需要提供接口給他們。

這時(shí)候你給他們的不應(yīng)該是一個(gè)Web接口哎甲,應(yīng)該是RPC調(diào)用的服務(wù)層接口蔫敲,至于原因不是本文的重點(diǎn),具體就不展開(kāi)了炭玫。

所以在COLA中奈嘿,你的adapter層,調(diào)用了client層吞加,client層中就是你服務(wù)接口的定義裙犹。


image.png

從上圖中可以看到酝惧,client包里有:

  • api文件夾:存放服務(wù)接口定義
  • dto文件夾:存放傳輸實(shí)體

注意,這里只是服務(wù)接口定義伯诬,而不是服務(wù)層的具體實(shí)現(xiàn),所以在adapter層中巫财,調(diào)用的其實(shí)是client層的接口:

@RestController
public class CustomerController {

    @Autowired
    private CustomerServiceI customerService;

    @GetMapping(value = "/customer")
    public MultiResponse<CustomerDTO> listCustomerByName(@RequestParam(required = false) String name){
        CustomerListByNameQry customerListByNameQry = new CustomerListByNameQry();
        customerListByNameQry.setName(name);
        return customerService.listByName(customerListByNameQry);
    }

}

而最終接口的具體實(shí)現(xiàn)邏輯放到了app層盗似。

@Service
@CatchAndLog
public class CustomerServiceImpl implements CustomerServiceI {

    @Resource
    private CustomerListByNameQryExe customerListByNameQryExe;

    @Override
    public MultiResponse<CustomerDTO> listByName(CustomerListByNameQry customerListByNameQry) {
        return customerListByNameQryExe.execute(customerListByNameQry);
    }
}

app層

接著上面說(shuō)的,我們的app模塊作為服務(wù)的實(shí)現(xiàn)平项,存放了各個(gè)業(yè)務(wù)的實(shí)現(xiàn)類赫舒,并且嚴(yán)格按照業(yè)務(wù)分包,這里劃重點(diǎn)闽瓢,是先按照業(yè)務(wù)分包接癌,再按照功能分包的,為何要這么做扣讼,文章后面還會(huì)多說(shuō)兩句缺猛,先看圖:

image.png

customer和order分別對(duì)應(yīng)了消費(fèi)著和訂單兩個(gè)業(yè)務(wù)子領(lǐng)域。里面是COLA定義app層下面三種功能:

App層 executor 處理request椭符,包括command和query
App層 consumer 處理外部message
App層 scheduler 處理定時(shí)任務(wù)

可以看到荔燎,消息隊(duì)列的消費(fèi)者和定時(shí)任務(wù),這類平時(shí)我們業(yè)務(wù)開(kāi)發(fā)經(jīng)常會(huì)遇到的場(chǎng)景销钝,也放在app層有咨。

domain層

接下來(lái)便是domain,也就是領(lǐng)域?qū)诱艚。瓤匆幌骂I(lǐng)域?qū)诱w結(jié)構(gòu):

image.png

可以看到座享,首先是按照不同的領(lǐng)域(customer和order)分包,里面則是三種主要的文件類型:

  1. 領(lǐng)域?qū)嶓w:實(shí)體模型可以是充血模型(請(qǐng)自行了解)似忧,例如官方示例里的Customer.java如下:
@Data
@Entity
public class Customer{

    private String customerId;
    private String memberId;
    private String globalId;
    private long registeredCapital;
    private String companyName;
    private SourceType sourceType;
    private CompanyType companyType;

    public Customer() {
    }

    public boolean isBigCompany() {
        return registeredCapital > 10000000; //注冊(cè)資金大于1000萬(wàn)的是大企業(yè)
    }

    public boolean isSME() {
        return registeredCapital > 10000 && registeredCapital < 1000000; //注冊(cè)資金大于10萬(wàn)小于100萬(wàn)的為中小企業(yè)
    }

    public void checkConfilict(){
        //Per different biz, the check policy could be different, if so, use ExtensionPoint
        if("ConflictCompanyName".equals(this.companyName)){
            throw new BizException(this.companyName+" has already existed, you can not add it");
        }

    }
}

  1. 領(lǐng)域能力:domainservice文件夾下渣叛,是領(lǐng)域?qū)ν獗┞兜姆?wù)能力,如上圖中的CreditChecker

  2. 領(lǐng)域網(wǎng)關(guān):gateway文件夾下的接口定義橡娄,這里的接口你可以粗略的理解成一種SPI诗箍,也就是交給infrastructure層去實(shí)現(xiàn)的接口。

例如CustomerGateway里定義了接口getByById挽唉,要求infrastructure的實(shí)現(xiàn)類必須定義如何通過(guò)消費(fèi)者Id獲取消費(fèi)者實(shí)體信息滤祖,而infrastructure層可以實(shí)現(xiàn)任何數(shù)據(jù)源邏輯,比如瓶籽,從MySQL獲取匠童,從Redis獲取,還是從外部API獲取等等塑顺。

public interface CustomerGateway {
    public Customer getByById(String customerId);
}

在示例代碼的CustomerGatewayImpl(位于infrastructure層)中汤求,CustomerDO(數(shù)據(jù)庫(kù)實(shí)體)經(jīng)過(guò)MyBatis的查詢俏险,轉(zhuǎn)換為了Customer領(lǐng)域?qū)嶓w,進(jìn)行返回扬绪。完成了依賴倒置竖独。

@Component
public class CustomerGatewayImpl implements CustomerGateway {
    @Autowired
    private CustomerMapper customerMapper;

    public Customer getByById(String customerId){
      CustomerDO customerDO = customerMapper.getById(customerId);
      //Convert to Customer
      return null;
    }
}

image.png

infrastructure層

最后是我們的infrastructure也就是基礎(chǔ)設(shè)施層,這層有我們剛才提到的gatewayimpl網(wǎng)關(guān)實(shí)現(xiàn)挤牛,也有MyBatis的mapper等數(shù)據(jù)源的映射和config配置文件莹痢。

Infra層 gatewayimpl 網(wǎng)關(guān)實(shí)現(xiàn)
Infra層 mapper ibatis數(shù)據(jù)庫(kù)映射
Infra層 config 配置信息
image.png

所有層講完了,COLA4.0很簡(jiǎn)單明了墓赴,最后竞膳,在引用一段官方介紹博客原文來(lái)總結(jié)COLA的層級(jí):

1)適配層(Adapter Layer):負(fù)責(zé)對(duì)前端展示(web,wireless诫硕,wap)的路由和適配坦辟,對(duì)于傳統(tǒng)B/S系統(tǒng)而言,adapter就相當(dāng)于MVC中的controller章办;

2)應(yīng)用層(Application Layer):主要負(fù)責(zé)獲取輸入锉走,組裝上下文,參數(shù)校驗(yàn)纲菌,調(diào)用領(lǐng)域?qū)幼鰳I(yè)務(wù)處理挠日,如果需要的話,發(fā)送消息通知等翰舌。層次是開(kāi)放的嚣潜,應(yīng)用層也可以繞過(guò)領(lǐng)域?qū)樱苯釉L問(wèn)基礎(chǔ)實(shí)施層椅贱;

3)領(lǐng)域?qū)樱―omain Layer):主要是封裝了核心業(yè)務(wù)邏輯懂算,并通過(guò)領(lǐng)域服務(wù)(Domain Service)和領(lǐng)域?qū)ο螅―omain Entity)的方法對(duì)App層提供業(yè)務(wù)實(shí)體和業(yè)務(wù)邏輯計(jì)算。領(lǐng)域是應(yīng)用的核心庇麦,不依賴任何其他層次计技;

4)基礎(chǔ)實(shí)施層(Infrastructure Layer):主要負(fù)責(zé)技術(shù)細(xì)節(jié)問(wèn)題的處理,比如數(shù)據(jù)庫(kù)的CRUD山橄、搜索引擎垮媒、文件系統(tǒng)、分布式服務(wù)的RPC等航棱。此外睡雇,領(lǐng)域防腐的重任也落在這里,外部依賴需要通過(guò)gateway的轉(zhuǎn)義處理饮醇,才能被上面的App層和Domain層使用它抱。

COLA架構(gòu)的特色

說(shuō)完了分層架構(gòu),我們?cè)賮?lái)回顧下上面提到的COLA架構(gòu)的幾個(gè)特色的設(shè)計(jì)

領(lǐng)域與功能的分包策略

也就是下面這張圖的意思朴艰,先按照領(lǐng)域分包观蓄,再按照功能分包混移,這樣做的其中一點(diǎn)好處是能將腐爛控制在該業(yè)務(wù)域內(nèi)。

比如消費(fèi)者customer和訂單order兩個(gè)領(lǐng)域是兩個(gè)后端開(kāi)發(fā)并行開(kāi)發(fā)侮穿,兩個(gè)人對(duì)于dto歌径,util這些文件夾的命名習(xí)慣都不同,那么只會(huì)腐爛在各自的業(yè)務(wù)包下面亲茅,而不會(huì)將dto,util,config等文件夾放在一起沮脖,極容易引發(fā)文件沖突。

image.png
image.png

前面的包定義芯急,都是功能維度的定義。為了兼顧領(lǐng)域維度的內(nèi)聚性驶俊,我們有必要對(duì)包結(jié)構(gòu)進(jìn)行一下微調(diào)娶耍,即頂層包結(jié)構(gòu)應(yīng)該是按照領(lǐng)域劃分,讓領(lǐng)域內(nèi)聚饼酿。

業(yè)務(wù)域和外部依賴解耦

前面提到的domain和infrastructure層的依賴倒置榕酒,是一個(gè)非常有用的設(shè)計(jì),進(jìn)一步解耦了取數(shù)邏輯的實(shí)現(xiàn)故俐。

例如下圖中想鹰,你的領(lǐng)域?qū)嶓w是商品item,通過(guò)gateway接口药版,你的商品的數(shù)據(jù)源可以是數(shù)據(jù)庫(kù)辑舷,也可以是外部的服務(wù)API。

如果是外部的商品服務(wù)槽片,你經(jīng)過(guò)API調(diào)用后何缓,商品域吐出的是一個(gè)大而全的DTO(可能包含幾十個(gè)字段),而在下單這個(gè)階段还栓,訂單所需要的可能只是其中幾個(gè)字段而已碌廓。你拿到了外部領(lǐng)域DTO,轉(zhuǎn)為自己領(lǐng)域的Item剩盒,只留下標(biāo)題價(jià)格庫(kù)存等必要的數(shù)據(jù)字段谷婆。


image.png

COLA并不完美

誠(chéng)然,COLA已經(jīng)做的足夠清晰簡(jiǎn)潔了辽聊,但是它仍然有不完美的地方纪挎,比如每個(gè)接口的出入?yún)⒍紩?huì)根據(jù)業(yè)務(wù)名做定義,導(dǎo)致了很多結(jié)構(gòu)極為相似的DTO身隐,DTO的爆炸增長(zhǎng)是個(gè)問(wèn)題廷区。參考:ISSUE-271

但是總的來(lái)說(shuō),COLA只是給你提供了一種架構(gòu)設(shè)計(jì)的思想贾铝,并不深入到強(qiáng)制你使用某種規(guī)范的層面隙轻,所以對(duì)于COLA中你覺(jué)得復(fù)雜埠帕,或者不理解的地方,很多時(shí)候需要你自己來(lái)做權(quán)衡玖绿,作取舍敛瓷。取其精華,去其糟粕的運(yùn)用到你的項(xiàng)目中斑匪。

總結(jié)

COLA架構(gòu)并不復(fù)雜呐籽,COLA已經(jīng)從1.0版本經(jīng)過(guò)逐次精簡(jiǎn),發(fā)展到了如今的形態(tài)蚀瘸。在阿里云代碼腳手架生成器中作為一個(gè)可選項(xiàng)狡蝶,足見(jiàn)其已經(jīng)趨于成熟。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末贮勃,一起剝皮案震驚了整個(gè)濱河市贪惹,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌寂嘉,老刑警劉巖奏瞬,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異泉孩,居然都是意外死亡硼端,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門寓搬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)珍昨,“玉大人,你說(shuō)我怎么就攤上這事句喷÷穑” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵脏嚷,是天一觀的道長(zhǎng)骆撇。 經(jīng)常有香客問(wèn)我,道長(zhǎng)父叙,這世上最難降的妖魔是什么神郊? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮趾唱,結(jié)果婚禮上涌乳,老公的妹妹穿的比我還像新娘。我一直安慰自己甜癞,他們只是感情好夕晓,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著悠咱,像睡著了一般蒸辆。 火紅的嫁衣襯著肌膚如雪征炼。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,764評(píng)論 1 290
  • 那天躬贡,我揣著相機(jī)與錄音谆奥,去河邊找鬼。 笑死拂玻,一個(gè)胖子當(dāng)著我的面吹牛酸些,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播檐蚜,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼魄懂,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了闯第?” 一聲冷哼從身側(cè)響起逢渔,我...
    開(kāi)封第一講書(shū)人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎乡括,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體智厌,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡诲泌,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了铣鹏。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片敷扫。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖诚卸,靈堂內(nèi)的尸體忽然破棺而出葵第,到底是詐尸還是另有隱情,我是刑警寧澤合溺,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布卒密,位于F島的核電站,受9級(jí)特大地震影響棠赛,放射性物質(zhì)發(fā)生泄漏哮奇。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一睛约、第九天 我趴在偏房一處隱蔽的房頂上張望鼎俘。 院中可真熱鬧,春花似錦辩涝、人聲如沸贸伐。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)捉邢。三九已至脯丝,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間歌逢,已是汗流浹背巾钉。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留秘案,地道東北人砰苍。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像阱高,于是被迫代替她去往敵國(guó)和親赚导。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348