青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆 - 181, 文章 - 2, 評(píng)論 - 85, 引用 - 0
數(shù)據(jù)加載中……

6月19日----- 通過(guò)服務(wù)模擬來(lái)簡(jiǎn)化 SOA 開(kāi)發(fā)

?

?

通過(guò)用例和模擬對(duì)象簡(jiǎn)化 SOA 開(kāi)發(fā)——特別在您的項(xiàng)目涉及多個(gè)團(tuán)隊(duì)時(shí)——并提高 SOA 應(yīng)用程序質(zhì)量。

借助于可重用服務(wù)和需要很少的新代碼的應(yīng)用程序(因?yàn)榭梢砸蕾?lài)這些可重用服務(wù)),面向服務(wù)的體系結(jié)構(gòu) (SOA) 可以大幅度提高應(yīng)用程序開(kāi)發(fā)的速度。但是 SOA 還可能大大增加應(yīng)用程序開(kāi)發(fā)的復(fù)雜性,因?yàn)閳F(tuán)隊(duì)需要同時(shí)進(jìn)行應(yīng)用程序的不同部分的工作,而且要在最后成功地將各個(gè)部分組合起來(lái)。本文將探討致使 SOA 開(kāi)發(fā)變得困難的原因,并提供了一個(gè)可以對(duì)其進(jìn)行簡(jiǎn)化的流程。各種組織可以使用此流程來(lái)極大地增加其 SOA 成功的幾率。

SOA 開(kāi)發(fā)問(wèn)題

使用 SOA 開(kāi)發(fā)應(yīng)用程序可提供更多的應(yīng)用程序部署選項(xiàng),但也使得開(kāi)發(fā)工作變得越發(fā)困難。這是因?yàn)?SOA 將應(yīng)用程序開(kāi)發(fā)拆分為兩個(gè)截然不同的部分:

  • SOA 服務(wù)提供程序(SOA Service Provider,SOA-SP) ——該層的代碼實(shí)現(xiàn)服務(wù)。它具有服務(wù) API,以對(duì)服務(wù)進(jìn)行聲明和為客戶(hù)機(jī)提供調(diào)用服務(wù)的方法。
  • SOA 服務(wù)協(xié)調(diào)程序(SOA Service Coordinator,SOA-SC)——該層的代碼通過(guò)一個(gè)或多個(gè) SOA-SP 中的服務(wù)提供用戶(hù)功能。它可能具有 UI 或 GUI,以便同傳統(tǒng)應(yīng)用程序一樣與 SOA-SC 進(jìn)行交互。

例如,某個(gè)金融應(yīng)用程序的 SOA 可能如圖 1 中所示。


圖 1:個(gè)人金融應(yīng)用程序和服務(wù)
個(gè)人金融應(yīng)用程序和服務(wù)

通常由獨(dú)立的團(tuán)隊(duì)分別負(fù)責(zé)同時(shí)開(kāi)發(fā)這兩個(gè)獨(dú)立的部分。一個(gè)團(tuán)隊(duì)負(fù)責(zé)開(kāi)發(fā) SOA-SC——對(duì)用戶(hù)而言的應(yīng)用程序。另一個(gè)團(tuán)隊(duì)負(fù)責(zé)開(kāi)發(fā) SOA-SP,或許存在多個(gè)負(fù)責(zé)此項(xiàng)任務(wù)的團(tuán)隊(duì),而每個(gè)團(tuán)隊(duì)負(fù)責(zé)開(kāi)發(fā)若干服務(wù)。雖然可能已經(jīng)實(shí)現(xiàn)了一些提供程序,但可能仍然需要專(zhuān)門(mén)為此應(yīng)用程序?qū)崿F(xiàn)其他的提供程序。

而這給我們提出了第一個(gè)問(wèn)題:如果某些提供程序尚未實(shí)現(xiàn),協(xié)調(diào)程序開(kāi)發(fā)團(tuán)隊(duì)如何開(kāi)發(fā)其負(fù)責(zé)的應(yīng)用程序部分呢?

這兩個(gè)團(tuán)隊(duì)——開(kāi)發(fā)服務(wù)的團(tuán)隊(duì)和開(kāi)發(fā)協(xié)調(diào)程序的團(tuán)隊(duì)——需要使其活動(dòng)同步。他們必須就服務(wù) API 達(dá)成一致;服務(wù) API 可以是簡(jiǎn)單的 Java? 接口或 Java Message Service (JMS) 消息格式和隊(duì)列名稱(chēng),但必須就此達(dá)成一致。但僅就接口達(dá)成一致是不夠的;服務(wù)具有行為,因此團(tuán)隊(duì)必須就服務(wù)的行為達(dá)成一致。服務(wù)并不會(huì)始終成功地工作,因此團(tuán)隊(duì)還必須就錯(cuò)誤情況和相應(yīng)的響應(yīng)達(dá)成一致。

在理想的情況下,多個(gè)團(tuán)隊(duì)可以非常容易地協(xié)調(diào)工作,最初的決策可以稍后進(jìn)行修改,而所造成的影響卻非常小,并且評(píng)估工作非常靈活,此外還會(huì)不斷地進(jìn)行改進(jìn)。在現(xiàn)實(shí)世界中,團(tuán)隊(duì)之間經(jīng)常存在協(xié)作問(wèn)題,往往較早地(甚至不成熟地)做出不可更改的決策,而且評(píng)估方法是固定的。

這樣就帶來(lái)了第二個(gè)問(wèn)題:協(xié)調(diào)程序和提供程序團(tuán)隊(duì)如何較早而可靠地就服務(wù)如何工作達(dá)成一致?

經(jīng)常通過(guò)多個(gè)提供程序來(lái)實(shí)現(xiàn)服務(wù)冗余。這樣就可以在提供程序之間提供負(fù)載平衡和故障轉(zhuǎn)移功能,從而使得協(xié)調(diào)程序的服務(wù)體驗(yàn)更為一致和可靠。冗余可以通過(guò)多次部署同一服務(wù)實(shí)現(xiàn)來(lái)實(shí)現(xiàn)。不過(guò),當(dāng)不同的供應(yīng)商部署了不同的提供程序時(shí),服務(wù)幾乎肯定具有不同的實(shí)現(xiàn)。盡管如此,對(duì)于協(xié)調(diào)程序,所有提供程序的全部實(shí)現(xiàn)的工作方式都必須一致,以便協(xié)調(diào)程序可以采用可交換的方式來(lái)調(diào)用提供程序。服務(wù)的不同實(shí)現(xiàn)(特別是來(lái)自不同供應(yīng)商的不同實(shí)現(xiàn))是由不同的團(tuán)隊(duì)開(kāi)發(fā)的,而這些團(tuán)隊(duì)必須加以協(xié)調(diào),以確保開(kāi)發(fā)的是相同的服務(wù)。

因此,第三個(gè)問(wèn)題就是:多個(gè)提供程序團(tuán)隊(duì)如何實(shí)現(xiàn)相同的服務(wù),以確保他們的實(shí)現(xiàn)具有兼容性?

以上是使用 SOA 進(jìn)行開(kāi)發(fā)的主要問(wèn)題。必須實(shí)現(xiàn)尚未開(kāi)發(fā)的服務(wù)來(lái)開(kāi)發(fā)協(xié)調(diào)程序,協(xié)調(diào)程序團(tuán)隊(duì)和提供程序團(tuán)隊(duì)必須就服務(wù)如何工作達(dá)成一致,而且,多個(gè)提供程序團(tuán)隊(duì)也必須就服務(wù)如何工作達(dá)成一致。如果沒(méi)有良好的流程,這就會(huì)導(dǎo)致一片混亂,如果不對(duì)其進(jìn)行檢查,將會(huì)導(dǎo)致 SOA 項(xiàng)目失敗。




?
?


SOA 開(kāi)發(fā)流程

下面給出用于對(duì)協(xié)調(diào)程序和提供程序團(tuán)隊(duì)進(jìn)行同步的簡(jiǎn)單流程,以幫助確保可重用服務(wù)以及使用這些服務(wù)的應(yīng)用程序能夠成功地進(jìn)行開(kāi)發(fā):

  1. 使用服務(wù)用例描述服務(wù)。
  2. 開(kāi)發(fā)體現(xiàn)服務(wù)用例的服務(wù)測(cè)試。
  3. 開(kāi)發(fā)通過(guò)服務(wù)測(cè)試的服務(wù)模擬。
  4. 提供程序團(tuán)隊(duì)采用服務(wù)模擬作為原型,并將服務(wù)測(cè)試作為要求,從而實(shí)現(xiàn)服務(wù)。
  5. 協(xié)調(diào)程序團(tuán)隊(duì)將服務(wù)測(cè)試作為服務(wù)使用者可以進(jìn)行的工作的示例,并在實(shí)際的服務(wù)仍然處于開(kāi)發(fā)過(guò)程的同時(shí)使用服務(wù)模擬對(duì)其代碼進(jìn)行測(cè)試。

這個(gè)簡(jiǎn)單的流程處理了以下問(wèn)題:如何確定服務(wù)的范圍以及如何保持團(tuán)隊(duì)的一致性和高效率,從而避免發(fā)生意外。公正地說(shuō),還有許多其他問(wèn)題仍然沒(méi)有通過(guò)此流程得到解決。該流程并沒(méi)有涉及服務(wù)自身如何開(kāi)發(fā)或協(xié)調(diào)應(yīng)用程序如何開(kāi)發(fā)的問(wèn)題。它并不涉及服務(wù)的質(zhì)量問(wèn)題(即服務(wù)的可靠性問(wèn)題),而是只定義服務(wù)如何提供必要的行為。該流程總體上也不處理傳統(tǒng)獨(dú)立應(yīng)用程序如何使用 SOA 重新進(jìn)行體系結(jié)構(gòu)設(shè)計(jì),以及如何發(fā)現(xiàn)或設(shè)計(jì)服務(wù)。所有這些問(wèn)題都是必要的,但其并不在此流程的范圍之內(nèi)。

此流程使協(xié)調(diào)應(yīng)用程序和服務(wù)實(shí)現(xiàn)協(xié)同工作,并允許團(tuán)隊(duì)以相當(dāng)獨(dú)立的方式同時(shí)對(duì)這兩個(gè)部分進(jìn)行開(kāi)發(fā)。這并非 SOA 項(xiàng)目所需的全部?jī)?nèi)容,但卻是一個(gè)不錯(cuò)的起點(diǎn)。

為了說(shuō)明此流程,我將討論如何實(shí)現(xiàn)一個(gè)簡(jiǎn)單服務(wù)。它就是大家都喜歡用的服務(wù)示例,即股票報(bào)價(jià)服務(wù)。為了讓內(nèi)容更豐富一些,我提供了以下三種類(lèi)型的信息:

  1. 簡(jiǎn)單的當(dāng)前價(jià)格報(bào)價(jià)
  2. 包含當(dāng)前價(jià)格、當(dāng)日最高價(jià)和最低價(jià)以及當(dāng)天交易量的復(fù)雜報(bào)價(jià)
  3. 包含過(guò)去某天的復(fù)雜報(bào)價(jià)的歷史報(bào)價(jià)

此示例應(yīng)該足以闡釋該流程的工作過(guò)程。

服務(wù)用例

此 SOA 開(kāi)發(fā)流程中的第一步是開(kāi)發(fā)描述服務(wù)的服務(wù)用例。

Alistair Cockburn 將用例 定義為“系統(tǒng)涉眾之間有關(guān)系統(tǒng)的行為的協(xié)定”(請(qǐng)參閱參考資料部分列出的 Writing Effective Use Cases)。用例必須適合所定義的系統(tǒng)范圍,能夠代表此情況下使用系統(tǒng)的主要參與者的觀(guān)點(diǎn),且能夠在一致的抽象層次上表示參與者的系統(tǒng)使用情況。

Alistair 給出的一個(gè)例子是網(wǎng)上的股票購(gòu)買(mǎi)服務(wù),其中,購(gòu)買(mǎi)者使用與股票代理的網(wǎng)站協(xié)同工作的個(gè)人金融應(yīng)用程序來(lái)購(gòu)買(mǎi)股票。系統(tǒng)范圍既包含金融應(yīng)用程序,又包含代理的網(wǎng)站。購(gòu)買(mǎi)者是主要的參與者。抽象級(jí)別為應(yīng)用程序和網(wǎng)站之間的交互,而不是應(yīng)用程序或網(wǎng)站內(nèi)的詳細(xì)信息。用例將描述主要成功方案(購(gòu)買(mǎi)者根據(jù)這些方案購(gòu)買(mǎi)股票)和一些可能出現(xiàn)錯(cuò)誤的擴(kuò)展。

因此,用例是關(guān)于以下內(nèi)容的文本描述:希望系統(tǒng)如何工作、將涉及到哪些人以及他們之間如何交互、系統(tǒng)在正常運(yùn)行時(shí)如何工作,以及出現(xiàn)錯(cuò)誤時(shí)應(yīng)該如何處理。它關(guān)心的是系統(tǒng)將做什么,而不考慮將如何 實(shí)現(xiàn)。

現(xiàn)在,假定所討論的不是系統(tǒng)或應(yīng)用程序,而是一個(gè) SOA 服務(wù)。用例技術(shù)仍然適用。可以采用此技術(shù)來(lái)描述服務(wù)使用者與服務(wù)提供程序如何進(jìn)行交互,說(shuō)明服務(wù)做什么 而不用描述其如何 實(shí)現(xiàn)。服務(wù)用例 的最初草稿應(yīng)將重點(diǎn)放在服務(wù)的行為上。由于這是必須調(diào)用的服務(wù),因此后面的用例草稿還應(yīng)該指定調(diào)用協(xié)議——將用于調(diào)用服務(wù)的技術(shù)、傳輸和數(shù)據(jù)格式。(用例純粹主義者甚至可能說(shuō)協(xié)議不屬于用例的實(shí)現(xiàn)細(xì)節(jié),他們是對(duì)的。但服務(wù)用例不僅描述服務(wù),而且還要描述如何調(diào)用該服務(wù),因此協(xié)議是使用者和提供程序參與者之間的協(xié)定的一部分,必須在某個(gè)地方加以指定。)

因此,開(kāi)發(fā)用例的第一步是對(duì)服務(wù)完成的操作進(jìn)行充分的描述。此描述代表了使用者對(duì)提供程序必須提供的行為的要求,主要由協(xié)調(diào)程序開(kāi)發(fā)團(tuán)隊(duì)創(chuàng)建,但同樣以提供程序開(kāi)發(fā)團(tuán)隊(duì)提供的輸出為基礎(chǔ)。這兩種類(lèi)型的開(kāi)發(fā)團(tuán)隊(duì)必須對(duì)用例滿(mǎn)意才行,因?yàn)檫@些用例是對(duì)所有團(tuán)隊(duì)開(kāi)發(fā)其負(fù)責(zé)的應(yīng)用程序部分的要求。

服務(wù)不僅要在條件良好的情況下正常工作,而且還要能夠恰當(dāng)?shù)靥幚沓霈F(xiàn)錯(cuò)誤的情況,這非常重要。因此,您的服務(wù)用例應(yīng)該對(duì)錯(cuò)誤情況和服務(wù)無(wú)法成功處理的錯(cuò)誤輸入加以處理。其中很多錯(cuò)誤路徑最終都表現(xiàn)為用例的備用路徑。其他錯(cuò)誤場(chǎng)景也可能非常極端,因而需要各自的錯(cuò)誤用例。在這兩種方法中,用例都必須記錄服務(wù)如何像成功路徑一樣全面地處理錯(cuò)誤。

示例用例

例如,讓我們看看股票報(bào)價(jià)示例的服務(wù)用例。它需要做三件事,因此需要以下三個(gè)服務(wù)用例:

  1. 簡(jiǎn)單報(bào)價(jià):使用者傳入股票代碼;提供程序返回指定的股票的當(dāng)前價(jià)格。
  2. 復(fù)雜報(bào)價(jià):使用者傳入股票代碼;提供程序返回指定股票的當(dāng)前價(jià)格,當(dāng)前的最高價(jià)格、最低價(jià)格以及交易量。
  3. 歷史報(bào)價(jià):使用者傳入股票代碼和日期;提供程序返回指定股票和日期的復(fù)雜報(bào)價(jià)。

即便對(duì)于這樣的簡(jiǎn)單示例,仍然需要確定很多問(wèn)題并將其添加到用例中,如下所示:

  • 如果股票代碼無(wú)效,或者提供程序所屬的交易所不支持該股票,該如何處理?
  • 應(yīng)該為價(jià)格使用何種格式?浮點(diǎn)數(shù)可能存在舍入誤差。小數(shù)更為準(zhǔn)確,但不標(biāo)準(zhǔn)。字符串效率較低,但更為明確。
  • 應(yīng)該為復(fù)雜報(bào)價(jià)使用何種格式?逗號(hào)分隔值?數(shù)組?對(duì)象?XML 文檔?SOAP 響應(yīng)?
  • 如果所請(qǐng)求的日期是當(dāng)日或?qū)?lái)的時(shí)間,該如何處理?如果日期是過(guò)去的某個(gè)市場(chǎng)不開(kāi)放的日期,該如何處理?對(duì)于交易所尚未開(kāi)始進(jìn)行股票交易的日期該如何處理?如果日期過(guò)早,而不存在相關(guān)記錄了,該如何處理?如果股票代碼或交易從那以后發(fā)生了變化,又該如何處理?

即使開(kāi)發(fā)本文中的簡(jiǎn)單用例也不簡(jiǎn)單。用例非常麻煩,必須考慮周全才能圓滿(mǎn)地完成開(kāi)發(fā)工作。此時(shí)的細(xì)心工作是非常不錯(cuò)的一項(xiàng)投資;利用好的服務(wù)用例可以開(kāi)發(fā)良好的服務(wù)測(cè)試和服務(wù)模擬,從而幫助開(kāi)發(fā)團(tuán)隊(duì)正常進(jìn)行開(kāi)發(fā)工作。




?
?


服務(wù)測(cè)試

此 SOA 開(kāi)發(fā)流程的第二步是開(kāi)發(fā)服務(wù)測(cè)試,以將用例系統(tǒng)編寫(xiě)為可執(zhí)行格式。僅當(dāng)服務(wù)恰當(dāng)?shù)貙?shí)現(xiàn)了用例時(shí),測(cè)試才能通過(guò)。

Kent Beck 指出,測(cè)試 應(yīng)該是自動(dòng)而獨(dú)立的,而且應(yīng)該對(duì)可能出現(xiàn)問(wèn)題的部分進(jìn)行檢查(請(qǐng)參閱參考資料部分,以獲得有關(guān)他的書(shū)籍 Extreme Programming ExplainedTest Driven Development 的信息)。測(cè)試——通過(guò)測(cè)試開(kāi)發(fā)工作軟件——是 Beck 稱(chēng)為極限編程 (XP) 的方法所包含的十二項(xiàng)實(shí)踐之一。它是測(cè)試驅(qū)動(dòng)的開(kāi)發(fā) (TDD) 的核心——如果您只能遵循一個(gè)實(shí)踐,該如何執(zhí)行 XP 呢?當(dāng)采用 XP 和 TDD 時(shí),將首先開(kāi)發(fā)測(cè)試,然后開(kāi)發(fā)軟件以通過(guò)測(cè)試,接著重復(fù)這些步驟,直到軟件足夠完善為止。

應(yīng)該測(cè)試什么?測(cè)試的概念源于許多地方,但用例是測(cè)試的最佳來(lái)源。用例文本和關(guān)系圖描述用戶(hù)對(duì)需求的理解。測(cè)試以更明確的方式表述這種理解,并以可靠和重復(fù)執(zhí)行的代碼加以表示。用例和測(cè)試是面向不同的受眾(人和計(jì)算機(jī))以不同形式表示相同內(nèi)容的對(duì)等項(xiàng)。

服務(wù)用例的服務(wù)測(cè)試 沒(méi)有什么不同,不過(guò)更多地將其看作功能測(cè)試,而不是單元測(cè)試。服務(wù)測(cè)試不會(huì)驗(yàn)證服務(wù)如何實(shí)現(xiàn);提供程序開(kāi)發(fā)團(tuán)隊(duì)可以自行實(shí)現(xiàn)此用途的單元測(cè)試。服務(wù)測(cè)試驗(yàn)證服務(wù)是否提供了服務(wù)用例認(rèn)為其應(yīng)該提供的行為。這些測(cè)試還需要對(duì)錯(cuò)誤路徑進(jìn)行測(cè)試。

測(cè)試將最終定義服務(wù)的期望接口。此接口通常為 Web 服務(wù)的 Web 服務(wù)描述語(yǔ)言(Web Services Description Language,WSDL)文件、Java 接口或 Java 組件的 EJB 遠(yuǎn)程接口等等。如果首先開(kāi)發(fā)接口,然后根據(jù)接口實(shí)現(xiàn)測(cè)試,可能會(huì)看起來(lái)更簡(jiǎn)單,不過(guò)更直接的方法是首先開(kāi)發(fā)測(cè)試,然后開(kāi)發(fā)接口,以使測(cè)試能夠成功編譯。

示例服務(wù)測(cè)試

可以使用簡(jiǎn)單的單元測(cè)試框架(JUnit 或 Cactus)來(lái)開(kāi)發(fā)測(cè)試。該框架將充當(dāng)服務(wù)的使用者,并進(jìn)行使用者將進(jìn)行的操作。下面是一些可能的測(cè)試:

  • 使用 IBM 調(diào)用 simple quote ,以驗(yàn)證獲得的結(jié)果是“$100.00”。
  • 使用 MSFT 調(diào)用 simple quote,以驗(yàn)證獲得的結(jié)果是“$30.00”。
  • 使用 BOGUS 調(diào)用 simple quote,以驗(yàn)證獲得的結(jié)果是 invalid stock symbol 錯(cuò)誤。

對(duì)復(fù)雜報(bào)價(jià)和歷史報(bào)價(jià)的測(cè)試將與此類(lèi)似。另外,還有針對(duì)可能的基礎(chǔ)結(jié)構(gòu)錯(cuò)誤的測(cè)試,如遠(yuǎn)程異常和 HTTP 400 錯(cuò)誤。最后,測(cè)試應(yīng)該對(duì)服務(wù)用例中指定的所有內(nèi)容進(jìn)行驗(yàn)證;如果在用例中指定了操作,但卻不在一個(gè)或多個(gè)測(cè)試中進(jìn)行檢查,則意味著使用者不能期望提供程序?qū)?shí)際執(zhí)行該操作。




?
?


服務(wù)模擬

此 SOA 開(kāi)發(fā)流程的第三步是開(kāi)發(fā)服務(wù)模擬——通過(guò)服務(wù)測(cè)試的模擬對(duì)象。這些服務(wù)模擬是實(shí)際服務(wù)提供程序的簡(jiǎn)單原型。

Kent Beck 將模擬對(duì)象 描述為測(cè)試對(duì)象,該對(duì)象可以使用常量進(jìn)行響應(yīng),從而實(shí)現(xiàn)開(kāi)銷(xiāo)大或復(fù)雜的資源的模仿版本。例如,模擬數(shù)據(jù)庫(kù)是一個(gè)簡(jiǎn)單對(duì)象,但具有數(shù)據(jù)庫(kù)的 API,可以接受一些已知的 SQL 字符串,并為每個(gè)字符串返回一組固定的結(jié)果。模擬對(duì)象允許您對(duì)組件進(jìn)行測(cè)試,而不必依賴(lài)于外部資源。

現(xiàn)在假定此外部資源是一個(gè) SOA 服務(wù)。如果您的組件使用該服務(wù),則測(cè)試此組件時(shí)也在測(cè)試該服務(wù)。如果服務(wù)工作不正常,或者不可用,則即使組件工作正常,測(cè)試也會(huì)失敗。如果服務(wù)很慢(通過(guò)網(wǎng)絡(luò)遠(yuǎn)程調(diào)用服務(wù)時(shí)就是這樣),您的測(cè)試也會(huì)運(yùn)行得很慢——這樣就不能如您所愿頻繁地運(yùn)行測(cè)試了。而且,如果服務(wù)尚未實(shí)現(xiàn),則根本就不能對(duì)您的組件進(jìn)行測(cè)試。

因此,一個(gè)不錯(cuò)的方法就是開(kāi)發(fā)服務(wù)模擬,模擬對(duì)象是實(shí)際服務(wù)的簡(jiǎn)單仿真程序。服務(wù)具有與實(shí)際服務(wù)相同的 API;它會(huì)實(shí)現(xiàn)針對(duì)服務(wù)測(cè)試而開(kāi)發(fā)的接口。服務(wù)模擬應(yīng)該如何工作?它應(yīng)該通過(guò)您已經(jīng)開(kāi)發(fā)的服務(wù)測(cè)試,這表明模擬真的和實(shí)際服務(wù)的工作方式一樣。

在某些情況下,服務(wù)模擬實(shí)際上比實(shí)際服務(wù)更適合用于進(jìn)行測(cè)試工作。假定您的組件使用返回股票報(bào)價(jià)的服務(wù)。如果傳入代碼 IBM,您將獲得什么樣的結(jié)果呢?$50?$100?$150?具體取決于當(dāng)前的股票價(jià)格,但這是測(cè)試的一個(gè)“雞與蛋”問(wèn)題。通過(guò)使用服務(wù)模擬,已硬編碼的模擬將始終返回 $100,然后據(jù)此進(jìn)行測(cè)試,與測(cè)試實(shí)際服務(wù)相比,這實(shí)際上更加可靠。

誰(shuí)開(kāi)發(fā)服務(wù)模擬?提供程序團(tuán)隊(duì)(而非協(xié)調(diào)程序團(tuán)隊(duì))應(yīng)該開(kāi)發(fā)服務(wù)模擬。服務(wù)模擬表示提供程序團(tuán)隊(duì)計(jì)劃實(shí)際實(shí)現(xiàn)的內(nèi)容的簡(jiǎn)單實(shí)現(xiàn)。如果相同的服務(wù)有多個(gè)提供程序團(tuán)隊(duì),則他們必須進(jìn)行協(xié)調(diào),以產(chǎn)生一個(gè)他們都認(rèn)可的模擬服務(wù)。

示例服務(wù)模擬

此示例服務(wù)模擬需要通過(guò)我前面編寫(xiě)的示例服務(wù)測(cè)試。因此,它的簡(jiǎn)單報(bào)價(jià)實(shí)現(xiàn)是一個(gè) case 語(yǔ)句。如果服務(wù)只是一個(gè)傳統(tǒng) Java 對(duì)象(plain old Java object,POJO),則對(duì)應(yīng)的模擬將為通用接口的特殊實(shí)現(xiàn),如下所示:


清單 1:作為通用接口的特殊實(shí)現(xiàn)的服務(wù)模擬
																				
																						public class StockQuoteMock implements StockQuoteService

																				
																		

簡(jiǎn)單報(bào)價(jià)則將為 StockQuoteService 中聲明的一個(gè)方法,并在 StockQuoteMock 實(shí)現(xiàn)如下方法:


清單 2:在 StockQuoteService 中聲明并在 StockQuoteMock 中實(shí)現(xiàn)的簡(jiǎn)單報(bào)價(jià)方法
																				
																						public String getSimpleQuote(String symbol) throws InvalidSymbolException {
	if (symbol == null) throw new InvalidSymbolException(symbol);
	if (symbol.equals("IBM")) return "$100.00";
	if (symbol.equals("MSFT")) return "$30.00";
	if (symbol.equals("BOGUS")) throw new InvalidSymbolException(symbol);
	throw new InvalidSymbolException(symbol);
}

																				
																		

如果服務(wù)更復(fù)雜(如無(wú)狀態(tài)會(huì)話(huà) Bean 或 SOAP Web 服務(wù)),此 POJO 代碼仍然可以作為更復(fù)雜的模擬實(shí)現(xiàn)的基礎(chǔ)。在任何情況下,模擬實(shí)現(xiàn)肯定都不應(yīng)該試圖處理每個(gè)可能的股票代碼或訪(fǎng)問(wèn)具有實(shí)時(shí)數(shù)據(jù)的數(shù)據(jù)庫(kù)。模擬實(shí)現(xiàn)應(yīng)該足以通過(guò)服務(wù)測(cè)試即可。




?
?


提供程序開(kāi)發(fā)

此 SOA 開(kāi)發(fā)流程的第四步是由提供程序開(kāi)發(fā)團(tuán)隊(duì)實(shí)現(xiàn)通過(guò)服務(wù)測(cè)試的服務(wù)。

此時(shí),提供程序團(tuán)隊(duì)已經(jīng)準(zhǔn)備好,可以進(jìn)行服務(wù)開(kāi)發(fā)了。既然他們還沒(méi)有開(kāi)始實(shí)現(xiàn)服務(wù),怎么可能進(jìn)行服務(wù)開(kāi)發(fā)呢?幸運(yùn)的是,他們已經(jīng)開(kāi)發(fā)了描述服務(wù)應(yīng)如何工作的服務(wù)用例,開(kāi)發(fā)人員就是開(kāi)發(fā)人員,他們已經(jīng)開(kāi)始考慮如何實(shí)現(xiàn)服務(wù)了。開(kāi)發(fā)人員已經(jīng)創(chuàng)建了服務(wù)測(cè)試,這些測(cè)試可說(shuō)明服務(wù)的 API 是什么,并幫助演示服務(wù)的行為。他們已經(jīng)開(kāi)發(fā)了服務(wù)模擬,這些模擬是表示實(shí)際服務(wù)將如何工作的快速原型。

因此,開(kāi)發(fā)人員已經(jīng)非常明確如何實(shí)現(xiàn)服務(wù),只是尚未實(shí)現(xiàn)其相關(guān)的任何代碼而已。

這幾乎是毫無(wú)疑問(wèn)的,但開(kāi)發(fā)人員實(shí)現(xiàn)的服務(wù)必須通過(guò)服務(wù)測(cè)試。他們?nèi)绾沃雷约阂呀?jīng)完成服務(wù)實(shí)現(xiàn)工作了呢?當(dāng)服務(wù)通過(guò)了所有測(cè)試后,服務(wù)就已完全實(shí)現(xiàn)了。在開(kāi)發(fā)期間,團(tuán)隊(duì)的開(kāi)發(fā)活動(dòng)可能會(huì)讓他們添加要測(cè)試的其他功能。訓(xùn)練有素的團(tuán)隊(duì)不會(huì)放棄這些想法,而將對(duì)其進(jìn)行捕獲并添加到服務(wù)的測(cè)試集中。服務(wù)實(shí)現(xiàn)也必須通過(guò)這些測(cè)試。提供程序團(tuán)隊(duì)還應(yīng)該向其他提供程序團(tuán)隊(duì)和協(xié)調(diào)程序團(tuán)隊(duì)通報(bào)這些添加的測(cè)試,以便所有團(tuán)隊(duì)的測(cè)試集保持同步。

理想的情況下,提供程序團(tuán)隊(duì)將可以成功地實(shí)現(xiàn)通過(guò)測(cè)試的服務(wù),而不必修改已達(dá)成一致的測(cè)試。不過(guò),這經(jīng)常被證明是不切實(shí)際的。當(dāng)開(kāi)發(fā)人員實(shí)現(xiàn)服務(wù)時(shí),他們有時(shí)會(huì)發(fā)現(xiàn)需要更改服務(wù)的接口或行為。如果服務(wù)測(cè)試的質(zhì)量良好,而開(kāi)發(fā)人員更改了服務(wù)的工作方式,則測(cè)試就不能再通過(guò)了。為了使測(cè)試仍然有效,開(kāi)發(fā)人員必須修改測(cè)試,使其可以驗(yàn)證新的設(shè)計(jì)。更改測(cè)試意味著服務(wù)模擬現(xiàn)在將不能通過(guò)測(cè)試,因此也必須對(duì)其進(jìn)行更改,以實(shí)際模擬服務(wù)現(xiàn)在的工作方式。

如果提供程序開(kāi)發(fā)人員更改了服務(wù)測(cè)試或服務(wù)模擬,他們需要盡快通知協(xié)調(diào)程序開(kāi)發(fā)人員和該服務(wù)的任何其他提供程序的開(kāi)發(fā)人員。任何使用舊測(cè)試和模擬的人員都在根據(jù)一個(gè)現(xiàn)在已經(jīng)過(guò)時(shí)的協(xié)議進(jìn)行開(kāi)發(fā),因此各個(gè)團(tuán)隊(duì)需要根據(jù)新測(cè)試和模擬進(jìn)行同步。如果其他團(tuán)隊(duì)拒絕接受新測(cè)試和模擬,則重新同步的工作就變成了團(tuán)隊(duì)之間的重新協(xié)商點(diǎn)。他們?nèi)匀挥邢M头?wù)用例達(dá)成一致,以從此處繼續(xù)開(kāi)展工作,從而開(kāi)發(fā)一組一致認(rèn)可的測(cè)試和模擬。

示例提供程序?qū)崿F(xiàn)

提供程序開(kāi)發(fā)團(tuán)隊(duì)將開(kāi)發(fā)實(shí)現(xiàn) StockQuoteService 的類(lèi)或組件,其工作方式與 StockQuoteMock 類(lèi)似,并使股票報(bào)價(jià)測(cè)試能夠通過(guò)。模擬是一個(gè)包含硬編碼響應(yīng)的簡(jiǎn)單對(duì)象,而此提供程序是提供實(shí)際行為的組件。該實(shí)現(xiàn)應(yīng)該執(zhí)行以下操作:

  • 支持所有有效股票代碼(至少支持提供程序的股票交易中涉及到的所有股票)。
  • 確保使用包含所支持股票的實(shí)時(shí)價(jià)格的數(shù)據(jù)庫(kù)。
  • 將數(shù)據(jù)庫(kù)使用的價(jià)格格式轉(zhuǎn)換為服務(wù)返回的格式。
  • 將數(shù)據(jù)庫(kù)針對(duì)無(wú)效代碼的輸入結(jié)果(如空查詢(xún)結(jié)果)轉(zhuǎn)換為服務(wù)希望的錯(cuò)誤。
  • 實(shí)現(xiàn)服務(wù)的協(xié)議,如 EJB 遠(yuǎn)程接口、HTTP Web 服務(wù)或 JMS 請(qǐng)求和答復(fù)消息。

由于模擬和實(shí)際提供程序?qū)崿F(xiàn)相同的接口——在此例中為 Java 接口 StockQuoteService,因此服務(wù)測(cè)試可以使用兩個(gè)實(shí)現(xiàn)中的任何一個(gè);只要使用要實(shí)例化的正確類(lèi)對(duì)測(cè)試進(jìn)行配置即可。為了運(yùn)行測(cè)試,您還需要使用測(cè)試期望的股票價(jià)格對(duì)數(shù)據(jù)庫(kù)進(jìn)行配置。




?
?


協(xié)調(diào)程序開(kāi)發(fā)

此 SOA 開(kāi)發(fā)流程的第五步是由協(xié)調(diào)程序開(kāi)發(fā)團(tuán)隊(duì)實(shí)現(xiàn)使用服務(wù)的應(yīng)用程序。在實(shí)際服務(wù)實(shí)現(xiàn)就緒之前,應(yīng)用程序都將使用服務(wù)模擬。

此時(shí),由于具有大量的服務(wù)模擬,因此協(xié)調(diào)程序團(tuán)隊(duì)可以繼續(xù)進(jìn)行其相關(guān)工作,就像已經(jīng)實(shí)現(xiàn)并提供了服務(wù)提供程序一樣。而且,協(xié)調(diào)程序團(tuán)隊(duì)不僅具有一組可以使用的服務(wù)(也就是模擬),而且也有了可以演示服務(wù)如何工作的和客戶(hù)機(jī)如何使用服務(wù)的一組測(cè)試。該團(tuán)隊(duì)可以將這些測(cè)試作為可以如何實(shí)現(xiàn)其協(xié)調(diào)程序的簡(jiǎn)單原型使用。和提供程序團(tuán)隊(duì)一樣,盡管尚未實(shí)現(xiàn)任何代碼,但協(xié)調(diào)程序開(kāi)發(fā)團(tuán)隊(duì)已經(jīng)早就在進(jìn)行協(xié)調(diào)程序的工作了。

理想情況下,協(xié)調(diào)程序團(tuán)隊(duì)將可以使用達(dá)成一致的服務(wù)模擬來(lái)成功地實(shí)現(xiàn)他們的協(xié)調(diào)程序。不過(guò)有時(shí)候這樣做有些困難。模擬并不提供某些需要的行為或希望的接口。協(xié)調(diào)程序客戶(hù)還需要比模擬提供的服務(wù)更細(xì)粒度的服務(wù)。如果服務(wù)協(xié)調(diào)程序需要其他功能,則可以嘗試自行實(shí)現(xiàn)此功能。如果協(xié)調(diào)程序需要不同的接口,則可以嘗試實(shí)現(xiàn)一個(gè)適配器,來(lái)將其所希望的接口轉(zhuǎn)換為模擬實(shí)現(xiàn)的接口。如果協(xié)調(diào)程序希望更細(xì)粒度的功能,則該團(tuán)隊(duì)需要對(duì)模擬及其測(cè)試進(jìn)行修改。

這些更改會(huì)使得有必要重新與提供程序團(tuán)隊(duì)進(jìn)行同步。讓我們假定協(xié)調(diào)程序團(tuán)隊(duì)實(shí)現(xiàn)了額外的功能或不同的接口來(lái)提高服務(wù)的可用性。如果添加的行為不是特定于協(xié)調(diào)程序,而是會(huì)涉及到服務(wù),則添加的行為可以潛在地由其他服務(wù)使用者重用。因此應(yīng)將其內(nèi)置到提供程序中。提供程序所需的更改可以也應(yīng)該建模為對(duì)模擬及其測(cè)試的更改。當(dāng)協(xié)調(diào)程序團(tuán)隊(duì)必須修改模擬及其測(cè)試時(shí)——既可能是為了增強(qiáng)其他功能也可能是為了對(duì)功能進(jìn)行進(jìn)一步細(xì)化——必須將這些更改應(yīng)用到提供程序和其他所有的工作內(nèi)容。已更改的模擬和測(cè)試成為協(xié)調(diào)程序團(tuán)隊(duì)、提供程序團(tuán)隊(duì)以及其他協(xié)調(diào)程序提供團(tuán)隊(duì)之間的重新協(xié)商點(diǎn)。他們必須針對(duì)達(dá)成一致的一組新模擬和測(cè)試重新進(jìn)行同步。

示例協(xié)調(diào)程序?qū)崿F(xiàn)

協(xié)調(diào)程序開(kāi)發(fā)團(tuán)隊(duì)將實(shí)現(xiàn)一個(gè)委托給 StockQuoteService 的實(shí)現(xiàn)的客戶(hù)端組件。它的行為將與服務(wù)測(cè)試相似,不同的是,它將使用服務(wù)類(lèi)為 GUI 或客戶(hù)端應(yīng)用程序提供真正的功能。協(xié)調(diào)程序?qū)崿F(xiàn)只能使用 StockQuoteService 中經(jīng)服務(wù)測(cè)試證明可用的功能。Java 編譯器將確保協(xié)調(diào)程序代碼只能調(diào)用服務(wù)接口聲明的方法;保持協(xié)調(diào)程序?qū)崿F(xiàn)與測(cè)試實(shí)現(xiàn)的一致可以確保服務(wù)按預(yù)期的要求工作。




?
?


將流程組合起來(lái)

那么,該流程在實(shí)踐中是如何工作的呢?

第一步,開(kāi)發(fā)服務(wù)用例。服務(wù)用例團(tuán)隊(duì)可以包括來(lái)自提供程序團(tuán)隊(duì)和協(xié)調(diào)程序團(tuán)隊(duì)的代表。或者,這個(gè)團(tuán)隊(duì)可以?xún)H由那些專(zhuān)門(mén)進(jìn)行需求收集和用例開(kāi)發(fā)的分析人員組成。傳統(tǒng)用例開(kāi)發(fā)主要關(guān)注人們?nèi)绾问褂脩?yīng)用程序,而這個(gè)團(tuán)隊(duì)必須將重點(diǎn)放在組件如何集成上。他們不應(yīng)關(guān)心提供程序?qū)⑷绾螌?shí)現(xiàn),也不用考慮協(xié)調(diào)程序可以如何實(shí)現(xiàn)。相反,他們應(yīng)將重點(diǎn)放在服務(wù)是什么、它們完成什么工作以及如何對(duì)其進(jìn)行調(diào)用上。

第二步,將服務(wù)用例編寫(xiě)為服務(wù)測(cè)試。用例是人可讀的,而服務(wù)測(cè)試表示相同的需求,但采用的卻是計(jì)算機(jī)可執(zhí)行的方式。這些測(cè)試必須由開(kāi)發(fā)人員實(shí)現(xiàn),而不是由開(kāi)發(fā)用例的分析人員實(shí)現(xiàn)。測(cè)試開(kāi)發(fā)人員可以是提供程序團(tuán)隊(duì)和協(xié)調(diào)程序團(tuán)隊(duì)的成員,也可以是可用且有能力實(shí)現(xiàn)測(cè)試的人員。在最終確定測(cè)試之前,每個(gè)團(tuán)隊(duì)的代表都必須對(duì)其進(jìn)行認(rèn)可,從而表示所有團(tuán)隊(duì)已就其達(dá)成了一致,而不考慮誰(shuí)開(kāi)發(fā)了哪個(gè)測(cè)試。

第三步,開(kāi)發(fā)通過(guò)測(cè)試的服務(wù)模擬。開(kāi)發(fā)測(cè)試的團(tuán)體通常也實(shí)現(xiàn)模擬。模擬證明測(cè)試可以通過(guò),作為原型供提供程序團(tuán)隊(duì)使用,并支持協(xié)調(diào)程序團(tuán)隊(duì)繼續(xù)進(jìn)行開(kāi)發(fā)。與測(cè)試一樣,除非所有團(tuán)隊(duì)都認(rèn)可模擬并表示同意,否則就不能認(rèn)為已最終確定了模擬。換句話(huà)說(shuō),任何團(tuán)隊(duì)都不能強(qiáng)制別的團(tuán)隊(duì)接受一組測(cè)試和模擬,大家必須一致認(rèn)可,否則遲早會(huì)出現(xiàn)混亂。

第四步,提供程序團(tuán)隊(duì)部署提供程序,這些提供程序的行為與模擬相似,且均已通過(guò)了測(cè)試。如果將這些提供程序添加到測(cè)試和模擬,尤其是在更改了測(cè)試和模擬的情況下,則他們必須分發(fā)這些更改,以便其他團(tuán)隊(duì)重新進(jìn)行同步。他們不能強(qiáng)制讓其他團(tuán)隊(duì)接受這些修改;所有團(tuán)隊(duì)必須就此達(dá)成一致。

第五步,協(xié)調(diào)程序團(tuán)隊(duì)必須使用模擬開(kāi)發(fā)可以正常工作的協(xié)調(diào)程序。如果需要更改模擬,他們還需要對(duì)測(cè)試進(jìn)行更新。他們需要隨后將其更改分發(fā)給其他組,所有的團(tuán)隊(duì)必須找到一個(gè)大家都認(rèn)可的點(diǎn)——一組共同的測(cè)試和模擬,并據(jù)此重新進(jìn)行同步。

這些步驟一起的確可以形成一個(gè)簡(jiǎn)單的開(kāi)發(fā)流程。




?
?


解決 SOA 問(wèn)題

那么,這個(gè)流程是否解決了我在本文開(kāi)始時(shí)提出的問(wèn)題?

1. 如果某些提供程序尚未開(kāi)發(fā),則協(xié)調(diào)程序團(tuán)隊(duì)如何開(kāi)發(fā)其負(fù)責(zé)的應(yīng)用程序部分?

模擬解決了此問(wèn)題。模擬可以快速地進(jìn)行開(kāi)發(fā)。雖然實(shí)際提供程序的開(kāi)發(fā)需要更長(zhǎng)的時(shí)間,但協(xié)調(diào)程序團(tuán)隊(duì)可以使用模擬同步開(kāi)發(fā)協(xié)調(diào)程序。只要滿(mǎn)足了以下條件,此工作就可以順利地進(jìn)行:

  1. 模擬的功能全面,即意味著其編寫(xiě)的測(cè)試和用例也全面。
  2. 沒(méi)有團(tuán)隊(duì)必須更改模擬。只要某個(gè)團(tuán)隊(duì)必須對(duì)模擬進(jìn)行更改,他們就應(yīng)該在進(jìn)一步脫離同步之前盡可能快地重新進(jìn)行同步。

2. 協(xié)調(diào)程序團(tuán)隊(duì)和提供程序團(tuán)隊(duì)如何較早而可靠地就服務(wù)如何工作達(dá)成一致?

因?yàn)闇y(cè)試和模擬可以快速進(jìn)行開(kāi)發(fā),而且它們是真正可以運(yùn)行的實(shí)際代碼,所以提供了早期驗(yàn)證,從而可以確保用例有意義,并且團(tuán)隊(duì)真的達(dá)成了一致。有了經(jīng)驗(yàn)后,可以在前期投入更多的精力,以確保測(cè)試和模擬的全面性,這些構(gòu)件需要更改的幾率越小,剩下的開(kāi)發(fā)過(guò)程中需要重新進(jìn)行同步的幾率也就越小。

3. 實(shí)現(xiàn)相同服務(wù)的多個(gè)提供程序團(tuán)隊(duì)如何能確保他們的實(shí)現(xiàn)是兼容的?

一組公共測(cè)試以及通過(guò)這些測(cè)試的模擬可以作為公共參考框架使用,以確保獨(dú)立的提供程序?qū)崿F(xiàn)始終兼容且可互換。早期的測(cè)試越前面,需要更改的幾率就越小,從而團(tuán)隊(duì)需要重新同步的情況也就越少。

這樣一來(lái),該流程就解決了多個(gè)團(tuán)隊(duì)實(shí)現(xiàn) SOA 的不同部分時(shí)所面臨的主要問(wèn)題。




?
?


結(jié)束語(yǔ)

本文討論了以下內(nèi)容:

  • 在嘗試使用 SOA 開(kāi)發(fā)應(yīng)用程序時(shí),并行的獨(dú)立團(tuán)隊(duì)可能遇到的常見(jiàn)開(kāi)發(fā)問(wèn)題。
  • 一個(gè)簡(jiǎn)單的五步開(kāi)發(fā)流程,該流程通過(guò)使用服務(wù)用例、服務(wù)測(cè)試和服務(wù)模擬解決了這些問(wèn)題。

您可以將此流程應(yīng)用到您的組織中,從而大幅度提高使用 SOA 進(jìn)行開(kāi)發(fā)的成功幾率。

?

posted on 2006-06-19 18:54 wsdfsdf 閱讀(310) 評(píng)論(0)  編輯 收藏 引用 所屬分類(lèi): 技術(shù)文章

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美精品久久一区二区| 久久全球大尺度高清视频| 欧美日韩精品一区二区| 欧美一二三视频| 欧美mv日韩mv国产网站app| 午夜国产精品视频免费体验区| 亚洲精品一区二区三区婷婷月| 在线观看欧美| 欧美精品18+| 老司机成人在线视频| 久久精品一区蜜桃臀影院| 亚洲国产精品一区二区www在线| 91久久精品久久国产性色也91| 激情偷拍久久| 国产一区导航| 国内久久婷婷综合| 国产永久精品大片wwwapp| 国产综合欧美| 在线观看国产日韩| 亚洲精品日产精品乱码不卡| 99精品国产在热久久婷婷| 1024国产精品| 亚洲欧洲精品一区| 一区二区三区欧美成人| 亚洲在线观看视频| 午夜在线精品偷拍| 久久久久久亚洲精品杨幂换脸 | 亚洲靠逼com| 亚洲精品之草原avav久久| 亚洲在线中文字幕| 欧美一区二区精品| 一区二区激情视频| 午夜精彩视频在线观看不卡| 久久久久九九九九| 欧美成人午夜激情视频| 亚洲国产精品一区二区尤物区 | 久久久精品999| 欧美成年人在线观看| 亚洲激情一区二区| 亚洲午夜电影网| 久久久精品国产99久久精品芒果| 美女久久网站| 欧美婷婷久久| 在线精品福利| 亚洲欧美日韩直播| 欧美成人一区二区三区在线观看| 欧美成人精品一区| 久久久久欧美| av不卡在线| 久久久女女女女999久久| 欧美日韩精品福利| 在线成人小视频| 午夜激情综合网| 美日韩在线观看| 中国av一区| 欧美成人一区二区三区| 国产欧美精品国产国产专区| 亚洲美女av在线播放| 久久亚洲电影| 亚洲制服少妇| 欧美日韩亚洲视频一区| 亚洲电影下载| 中日韩在线视频| 欧美成人午夜| 亚洲日韩欧美视频一区| 99视频在线精品国自产拍免费观看| 亚洲一区二区在| 欧美成人国产一区二区| 精品999在线播放| 性色av一区二区三区| av成人激情| 免费91麻豆精品国产自产在线观看| 欧美激情一区二区三区四区| 欧美激情综合| 亚洲高清视频的网址| 久久久久国色av免费观看性色| 一区二区三区久久久| 欧美精品在线观看| 91久久久亚洲精品| 亚洲大胆人体视频| 黄色成人在线网站| 亚洲亚洲精品三区日韩精品在线视频 | 欧美高清免费| 亚洲一区二区三区精品在线| 欧美精品在线免费播放| 亚洲一区二区三区精品动漫| 亚洲欧洲久久| 午夜亚洲福利在线老司机| 国产精品久久婷婷六月丁香| 亚洲一二三区视频在线观看| 亚洲一区二区少妇| 国产精品国产三级国产a| 欧美伊人久久久久久午夜久久久久| 在线一区二区日韩| 欧美电影电视剧在线观看| 亚洲免费福利视频| av成人免费在线| 国产一区亚洲一区| 欧美国产综合| 国产精品嫩草影院一区二区| 久久久五月天| 欧美成人一区二区在线| 欧美一区二区在线| 久久九九全国免费精品观看| 亚洲系列中文字幕| 亚洲欧美中文日韩v在线观看| 亚洲国产va精品久久久不卡综合| 亚洲欧洲综合另类| 国产精品美女久久久免费| 免费在线欧美黄色| 欧美天堂亚洲电影院在线播放| 久久久久久黄| 欧美精品亚洲二区| 欧美在线一区二区| 欧美日韩国产成人在线免费| 久久av一区二区三区漫画| 欧美激情成人在线视频| 欧美一区二区三区在线免费观看| 一区二区三区欧美日韩| 亚洲精品激情| 午夜精品福利一区二区三区av| aa级大片欧美三级| 久久本道综合色狠狠五月| 亚洲免费在线电影| 欧美成人黑人xx视频免费观看| 一本大道av伊人久久综合| 免费高清在线视频一区·| 欧美一区二区视频在线观看| 欧美视频一区在线观看| 欧美激情在线有限公司| 久久国产日本精品| 亚洲天堂免费在线观看视频| 久久久亚洲国产天美传媒修理工 | 久久综合一区| 国产精品久久国产愉拍| 久久av免费一区| 国产精品天天看| 亚洲精品欧美日韩| 亚洲最新视频在线| 国产精品电影观看| 亚洲激情黄色| 在线精品亚洲| 午夜免费日韩视频| 欧美亚洲一级片| 欧美四级在线观看| 亚洲精品一区二区网址 | 一区二区三区日韩欧美精品| 最近中文字幕日韩精品| 久久精品中文| 久久久国产亚洲精品| 国产精品视频免费在线观看| 亚洲精品一区在线观看| 亚洲国产一区在线观看| 久久人91精品久久久久久不卡| 欧美一区二区视频网站| 国产精品日本欧美一区二区三区| 亚洲美女黄色片| 亚洲每日更新| 欧美成人在线免费观看| 欧美成人按摩| 亚洲国产一二三| 香蕉成人啪国产精品视频综合网| 欧美亚洲一区二区三区| 国产女精品视频网站免费| 亚洲综合精品| 久久精品91| 国产一区二区三区自拍| 欧美一区二区在线播放| 久久综合99re88久久爱| 在线观看欧美| 欧美插天视频在线播放| 亚洲精品四区| 亚洲一区二区三区四区视频| 国产精品日韩欧美一区| 欧美一区91| 欧美大片在线观看| 99视频精品全部免费在线| 欧美亚洲第一区| 欧美在线看片a免费观看| 欧美成人自拍视频| 亚洲视频在线观看一区| 国产精品一区免费观看| 久久九九国产精品| 亚洲激情视频在线观看| 亚洲欧美春色| 一区二区亚洲精品| 欧美成人一二三| 亚洲一区免费网站| 乱码第一页成人| 亚洲一区二区三区中文字幕| 国产资源精品在线观看| 欧美精品高清视频| 性欧美8khd高清极品| 亚洲第一黄网| 午夜精品美女自拍福到在线 | 亚洲第一中文字幕在线观看| 亚洲国产成人tv| 欧美日韩在线免费| 久久久精彩视频| 日韩视频在线观看|