Mixins 比繼承更好

作者:Olivier Halligon累榜,原文鏈接颈墅,原文日期:2015-11-08
譯者:ray16897188章母;校對(duì):Cee存哲;定稿:千葉知風(fēng)

譯者注:Mixin 和 [Trait](https://en.wikipedia.org/wiki/Trait_(computer_programming) 是面向?qū)ο缶幊陶Z(yǔ)言中的術(shù)語(yǔ)因宇,本文中作者并未明確指出兩者之間的區(qū)別七婴。這兩個(gè)單詞在本譯文中也不做翻譯。

從面向?qū)ο蟮木幊陶Z(yǔ)言的角度來(lái)說察滑,繼承(Inheritence)總被用來(lái)在多個(gè)類之間共享代碼打厘。但這并不總是一個(gè)最佳的解決方案,而且它本身還有些問題贺辰。在今天寫的這篇文章中户盯,我們會(huì)看到 Swift 中的協(xié)議擴(kuò)展(Protocol Extensions),并將其以「Mixins」的形式去使用是怎樣解決這個(gè)問題的饲化。

你可以從這里下載包含本篇文章所有代碼的 Swift Playground莽鸭。

繼承本身存在的問題

假設(shè)你有個(gè) app,里面有很多包含相同行為的 UIViewController 類吃靠,例如它們都有漢堡菜單硫眨。你當(dāng)然不想在 app 中的每一個(gè) View Controller 里都反復(fù)實(shí)現(xiàn)這個(gè)漢堡菜單的邏輯(例如設(shè)置 leftBarButtonItem 按鈕,點(diǎn)擊這個(gè)按鈕時(shí)打開或者關(guān)閉這個(gè)菜單巢块,等等)礁阁。

解決方案很簡(jiǎn)單,你只需要?jiǎng)?chuàng)建一個(gè)負(fù)責(zé)實(shí)現(xiàn)所有特定行為族奢、而且是 UIViewController 的子類 CommonViewController氮兵。然后讓你所有的 ViewController 都直接繼承 CommonViewController 而不是 UIViewController 就可以了,沒錯(cuò)吧歹鱼?通過使用這種方式,這些類都繼承了父類的方法卜高,且具有了相同的行為弥姻,你也不用每次重復(fù)實(shí)現(xiàn)這些東西了。

class CommonViewController: UIViewController {
  func setupBurgerMenu() { … }
  func onBurgerMenuTapped() { … }
  var burgerMenuIsOpen: Bool {
    didSet { … }
  }
}

class MyViewController: CommonViewController {
  func viewDidLoad() {
    super.viewDidLoad()
    setupBurgerMenu()
  }
}

但在隨后的開發(fā)階段掺涛,你會(huì)意識(shí)到自己需要一個(gè) UITableViewController 或者一個(gè) UICollectionViewController……暈死庭敦,CommonViewController 不能用了,因?yàn)樗抢^承自 UIViewController 而不是 UITableViewController薪缆!

你會(huì)怎么做秧廉,是實(shí)現(xiàn)和 CommonViewController 一樣的事情卻繼承于 UITableViewControllerCommonTableViewController 嗎?這會(huì)產(chǎn)生很多重復(fù)的代碼拣帽,而且是個(gè)十分糟糕的設(shè)計(jì)哦疼电。

組合(Composition)是救命稻草

誠(chéng)然,解決這個(gè)問題减拭,有句具有代表性并且正確的話是這么說的:

多用組合蔽豺,少用繼承。

這意味著我們不使用繼承的方式拧粪,而是讓我們的 UIViewController 包含一些提供相應(yīng)行為的內(nèi)部類(Inner class)修陡。

在這個(gè)例子中沧侥,我們可以假定 BurgerMenuManager 類能提供創(chuàng)建漢堡菜單圖標(biāo)、以及與這些圖標(biāo)交互邏輯的所有必要的方法魄鸦。那些各式各樣的 UIViewController 就會(huì)有一個(gè) BurgerMenuManager 類型的屬性宴杀,可以用來(lái)與漢堡餐單做交互。

class BurgerMenuManager {
  func setupBurgerMenu() { … }
  func onBurgerMenuTapped() { burgerMenuIsOpen = !burgerMenuisOpen }
  func burgerMenuIsOpen: Bool { didSet { … } }
}

class MyViewController: UIViewController {
  var menuManager: BurgerMenuManager()
  func viewDidLoad() {
    super.viewDidLoad()
    menuManager.setupBurgerMenu()
  }
}

class MyOtherViewController: UITableViewController {
  var menuManager: BurgerMenuManager()
  func viewDidLoad() {
    super.viewDidLoad()
    menuManager.setupBurgerMenu()
  }  
}

然而你能看出來(lái)這種解決方案會(huì)變得很臃腫拾因。每次你都得去明確引用那個(gè)中間對(duì)象 menuManager旺罢。

多繼承(Multiple inheritance)

繼承的另一個(gè)問題就是很多面向?qū)ο蟮木幊陶Z(yǔ)言都不支持多繼承(這兒有個(gè)很好的解釋,是關(guān)于菱形缺陷(Diamond problem)的)盾致。

這就意味著一個(gè)類不能繼承自多個(gè)父類主经。

假如說你要?jiǎng)?chuàng)建一些科幻小說中的人物的對(duì)象模型。顯然庭惜,你得展現(xiàn)出 DocEmmettBrown罩驻,DoctorWhoTimeLord护赊,IronMan 還有 Superman 的能力……這些角色的相互關(guān)系是什么惠遏?有些能時(shí)間旅行,有些能空間穿越骏啰,還有些兩種能力都會(huì)节吮;有些能飛,而有些不能飛判耕;有些是人類透绩,而有些不是……

IronManSuperman 這個(gè)兩個(gè)類都能飛,于是我們就會(huì)設(shè)想有個(gè) Flyer 類能提供一個(gè)實(shí)現(xiàn) fly() 的方法壁熄。但是 IronManDocEmmettBrown 都是人類帚豪,我們還會(huì)設(shè)想要有個(gè) Human 父類;而 SupermanTimeLord 又得是 Alien 的子類草丧。哦狸臣,等會(huì)兒…… 那 IronMan 得同時(shí)繼承 FlyerHuman 兩個(gè)類嗎?這在 Swift 中是不可能的實(shí)現(xiàn)的(在很多其他的面向?qū)ο蟮恼Z(yǔ)言中也不能這么實(shí)現(xiàn))昌执。

我們應(yīng)該從所有父類中選擇出符合子類屬性最好的一個(gè)么烛亦?但是假如我們讓 IronMan 繼承 Human,那么怎么去實(shí)現(xiàn) fly() 這個(gè)方法懂拾?很顯然我們不能在 Human 這個(gè)類中實(shí)現(xiàn)煤禽,因?yàn)椴⒉皇敲總€(gè)人都會(huì)飛,但是 Superman 卻需要這個(gè)方法岖赋,然而我們并不想重復(fù)寫兩次呜师。

所以,我們?cè)谶@里會(huì)使用組合(Composition)方法贾节,讓 var flyingEngine: Flyer 成為 Superman 類中的一個(gè)屬性汁汗。

但是調(diào)用時(shí)你必須寫成 superman.flyingEngine.fly() 而不是優(yōu)雅地寫成 superman.fly()衷畦。

Mixins & Traits

生生不息,Mixin 繁榮
生生不息知牌,Mixin 繁榮

Mixins 和 Traits 的概念<sup id="fnref1"><a href="#fn1" rel="footnote">1</a>由此引入祈争。

  • 通過繼承,你定義你的類是什么角寸。例如每條 Dog一個(gè) Animal菩混。
  • 通過 Traits,你定義你的類能做什么扁藕。例如每個(gè) Animal eat()沮峡,但是人類也可以吃,而且異世奇人(Doctor Who)也能吃魚條和蛋撻亿柑,甚至即使是位 Gallifreyan(既不是人類也不是動(dòng)物)邢疙。

使用 Traits,重要的不是「是什么」望薄,而是能「做什么」疟游。

繼承描述了一個(gè)對(duì)象是什么,而 Traits 描述了這個(gè)對(duì)象能做什么痕支。

最棒的事情就是一個(gè)類可以選用多個(gè) Traits 來(lái)做多個(gè)事情颁虐,而這個(gè)類還只是一種事物(只從一個(gè)父類繼承)智末。

那么如何應(yīng)用到 Swift 中呢虾标?

有默認(rèn)實(shí)現(xiàn)的協(xié)議

Swift 2.0 中定義一個(gè)協(xié)議(Protocol)的時(shí)候,還可以使用這個(gè)協(xié)議的擴(kuò)展(Extension)給它的部分或是所有的方法做默認(rèn)實(shí)現(xiàn)南吮』ㄋ唬看上去是這樣的:

protocol Flyer {
  func fly()
}

extension Flyer {
  func fly() {
    print("I believe I can flyyyyy ?")
  }
}

有了上面的代碼板熊,當(dāng)你創(chuàng)建一個(gè)遵從 Flyer 協(xié)議的類或者是結(jié)構(gòu)體時(shí),就能很順利地獲得 fly() 方法察绷!

這只是一個(gè)默認(rèn)的實(shí)現(xiàn)方式。因此你可以在需要的時(shí)候不受約束地重新定義這個(gè)方法津辩;如果不重新定義的話拆撼,會(huì)使用你默認(rèn)的那個(gè)方法。

class SuperMan: Flyer {
  // 這里我們沒有實(shí)現(xiàn) fly() 方法喘沿,因此能夠聽到 Clark 唱歌
}

class IronMan: Flyer {
  // 如果需要我們也可以給出單獨(dú)的實(shí)現(xiàn)
  func fly() {
    thrusters.start()
  }
}

對(duì)于很多事情來(lái)說闸度,協(xié)議的默認(rèn)實(shí)現(xiàn)這個(gè)特性非常的有用。其中一種自然就是如你所想的那樣蚜印,把「Traits」概念引入到了 Swift 中莺禁。

一種身份,多種能力

Traits 很贊的一點(diǎn)就是它們并不依賴于使用到它們的對(duì)象本身的身份窄赋。Traits 并不關(guān)心類是什么哟冬,亦或是類是從哪里繼承的:Traits 僅僅在類上定義了一些函數(shù)楼熄。

這就解決了我們的問題:異世奇人(Doctor Who)可以既是一位時(shí)間旅行者,同時(shí)還是一個(gè)外星人浩峡;而愛默·布朗博士(Dr Emmett Brown)既是一位時(shí)間旅行者可岂,同時(shí)還屬于人類;鋼鐵俠(Iron Man)是一個(gè)能飛的人翰灾,而超人(Superman)是一個(gè)能飛的外星人缕粹。

你是什么并不限制你能夠做什么

現(xiàn)在我們利用 Traits 的優(yōu)點(diǎn)來(lái)實(shí)現(xiàn)一下我們的模板類。

首先定義不同的 Traits:

protocol Flyer {
  func fly()
}
protocol TimeTraveler {
  var currentDate: NSDate { get set }
  mutating func travelTo(date: NSDate)
}

隨后給它們一些默認(rèn)的實(shí)現(xiàn):

extension Flyer {
  func fly() {
    print("I believe I can flyyyyy ?")
  }
}

extension TimeTraveler {
  mutating func travelTo(date: NSDate) {
    currentDate = date
  }
}

在這點(diǎn)上纸淮,我們還是用繼承去定義我們英雄角色的身份(他們是什么)平斩,先定義一些父類:

class Character {
  var name: String
  init(name: String) {
    self.name = name
  }
}

class Human: Character {
  var countryOfOrigin: String?
  init(name: String, countryOfOrigin: String? = nil) {
    self.countryOfOrigin = countryOfOrigin
    super.init(name: name)
  }
}

class Alien: Character {
  let species: String
  init(name: String, species: String) {
    self.species = species
    super.init(name: name)
  }
}

現(xiàn)在我們就能通過他們的身份(通過繼承)和能力(Traits/協(xié)議遵循)來(lái)定義英雄角色了:

class TimeLord: Alien, TimeTraveler {
  var currentDate = NSDate()
  init() {
    super.init(name: "I'm the Doctor", species: "Gallifreyan")
  }
}

class DocEmmettBrown: Human, TimeTraveler {
  var currentDate = NSDate()
  init() {
    super.init(name: "Emmett Brown", countryOfOrigin: "USA")
  }
}

class Superman: Alien, Flyer {
  init() {
    super.init(name: "Clark Kent", species: "Kryptonian")
  }
}

class IronMan: Human, Flyer {
  init() {
    super.init(name: "Tony Stark", countryOfOrigin: "USA")
  }
}

現(xiàn)在 SupermanIronMan 都使用了相同的 fly() 實(shí)現(xiàn),即使他們分別繼承自不同的父類(一個(gè)繼承自 Alien咽块,另一個(gè)繼承自 Human)绘面。而且這兩位博士都知道怎么做時(shí)間旅行了,即使一個(gè)是人類糜芳,另外一個(gè)來(lái)自 Gallifrey 星飒货。

let tony = IronMan()
tony.fly() // 輸出 "I believe I can flyyyyy ?"
tony.name  // 返回 "Tony Stark"

let clark = Superman()
clark.fly() // 輸出 "I believe I can flyyyyy ?"
clark.species  // 返回 "Kryptonian"

var docBrown = DocEmmettBrown()
docBrown.travelTo(NSDate(timeIntervalSince1970: 499161600))
docBrown.name // "Emmett Brown"
docBrown.countryOfOrigin // "USA"
docBrown.currentDate // Oct 26, 1985, 9:00 AM

var doctorWho = TimeLord()
doctorWho.travelTo(NSDate(timeIntervalSince1970: 1303484520))
doctorWho.species // "Gallifreyan"
doctorWho.currentDate // Apr 22, 2011, 5:02 PM

時(shí)空大冒險(xiǎn)

現(xiàn)在我們引入一個(gè)新的空間穿越的能力/trait:

protocol SpaceTraveler {
  func travelTo(location: String)
}

并給它一個(gè)默認(rèn)的實(shí)現(xiàn):

extension SpaceTraveler {
  func travelTo(location: String) {
    print("Let's go to \(location)!")
  }
}

我們可以使用 Swift 的擴(kuò)展(Extension)方式讓現(xiàn)有的一個(gè)類遵循一個(gè)協(xié)議,把這些能力加到我們定義的角色身上去峭竣。如果忽略掉鋼鐵俠之前跑到紐約城上面隨后短暫飛到太空中去的那次情景塘辅,那只有博士和超人是真正能做空間穿越的:

extension TimeLord: SpaceTraveler {}
extension Superman: SpaceTraveler {}
天哪!
天哪皆撩!

沒錯(cuò)扣墩,這就是給已有類添加能力/trait 僅需的步驟!就這樣扛吞,他們可以 travelTo() 任何的地方了呻惕!很簡(jiǎn)潔,是吧滥比?

doctorWho.travelTo("Trenzalore") // prints "Let's go to Trenzalore!"

邀請(qǐng)更多的人來(lái)參加這場(chǎng)聚會(huì)亚脆!

現(xiàn)在我們?cè)僮尭嗟娜思尤脒M(jìn)來(lái)吧:

// 來(lái)吧,Pond盲泛!
let amy = Human(name: "Amelia Pond", countryOfOrigin: "UK")
// 該死濒持,她是一個(gè)時(shí)間和空間旅行者,但是卻不是 TimeLord寺滚!

class Astraunaut: Human, SpaceTraveler {}
let neilArmstrong = Astraunaut(name: "Neil Armstrong", countryOfOrigin: "USA")
let laika = Astraunaut(name: "La?ka", countryOfOrigin: "Russia")
// 等等柑营,Le?ka 是一只狗,不是嗎村视?

class MilleniumFalconPilot: Human, SpaceTraveler {}
let hanSolo = MilleniumFalconPilot(name: "Han Solo")
let chewbacca = MilleniumFalconPilot(name: "Chewie")
// 等等官套,MilleniumFalconPilot 不該定義成「人類」吧!

class Spock: Alien, SpaceTraveler {
  init() {
    super.init(name: "Spock", species: "Vulcan")
    // 并不是 100% 正確
  }
}

Huston,我們有麻煩了(譯注:原文 "Huston, we have a problem here"奶赔,是星際迷航中的梗)惋嚎。Laika 不是一個(gè)人,Chewie 也不是纺阔,Spock 算半個(gè)人瘸彤、半個(gè)瓦肯(Vulcan)人,所以上面的代碼定義錯(cuò)的離譜笛钝!

你看出來(lái)什么問題了么质况?我們又一次被繼承擺了一道,理所應(yīng)當(dāng)?shù)卣J(rèn)為 HumanAlien是身份玻靡。在這里一些類必須屬于某種類型结榄,或是必須繼承自某個(gè)父類,而實(shí)際情況中不總是這樣囤捻,尤其對(duì)科幻故事來(lái)說臼朗。

這也是為什么要在 Swift 中使用協(xié)議,以及協(xié)議的默認(rèn)擴(kuò)展蝎土。這能夠幫助我們把因使用繼承而強(qiáng)加到類上的這些限制移除视哑。

如果 HumanAlien 不是而是協(xié)議,那就會(huì)有很多的好處:

  • 我們可以定義一個(gè) MilleniumFalconPilot 類型誊涯,不必讓它是一個(gè) Human 挡毅,這樣就可以讓 Chewie 駕駛它了;
  • 我們可以把 La?ka 定義成一個(gè) Astronaut暴构,即使她不是人類跪呈;
  • 我們可以將 Spock 定義成 HumanAlien 的結(jié)合體;
  • 我們甚至可以在這個(gè)例子中完全摒棄繼承取逾,并將我們的類型從類(Classes)轉(zhuǎn)換成結(jié)構(gòu)體(Structs)耗绿。結(jié)構(gòu)體不支持繼承,但可以遵循你想要遵循的協(xié)議砾隅,想遵循多少協(xié)議就能遵循多少協(xié)議误阻!

無(wú)處不在的協(xié)議!

因此晴埂,我們的一個(gè)解決方案是徹底棄用繼承究反,將所有的東西都變成協(xié)議。畢竟我們不在乎我們的角色是什么邑时,能夠定義英雄本身的是他們擁有的能力

終結(jié)掉繼承特姐!
終結(jié)掉繼承晶丘!

我在這里附上了一個(gè)可下載的 Swift Playground 文件,包含這篇文章里的所有代碼,并在 Playground 的第二頁(yè)放上了一個(gè)全部用協(xié)議和結(jié)構(gòu)體的解決方案浅浮,完全不用繼承沫浆。快去看看吧滚秩!

這當(dāng)然并不意味著你必須不惜一切代價(jià)放棄對(duì)繼承的使用(別聽那個(gè) Dalek 講太多专执,機(jī)器人畢竟沒感情的??)。繼承依然有用郁油,而且依然有意義——很符合邏輯的一個(gè)說法就是 UILabelUIView 的一個(gè)子類本股。但我們提供的方法能讓你能感受到 Mixins 和協(xié)議帶給你的不同體驗(yàn)。

小結(jié)

實(shí)踐 Swift 的時(shí)候桐腌,你會(huì)意識(shí)到它實(shí)質(zhì)上是一個(gè)面向協(xié)議的語(yǔ)言(Protocols-Oriented language)拄显,而且在 Swift 中使用協(xié)議和在 Objective-C 中使用相比更加常見和有效。畢竟案站,那些類似于 Equatable躬审,CustomStringConvertible 的協(xié)議以及 Swift 標(biāo)準(zhǔn)庫(kù)中其它所有以 -able 結(jié)尾的協(xié)議都可以被看做是 Mixins!

有了 Swift 的協(xié)議和協(xié)議的默認(rèn)實(shí)現(xiàn)蟆盐,你就能實(shí)現(xiàn) Mixins 和 Traits承边,而且你還可以實(shí)現(xiàn)類似于抽象類<sup id="fnref2"><a href="#fn2" rel="footnote">2</a>以及更多的一些東西,這讓你的代碼變得更加靈活石挂。

Mixins 和 Traits 的方式可以讓你描述你的類型能夠做什么博助,而不是描述它們是什么。更重要的是誊稚,它們能夠?yàn)槟愕念愋驮黾痈鞣N能力翔始。這就像購(gòu)物那樣,無(wú)論你的類是從哪個(gè)父類繼承的(如果有)里伯,你都能為它們選擇你想要它們具有的那些能力城瞎。

回到第一個(gè)例子,你可以創(chuàng)建一個(gè) BurgerMenuManager 協(xié)議且該協(xié)議有一個(gè)默認(rèn)實(shí)現(xiàn)疾瓮,然后可以簡(jiǎn)單地將 View Controllers(不論是 UIViewController脖镀,UITableViewController 還是其他的類)都遵循這個(gè)協(xié)議,它們都能自動(dòng)獲得 BurgerMenuManager 所具有的能力和特性狼电,你也根本不用去為父類 UIViewController 操心蜒灰!

我不想離開
我不想離開

關(guān)于協(xié)議擴(kuò)展還有很多要說的,我還想在文章中繼續(xù)告訴你關(guān)于它更多的事情肩碟,因?yàn)樗軌蛲ㄟ^很多方式提高你的代碼質(zhì)量强窖。嘿,但是削祈,這篇文章已經(jīng)挺長(zhǎng)的了翅溺,同時(shí)也為以后的博客文章留一些空間吧脑漫,希望你到時(shí)還會(huì)再來(lái)看!

與此同時(shí)咙崎,生生不息优幸,繁榮昌盛,杰羅尼莫(譯注:跳傘時(shí)老兵鼓勵(lì)新兵的一句話)褪猛!


<a id="fn1" href="#fnref1" rev="footnote">1.我不會(huì)深入去講 Mixin 和 Traits 這兩個(gè)概念之間的區(qū)別网杆。由于這兩個(gè)詞的意思很接近,為簡(jiǎn)單起見伊滋,在本篇文章中它倆可以互相替換使用碳却。</a>
<a id="fn2" href="#fnref2" rev="footnote">2.在以后的博文中會(huì)作為一個(gè)專題去講解。</a>

本文由 SwiftGG 翻譯組翻譯新啼,已經(jīng)獲得作者翻譯授權(quán)追城,最新文章請(qǐng)?jiān)L問 http://swift.gg

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末燥撞,一起剝皮案震驚了整個(gè)濱河市座柱,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌物舒,老刑警劉巖色洞,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異冠胯,居然都是意外死亡火诸,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門荠察,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)置蜀,“玉大人,你說我怎么就攤上這事悉盆《⒒纾” “怎么了?”我有些...
    開封第一講書人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵焕盟,是天一觀的道長(zhǎng)秋秤。 經(jīng)常有香客問我,道長(zhǎng)脚翘,這世上最難降的妖魔是什么灼卢? 我笑而不...
    開封第一講書人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮来农,結(jié)果婚禮上鞋真,老公的妹妹穿的比我還像新娘。我一直安慰自己沃于,他們只是感情好涩咖,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開白布赶袄。 她就那樣靜靜地躺著,像睡著了一般抠藕。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蒋困,一...
    開封第一講書人閱讀 49,007評(píng)論 1 284
  • 那天盾似,我揣著相機(jī)與錄音,去河邊找鬼雪标。 笑死零院,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的村刨。 我是一名探鬼主播告抄,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼嵌牺!你這毒婦竟也來(lái)了打洼?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤逆粹,失蹤者是張志新(化名)和其女友劉穎募疮,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體僻弹,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡阿浓,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蹋绽。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片芭毙。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖卸耘,靈堂內(nèi)的尸體忽然破棺而出退敦,到底是詐尸還是另有隱情,我是刑警寧澤鹊奖,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布苛聘,位于F島的核電站,受9級(jí)特大地震影響忠聚,放射性物質(zhì)發(fā)生泄漏设哗。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一两蟀、第九天 我趴在偏房一處隱蔽的房頂上張望网梢。 院中可真熱鬧,春花似錦赂毯、人聲如沸战虏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)烦感。三九已至巡社,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間手趣,已是汗流浹背晌该。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留绿渣,地道東北人朝群。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像中符,于是被迫代替她去往敵國(guó)和親姜胖。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

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

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)淀散、插件右莱、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,022評(píng)論 4 62
  • 小住海舟公寓。偶有一天档插,知道了自己除大名叫軍嫂外隧出,還有個(gè)小名——軍需。這極其曖昧的稱呼一入耳阀捅,羞臊與不自在便浸濕了...
    清水溪貝閱讀 1,031評(píng)論 4 5
  • 禽獸 一 燕國(guó)集市胀瞪,人群攘攘,皆為利來(lái)饲鄙,人群熙熙凄诞,皆為利往,是為禽獸忍级。 狗屠高手起刀落帆谍,一具具狗肉下鍋,香氣四溢轴咱,...
    有獎(jiǎng)勵(lì)君閱讀 269評(píng)論 1 1
  • 印象江浙 ●田秀 描畫江浙的 是誰(shuí) 今夜的月光 出沒著 ...
    興安居士閱讀 186評(píng)論 0 2
  • 擇業(yè)茲事體大汛蝙,關(guān)乎每個(gè)學(xué)子未來(lái)五年十年甚至一輩子。有人說細(xì)節(jié)決定成敗朴肺,這句話正確嗎窖剑,看什么條件下,我認(rèn)為在找工作這...
    蔚林閱讀 335評(píng)論 0 1