極限編程(XP) 基礎(chǔ)

在軟件項目中,過程與技術(shù)對項目結(jié)果只有次要影響,首要影響是人颊埃。如果想要項目取得成功,我們就必須組建起具有合作精神的自組織的團隊蝶俱,而極限編程便是眾多實現(xiàn)這個目標(biāo)的可行方法之一班利,極限編程方法論可以說是敏捷聯(lián)盟中最鮮艷的一面旗幟,也是被研究榨呆、嘗試罗标、應(yīng)用、贊揚积蜻、批判最多的一種方法論闯割,也是相對來說最成熟的一種。

與很多敏捷實踐一樣竿拆,極限編程方法也是由一組價值觀原則和實踐構(gòu)成的方法論體系纽谒,極限編程提倡溝通、反饋如输、簡單鼓黔、勇氣、尊重的價值觀不见,他提倡可持續(xù)的開發(fā)速度澳化、自動化測試、有效溝通稳吮、共享工作空間缎谷、現(xiàn)場客戶代表等實踐方法。大家常見的主要有十三種主要的實踐方法灶似,一般會以下面這種圖形方式來展現(xiàn)列林。


image

完整團隊/客戶現(xiàn)場參與

XP項目的所有參與者(開發(fā)人員瑞你、客戶、測試人員等)一起工作在一個開放的場所中希痴,他們是同一個團隊的成員者甲。這個場所的墻壁上隨意懸掛著大幅的、顯著的圖表以及其他一些顯示他們進度的東西砌创,以便彼此可以方便的知曉對方所面臨的問題虏缸,并能共同去解決。

為了保證開發(fā)出來的結(jié)果與客戶的預(yù)期一致嫩实,XP 認為最好的方法就是將客戶請到開發(fā)現(xiàn)場刽辙,在XP項目中,應(yīng)該時刻保證客戶負責(zé)業(yè)務(wù)決策甲献,開發(fā)團隊負責(zé)技術(shù)決策宰缤。因此,在項目中有客戶在現(xiàn)場參與用戶故事編寫及過程討論晃洒,并做出相應(yīng)的業(yè)務(wù)決策慨灭,對于 XP 項目而言有著十分重要的意義。千萬不要認為客戶在現(xiàn)場會帶來更多需求變更而拒絕讓客戶充分參與锥累,作為一名有經(jīng)驗的開發(fā)人員缘挑,絕對不會對現(xiàn)場客戶的價值產(chǎn)生任何懷疑,如果實在不具備客戶現(xiàn)場參與項目的條件也需要開發(fā)團隊?wèi)?yīng)該和客戶能夠隨時溝通桶略,可以是面談语淘,可以是在線聊天,可以是電話际歼,當(dāng)然面談是必不可少的惶翻。其中的關(guān)鍵是當(dāng)開發(fā)人員需要客戶做出業(yè)務(wù)決策是,需要進一步了解業(yè)務(wù)細節(jié)時能夠隨時找到相應(yīng)的客戶鹅心。

計劃游戲

計劃游戲的主要思想就是先快速地制定一份概要的計劃吕粗,然后隨著項目細節(jié)的不斷清晰,再逐步完善這份計劃旭愧。計劃游戲產(chǎn)生的結(jié)果是一套用戶故事及后續(xù)的一兩次迭代的概要計劃颅筋。

“客戶負責(zé)業(yè)務(wù)決策,開發(fā)團隊負責(zé)技術(shù)決策”是計劃游戲獲得成功的前提條件输枯。也就是說议泵,系統(tǒng)的范圍、下一次迭代的發(fā)布時間桃熄、用戶故事的優(yōu)先級應(yīng)該由客戶決定先口;而每個用戶故事所需的開發(fā)時間、不同技術(shù)的成本、如何組建團隊碉京、每個用戶故事的風(fēng)險厢汹,以及具體的開發(fā)順序應(yīng)該由開發(fā)團隊決定。

計劃游戲的一般過程是:首先客戶和開發(fā)人員坐在同一間屋子里谐宙,每個人都準(zhǔn)備一支筆烫葬、一些用于記錄用戶故事的紙片,最好再準(zhǔn)備一個白板卧惜,就可以開始了:

1. 客戶編寫故事

由客戶談?wù)撓到y(tǒng)應(yīng)該完成什么功能厘灼,然后用通俗的自然語言夹纫,使用自己的語匯咽瓷,將其寫在卡片上,這也就是用戶故事舰讹,初次實踐一般可以采用三段式方式編寫茅姜,詳細可以參考《用戶故事與敏捷方法》。

2. 開發(fā)人員進行估算

首先客戶按優(yōu)先級將用戶故事排序月匣,比如可以按照必須要有钻洒、希望有、如果有更好三類锄开,然后開發(fā)人員對每個用戶故事進行估算(可以采用計劃撲克等方式)素标,先從高優(yōu)先級開始估算。如果在估算的時候萍悴,感到有一些故事太大头遭,不容易進行估算,無法在一個迭代內(nèi)完成癣诱,那么就應(yīng)該對其進行分解计维,拆成多個小故事。

3. 確定迭代的周期

接下來就是確定本次迭代的時間周期撕予,這可以根據(jù)實際的情況進行確定鲫惶,一般推薦迭代周期是 1~4 周。確定了迭代周期之后結(jié)合參與的開發(fā)人數(shù)实抡,算出可以完成的工作量總數(shù)欠母。然后根據(jù)估算的結(jié)果,與客戶協(xié)商吆寨,根據(jù)優(yōu)先級挑出足夠本迭代完成的用戶故事赏淌,形成迭代計劃。

小規(guī)模頻繁發(fā)布

XP 方法論秉承的是“持續(xù)集成鸟废,小步快走”的哲學(xué)猜敢,也就是說每一次發(fā)布的版本應(yīng)該盡可能的小,而且需要確保每個版本有足夠的商業(yè)價值,值得發(fā)布缩擂。由于小型發(fā)布可以使得集成更頻繁鼠冕,客戶獲得的中間結(jié)果也越頻繁,反饋也就越頻繁胯盯,客戶就能夠?qū)崟r地了解項目的進展情況懈费,從而提出更多的意見,以便在下一次迭代中計劃進去博脑。以實現(xiàn)更高的客戶滿意度憎乙。

標(biāo)準(zhǔn)代碼/編碼規(guī)范

編碼標(biāo)準(zhǔn)是一個“雅俗共享”的最佳實踐,不管是代表重型方法論的 RUP叉趣,PSP泞边,還是代表敏捷方法論的 XP,都認為開發(fā)團隊?wèi)?yīng)該擁有一個統(tǒng)一的編碼標(biāo)準(zhǔn)疗杉。XP 方法論認為擁有編碼標(biāo)準(zhǔn)可以避免團隊在一些與開發(fā)進度無關(guān)的細節(jié)問題上發(fā)生爭論阵谚,而且會給重構(gòu)、結(jié)對編程帶來很大麻煩烟具。試想如果有人將你上次寫的代碼的變量命名法做了修改梢什,下次你需要再改這部分代碼時,會是一種什么感覺呢朝聋?

不過嗡午,XP 方法論的編碼標(biāo)準(zhǔn)的目的不是創(chuàng)建一個事無巨細的規(guī)則表,而是只要能夠提供一個確保代碼清晰冀痕,便于交流的指導(dǎo)方針荔睹。

如果你的團隊已經(jīng)擁有編碼標(biāo)準(zhǔn),就可以直接使用它金度,并在過程中進行完善应媚。如果還沒有,那么大家可以先進行編碼猜极,然后在過程中逐步總結(jié)出編碼規(guī)則中姜,邊做邊形成。當(dāng)然除了這種文字規(guī)范以外跟伏,還可以采用一些如自動格式化代碼工具之類的方法進行代碼規(guī)范丢胚。事實上,你只需要很好地貫徹執(zhí)行其他的實踐并且進行溝通受扳,編碼標(biāo)準(zhǔn)會很容易地浮現(xiàn)出來携龟。

共同擁有代碼

由于 XP 方法論鼓勵團隊進行結(jié)對編程,而且認為結(jié)對編程的組合應(yīng)該動態(tài)地搭配勘高,根據(jù)任務(wù)的不同峡蟋、專業(yè)技能的不同進行最優(yōu)組合坟桅。由于每個人都肯定會遇到不同的代碼,所以代碼的所有制就不再適合于私有蕊蝗,因為那樣會給修改工作帶來巨大的不便仅乓。

也就是說,團隊中的每個成員都擁有對代碼進行改進的權(quán)利蓬戚,每個人都擁有全部代碼夸楣,也都需要對全部代碼負責(zé)。同時子漩,XP 強調(diào)代碼是誰破壞的豫喧,就應(yīng)該由誰來修復(fù)。

由于在 XP 過程中幢泼,有一些與之匹配的最佳實踐紧显,因此你并無須擔(dān)心采用集體代碼所有制會讓你的代碼變得越來越亂:

  1. 由于在 XP 項目中,集成工作是一件經(jīng)常性得工作旭绒,因此當(dāng)有人修改代碼而帶來了集成的問題鸟妙,會在很快的時間內(nèi)被發(fā)現(xiàn)焦人。
  2. 由于每一個類都會有一個測試代碼挥吵,因此不論誰修改了代碼,都需要運行這個測試代碼花椭,這樣偶然性的破壞發(fā)生的概率將很小忽匈。
  3. 由于每一個代碼的修改就是通過了結(jié)對的兩個程序員共同思考,因此通常做出的修改都是對系統(tǒng)有益的矿辽。
  4. 由于大家都堅持了相同的編碼標(biāo)準(zhǔn)丹允,因此代碼的可讀性、可修改性都會比較好袋倔,而且還能夠避免由于命名法雕蔽、縮進等小問題引發(fā)經(jīng)常性得代碼修改。

集成代碼所有制是 XP 與其他敏捷方法的一個較大不同宾娜,也是從另一個側(cè)面體現(xiàn)了 XP 中蘊含的很深厚的編碼情節(jié)批狐。

持續(xù)集成

在前面談到小型發(fā)布、重構(gòu)前塔、結(jié)對編程嚣艇、集體代碼所有制等最佳實踐的時候,我們多次看到“持續(xù)集成”的字眼华弓,可以說持續(xù)集成是對這些最佳實踐的基本支撐條件食零。

可能大家會對持續(xù)集成與小型發(fā)布代表的意思混淆不清,其實小型發(fā)布是指在開發(fā)周期經(jīng)常發(fā)布中間版本寂屏,而持續(xù)集成的含義則是要求 XP 團隊每天盡可能多次地做代碼集成贰谣,每次都在確保系統(tǒng)運行的單元測試通過之后進行娜搂。

這樣,就可以及早地暴露吱抚、消除由于重構(gòu)涌攻、集體代碼所有制所引入的錯誤,從而減少解決問題的痛苦频伤。要在開發(fā)過程中做到持續(xù)集成并不容易恳谎,首先需要養(yǎng)成這個習(xí)慣。而且集成工作往往是十分枯燥憋肖、煩瑣的因痛,因此適當(dāng)?shù)匾朊咳占晒ぞ呤鞘直匾摹P 建議大家首先使用配置管理服務(wù)器將代碼管理起來岸更,然后使用Jenkins等工具搭建持續(xù)集成環(huán)境鸵膏。

隱喻

相對而言,隱喻這一個最佳實踐是極限編程實踐中最模糊的一個怎炊,也比較令人費解谭企。總結(jié)而言评肆,隱喻主要還是一種溝通技巧债查,用于提高溝通效率和溝通效果,常常用于四個方面瓜挽。

  1. 尋求共識:也就是鼓勵開發(fā)人員在尋求問題共識時盹廷,可以借用一些溝通雙方都比較熟悉的事物來做類比,從而幫助大家更好地理解解決方案的關(guān)鍵結(jié)構(gòu)久橙,也就是更好地理解系統(tǒng)是什么俄占、能做什么。
  2. 發(fā)明共享詞匯:通過隱喻淆衷,有助于提出一個用來表示對象缸榄、對象間的關(guān)系通用名稱。例如祝拯,策略模式(用來表示可以實現(xiàn)多種不同策略的設(shè)計模式)甚带、工廠模式(用來表示可以按需“生產(chǎn)”出所需類得設(shè)計模式)等。
  3. 創(chuàng)新的武器:有的時候鹿驼,可以借助其他東西來找到解決問題的新途徑欲低。例如:“我們可以將工作流看做一個生產(chǎn)線”。
  4. 描述體系結(jié)構(gòu):體系結(jié)構(gòu)是比較抽象的畜晰,引入隱喻能夠大大減輕理解的復(fù)雜度砾莱。例如管道體系結(jié)構(gòu)就是指兩個構(gòu)件之間通過一條傳遞消息的“管道”進行通信。

當(dāng)然凄鼻,如果能夠找到合適的隱喻是十分快樂的腊瑟,但并不是每種情況都可以找到恰當(dāng)?shù)碾[喻聚假,你也沒有必要強求

保持流動性/穩(wěn)定可持續(xù)的速度

這是最讓開發(fā)人員開心的、管理者反對的一個最佳實踐了闰非,在996已成為好多公司常態(tài)的國內(nèi)環(huán)境下尤其如此膘格,加班、再加班早已成為開發(fā)人員的家常便飯财松,也是管理者最常使用的一種策略瘪贱,而 XP 方法論認為,加班最終會扼殺團隊的積極性辆毡,最終導(dǎo)致項目失敗菜秦,這也充分體現(xiàn)了 XP 方法關(guān)注人的因素比關(guān)注過程的因素更多一些。

Kent Beck 認為開發(fā)人員即使能夠工作更長的時間舶掖,他們也不該這樣做球昨,因為這樣做會使他們更容易厭倦編程工作,從而產(chǎn)生一些影響他們效能的其他問題眨攘。因此主慰,每周工作 40 小時是一種順勢行為,是一種規(guī)律鲫售。其實對于開發(fā)人員和管理者來說共螺,違反這種規(guī)律是不值得的。

團隊只有持久才有獲勝的希望龟虎。他們以能夠長期維持的速度努力工作璃谨,他們保存精力,他們把項目看作是馬拉松長跑鲤妥,而不是全速短跑。

重構(gòu)

重構(gòu)時一種對代碼進行改進而不影響功能實現(xiàn)的技術(shù)拱雏,XP 需要開發(fā)人員在聞到代碼的壞味道時棉安,有重構(gòu)代碼的勇氣。重構(gòu)的目的是降低變化引發(fā)的風(fēng)險铸抑,使得代碼優(yōu)化更加容易贡耽。通常重構(gòu)發(fā)生在兩種情況之下。

實現(xiàn)某個特性之前:嘗試改變現(xiàn)有的代碼結(jié)構(gòu)鹊汛,以使得實現(xiàn)新的特性更加容易蒲赂。
實現(xiàn)某個特性之后:檢查剛剛寫完的代碼后,認真檢查一下刁憋,看是否能夠進行簡化滥嘴。

在《重構(gòu)》一書中,作者 Martin Fowler 提示我們:在考慮重構(gòu)時至耻,應(yīng)該要養(yǎng)成編寫并經(jīng)常運行測試代碼的習(xí)慣若皱;要先編寫代碼镊叁,再進行重構(gòu);把每一次增加功能都當(dāng)做一次重構(gòu)的好時機走触;將每一個糾正錯誤當(dāng)做一次重構(gòu)的重要時機晦譬。同時,該書中也列出大量需要重構(gòu)的情況和重構(gòu)方法互广。

簡單設(shè)計

強調(diào)簡單設(shè)計的價值觀敛腌,引出了簡單性假設(shè)原則,落到實處就是“簡單設(shè)計”實踐惫皱。這個實踐看上去似乎很容易理解迎瞧,但卻又經(jīng)常被誤解,許多批評者就指責(zé) XP 忽略設(shè)計是不正確的逸吵。其實凶硅,XP 的簡單設(shè)計實踐并不是要忽略設(shè)計,而且認為設(shè)計不應(yīng)該在編碼之前一次性完成扫皱,因為那樣只能建立在“情況不會發(fā)生變化”或者“我們可以預(yù)見所有的變化”之類的謊言的基礎(chǔ)上的足绅。

Kent Beck 概念中簡單設(shè)計是這樣的:

  1. 能夠通過所有的測試程序。
  2. 沒有包括任何重復(fù)的代碼韩脑。
  3. 清楚地表現(xiàn)了程序員賦予的所有意圖氢妈。
  4. 包括盡可能少的類和方法
  5. 他認為要想保持設(shè)計簡單的系統(tǒng),需要具備簡單思考的能力段多,擁有理解代碼和修改的勇氣首量,以及為了消除代碼的“壞味道”而定期重構(gòu)的習(xí)慣。

那么如何開始進行簡單的設(shè)計呢进苍?XP 實踐者們也總結(jié)也一些具體的加缘、可操作的思考方法。

  1. 首先寫測試代碼:具體將在后面詳細描述觉啊。
  2. 保持每個類只負責(zé)一件事:SRP(單一職責(zé)原則)是面向?qū)ο笤O(shè)計的基礎(chǔ)原則之一拣宏。
  3. 使用 Demeter(迪米特)法則:迪米特法則,也稱為 LoD 法則杠人、最少知識原則勋乾。也就是指一個對象應(yīng)當(dāng)對其他對象盡可能少地了解。用隱喻的方法來解釋的話就是“只與你直接的朋友通信”嗡善、“不要和陌生人說話”辑莫。

結(jié)對編程

這個是國內(nèi)公司最難接受的一個實踐方法,至少目前我還沒見過幾個會大規(guī)模應(yīng)用的公司罩引。國外公司這方面的嘗試相對會多一些各吨,長期以來的研究結(jié)果表明:結(jié)對編程的效率確實比單獨編程更高。往往一開始會犧牲一些速度蜒程,但慢慢的绅你,開發(fā)速度會逐漸加快伺帘,究其原因,主要是結(jié)對編程大打降低了溝通的成本忌锯,提供了工作的質(zhì)量伪嫁。

測試驅(qū)動開發(fā)

當(dāng)我第一次看到“測試先行”這個概念的時候,我也不太理解偶垮,也不知道如何下手张咳,后來參加培訓(xùn)時候老師舉了個例子,工匠砌墻時候:先拉上一根水平線似舵,砌每一塊磚時脚猾,都與這跟水平線進行比較,使得每一塊磚都保持水平砚哗。

而在軟件開發(fā)過程中龙助,我們不僅我們沒有采用工匠一的工作方法,甚至有的時候程序員會以“開發(fā)工作太緊張”為理由蛛芥,而忽略測試工作提鸟。但這樣卻導(dǎo)致了一個惡性循環(huán),越是沒有空編寫測試程序仅淑,代碼的效率與質(zhì)量越差称勋,花在找 Bug、解決 Bug 的時間也越來越多涯竟,實際產(chǎn)能大打降低赡鲜。由于產(chǎn)能降低了,因此時間更緊張庐船,壓力更大银酬。你想想,為什么不拉上一根水平線呢醉鳖?難道捡硅,我們不能夠?qū)⒑竺胬速M的時間花在單元測試上,使得我們的程序一開始就更健壯盗棵,更加易于修改嗎?不過北发,編寫測試程序當(dāng)然要比拉一條水平線難道多纹因,所以我們需要引入“自動化測試工具”,免費的 xUnit 測試框架就是你最佳的選擇琳拨。

  1. 當(dāng)所有的測試都通過的時候瞭恰,你再也不會擔(dān)心所寫的代碼今后會“暗箭傷人”,那種感覺是相當(dāng)棒的狱庇。
  2. 當(dāng)你的客戶看到所有的測試都通過的時候惊畏,會對程序充滿前所未有的信心恶耽。
  3. 當(dāng)你需要進行重構(gòu)時,測試代碼會給你帶來更大的勇氣颜启,因為你要測試是否重構(gòu)成功只需要一個按鈕偷俭。

測試先行是 XP 方法論中一個十分重要的最佳實踐,并且其中所蘊含的知識與方法也十分豐富缰盏。

極限編程早在20多年前就已經(jīng)由Kent Beck在國外開始推廣涌萤,經(jīng)過了廣泛的實際項目的驗證,建議每個開發(fā)人員應(yīng)該去嘗試學(xué)習(xí)和了解這個已經(jīng)有二十年歷史的專門給程序員準(zhǔn)備的方法學(xué)口猜,學(xué)會之后再決定是否適用于你的工作場景。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市俺抽,隨后出現(xiàn)的幾起案子凯亮,更是在濱河造成了極大的恐慌,老刑警劉巖须尚,帶你破解...
    沈念sama閱讀 211,376評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件崖堤,死亡現(xiàn)場離奇詭異,居然都是意外死亡恨闪,警方通過查閱死者的電腦和手機倘感,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來咙咽,“玉大人老玛,你說我怎么就攤上這事【ǎ” “怎么了蜡豹?”我有些...
    開封第一講書人閱讀 156,966評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長溉苛。 經(jīng)常有香客問我镜廉,道長,這世上最難降的妖魔是什么愚战? 我笑而不...
    開封第一講書人閱讀 56,432評論 1 283
  • 正文 為了忘掉前任娇唯,我火速辦了婚禮,結(jié)果婚禮上寂玲,老公的妹妹穿的比我還像新娘塔插。我一直安慰自己,他們只是感情好拓哟,可當(dāng)我...
    茶點故事閱讀 65,519評論 6 385
  • 文/花漫 我一把揭開白布想许。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪流纹。 梳的紋絲不亂的頭發(fā)上糜烹,一...
    開封第一講書人閱讀 49,792評論 1 290
  • 那天,我揣著相機與錄音漱凝,去河邊找鬼疮蹦。 笑死,一個胖子當(dāng)著我的面吹牛碉哑,可吹牛的內(nèi)容都是我干的挚币。 我是一名探鬼主播,決...
    沈念sama閱讀 38,933評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼扣典,長吁一口氣:“原來是場噩夢啊……” “哼妆毕!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起贮尖,我...
    開封第一講書人閱讀 37,701評論 0 266
  • 序言:老撾萬榮一對情侶失蹤笛粘,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后湿硝,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體薪前,經(jīng)...
    沈念sama閱讀 44,143評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,488評論 2 327
  • 正文 我和宋清朗相戀三年关斜,在試婚紗的時候發(fā)現(xiàn)自己被綠了示括。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,626評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡痢畜,死狀恐怖垛膝,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情丁稀,我是刑警寧澤吼拥,帶...
    沈念sama閱讀 34,292評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站线衫,受9級特大地震影響凿可,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜授账,卻給世界環(huán)境...
    茶點故事閱讀 39,896評論 3 313
  • 文/蒙蒙 一枯跑、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧白热,春花似錦全肮、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至乍恐,卻和暖如春评疗,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背茵烈。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工百匆, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人呜投。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓加匈,卻偏偏與公主長得像,于是被迫代替她去往敵國和親仑荐。 傳聞我的和親對象是個殘疾皇子雕拼,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,494評論 2 348

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