日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

「领域驱动设计」DDD,六边形架构,洋葱架构,整洁架构,CQRS的整合架构

發布時間:2024/1/8 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 「领域驱动设计」DDD,六边形架构,洋葱架构,整洁架构,CQRS的整合架构 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

這篇文章是軟件架構編年史的一部分,一系列關于軟件架構的文章。在這些文章中,我寫了我對軟件架構的了解,我如何看待它,以及我如何使用這些知識。如果您閱讀了本系列以前的文章,那么本文的內容可能更有意義。

大學畢業后,我從事了高中教師的職業,直到幾年前,我決定放棄它,成為一名全職軟件開發人員。

從那以后,我總是覺得我需要找回失去的時間,盡可能多地、盡可能快地學習。因此,我有點沉迷于試驗、閱讀和寫作,特別關注軟件設計和體系結構。這就是我寫這些帖子的原因,來幫助我學習。

在我的上一篇文章中,我寫了很多我學過的概念和原則,以及我是如何推理的。但我認為這些只是拼圖的一部分。

今天的帖子是關于我如何將所有這些部分組合在一起的,我似乎應該給它起個名字,我稱它為顯式架構(Explicit Architecture)。此外,這些概念都“通過了它們的考驗”,并被用于高要求平臺上的生產代碼中。一個是SaaS的e-com平臺,在全球擁有數千個網絡商店,另一個是市場,在兩個國家都有一個消息總線,每個月處理超過2000萬條消息。

  • 系統的基本模塊

  • 工具

  • 將工具和交付機制連接到應用程序核心

    • 端口

    • 主適配器或驅動適配器

    • 輔助或被驅動適配器

    • 控制反轉

  • 應用程序的核心組織

    • 域服務

    • 域模型

    • 應用程序層

    • 領域層

  • 組件

    • 組件之間共享的數據存儲

    • 每個組件隔離數據存儲

    • 解耦的組件

    • 觸發邏輯在其他組件

    • 從其他組件獲取數據

  • 控制流

系統的基本模塊

我首先回顧一下EBI和端口及適配器架構。它們都明確區分了哪些代碼是應用程序內部的,哪些是外部的,以及哪些用于連接內部和外部代碼。

此外,端口和適配器體系結構明確標識了系統中的三個基本代碼塊:

  • 是什么使得運行一個用戶界面成為可能,不管它是什么類型的用戶界面;

  • 系統業務邏輯,或應用程序核心,由用戶界面使用,以實際使事情發生;

  • 基礎構架代碼,它將我們的應用核心與數據庫、搜索引擎或第三方api等工具連接起來。

應用程序核心是我們真正應該關心的。是代碼允許我們的代碼做它應該做的事情,是我們的應用程序。它可能使用多個用戶界面(漸進式web應用程序、移動應用程序、CLI、API等),但是實際執行工作的代碼是相同的,并且位于應用程序內核中,不管什么UI觸發它,都應該是一樣的。

可以想象,典型的應用程序流從用戶界面中的代碼開始,通過應用程序核心到基礎設施代碼,然后返回到應用程序核心,最后向用戶界面交付響應。

工具

遠離系統中最重要的代碼(應用程序核心),我們擁有應用程序使用的工具,例如數據庫引擎、搜索引擎、Web服務器或CLI控制臺(盡管后兩個也是交付機制)。

雖然將CLI控制臺與數據庫引擎放在同一個“bucket”中可能感覺有些奇怪,盡管它們有不同類型的用途,但它們實際上是應用程序使用的工具。關鍵的區別在于,雖然CLI控制臺和web服務器用于告訴應用程序執行某些操作,但是數據庫引擎是由應用程序執行某些操作的。這是一個非常相關的區別,因為它對我們如何構建將這些工具與應用程序核心連接起來的代碼有很強的影響。

將工具和傳送機制連接到應用程序核心

將工具連接到應用程序核心的代碼單元稱為適配器(端口和適配器體系結構)。適配器是那些有效地實現代碼的適配器,這些代碼將允許業務邏輯與特定的工具通信,反之亦然。

告訴我們的應用程序做某事的適配器稱為主適配器或驅動適配器,而由我們的應用程序告訴我們做某事的適配器稱為輔助適配器或驅動適配器。

端口

然而,這些適配器不是隨機創建的。創建它們是為了將特定的入口點安裝到應用程序核心(一個端口)。端口只不過是工具如何使用應用程序內核或應用程序內核如何使用它的規范。在大多數語言及其最簡單的形式中,這個規范,即端口,將是一個接口,但它實際上可能由幾個接口和dto組成。

需要注意的是,端口(接口)屬于業務邏輯內部,而適配器屬于業務邏輯外部。要使此模式正常工作,最重要的是創建適合應用程序核心需求的端口,而不是簡單地模仿工具api。

主適配器或驅動適配器

主適配器或驅動適配器圍繞一個端口,并使用它來告訴應用程序核心要做什么。它們將來自交付機制的任何東西轉換為應用程序核心中的方法調用。

換句話說,我們的驅動適配器是控制器或控制臺命令,它們在構造函數中注入一些對象,這些對象的類實現控制器或控制臺命令所需的接口(端口)。

在更具體的示例中,端口可以是控制器所需的服務接口或存儲庫接口。然后將服務、存儲庫或查詢的具體實現注入并在控制器中使用。

或者,端口可以是命令總線或查詢總線接口。在這種情況下,將命令或查詢總線的具體實現注入控制器,然后控制器構造命令或查詢并將其傳遞給相關總線。

輔助或被驅動適配器

與圍繞端口的被驅動適配器不同,驅動適配器實現一個端口和一個接口,然后將其注入到應用程序核心中,無論哪里需要端口(類型暗示)。

例如,假設我們有一個需要持久化數據的簡單應用程序。所以我們創建一個持久性接口,滿足其需要,用一個方法來保存數組的數據和方法來刪除表中的一行的ID。從那時起,無論應用程序需要保存或刪除數據,我們需要在其構造函數實現持久化的對象我們定義的接口。

現在我們創建一個特定于MySQL的適配器來實現這個接口。它將具有保存數組和刪除表中的一行的方法,并且我們將在需要持久性接口的地方注入它。

如果在某個時候我們決定改變數據庫供應商,比如PostgreSQL或MongoDB,我們只需要創建一個新的適配器來實現PostgreSQL特定的持久化接口,并注入新的適配器而不是舊的。

控制反轉

關于此模式需要注意的一個特征是,適配器依賴于特定的工具和特定的端口(通過實現接口)。但是我們的業務邏輯只依賴于端口(接口),它被設計成適合業務邏輯需求,所以它不依賴于特定的適配器或工具。

這意味著依賴的方向是朝向中心的,這是建筑層面的控制原則的倒置。

盡管如此,創建端口是為了滿足應用程序的核心需求,而不是簡單地模仿工具api,這一點非常重要。

應用程序的核心組織

Onion架構采用DDD層,并將它們合并到端口和適配器架構中。這些層旨在為業務邏輯、端口和適配器的內部“六邊形”帶來一些組織,就像端口和適配器一樣,依賴關系的方向是向中心的。

應用程序層

用例是可以由應用程序中的一個或多個用戶接口在應用程序核心中觸發的流程。例如,在CMS中,我們可以有普通用戶使用的實際應用程序UI、CMS管理員使用的另一個獨立UI、另一個CLI UI和web API。這些ui(應用程序)可以觸發特定于其中一個或由其中幾個重用的用例。

用例在應用層中定義,這是DDD提供的第一層,由Onion Architecture使用。

這一層包含作為第一類公民的應用程序服務(及其接口),但它也包含端口和適配器接口(端口),其中包括ORM接口、搜索引擎接口、消息傳遞接口等等。在我們使用命令總線和/或查詢總線的情況下,這一層是命令和查詢各自的處理程序所在的地方。

應用程序服務和/或命令處理程序包含展開用例(業務流程)的邏輯。一般來說,他們的職責是:

  • 使用存儲庫查找一個或多個實體;

  • 告訴那些實體去做一些域邏輯;

  • 并使用存儲庫再次持久化實體,有效地保存數據更改。

命令處理程序可以用兩種不同的方式使用:

  • 它們可以包含執行用例的實際邏輯;

  • 它們可以在我們的體系結構中用作簡單的連接塊,接收命令并簡單地觸發存在于應用程序服務中的邏輯。

使用哪種方法取決于上下文,例如:

我們是否已經準備好了應用程序服務并正在添加命令總線?

命令總線是否允許指定任何類/方法作為處理程序,或者它們是否需要擴展或實現現有的類或接口?

這一層還包含應用程序事件的觸發,這些事件表示用例的一些結果。這些事件觸發的邏輯是用例的副作用,比如發送電子郵件、通知第三方API、發送推送通知,甚至啟動屬于應用程序不同組件的另一個用例。

領域層

再往里,我們有域層。這個層中的對象包含數據和操作數據的邏輯,這是特定于域本身的,它獨立于觸發邏輯的業務流程,它們是獨立的,完全不知道應用層。

域服務

如前所述,應用服務的作用是:

  • 使用存儲庫查找一個或多個實體;

  • 告訴那些實體去做一些域邏輯;

  • 并使用存儲庫再次持久化實體,有效地保存數據更改。

然而,有時我們會遇到一些涉及不同實體的域邏輯,不管它們是否屬于同一類型,我們覺得域邏輯不屬于實體本身,我們覺得那個邏輯不是它們的直接責任。

因此,我們的第一反應可能是將邏輯放在實體之外的應用程序服務中。然而,這意味著該域邏輯將不能在其他用例中重用:域邏輯應該遠離應用程序層!

解決方案是創建一個域服務,它的角色是接收一組實體并在其上執行一些業務邏輯。域服務屬于域層,因此它對應用層中的類一無所知,比如應用程序服務或存儲庫。另一方面,它可以使用其他域服務,當然還有域模型對象。

域模型

在最中心的是域模型,它不依賴于它之外的任何東西,它包含表示域內某些內容的業務對象。這些對象的示例首先是實體,但也包括值對象、枚舉和域模型中使用的任何對象。

域模型也是域事件“活動”的地方。當特定的一組數據發生更改時,將觸發這些事件,并將這些更改隨身攜帶。換句話說,當一個實體發生更改時,將觸發一個域事件,它將攜帶更改后的屬性新值。例如,這些事件非常適合用于事件源。

組件

到目前為止,我們一直在基于層隔離代碼,但這是細粒度的代碼隔離。粗粒度的代碼隔離至少是同樣重要的,它是根據子域和有界上下文來隔離代碼的,遵循Robert C. Martin在尖叫聲架構中表達的思想。這通常被稱為“按功能包”或“按組件包”,而不是“按層包”,Simon Brown在他的博客“按組件包和體系結構對齊測試”中對此做了很好的解釋:

我是“按組件打包”方法的倡導者,并且根據Simon Brown關于按組件打包的圖表,我將無恥地將其更改為以下內容:

這些代碼部分與前面描述的層是交叉的,它們是我們的應用程序的組件。組件的示例可以是身份驗證、授權、計費、用戶、審查或帳戶,但它們始終與域相關。像授權和/或身份驗證這樣的有界上下文應該被視為外部工具,我們為其創建適配器并隱藏在某種端口之后。

解耦的組件

就像細粒度的代碼單元(類、接口、特征、混合等)一樣,粗粒度的代碼單元(組件)也受益于低耦合和高內聚。

為了解耦類,我們使用依賴注入,將依賴注入到類中而不是在類中實例化,依賴倒置,使類依賴于抽象(接口和/或抽象類)而不是具體類。這意味著子類不知道它將要使用的具體類,它沒有引用它所依賴的類的完全限定類名。

同樣,完全解耦的組件意味著一個組件不直接知道任何其他組件。換句話說,它沒有引用來自另一個組件的任何細粒度代碼單元,甚至沒有接口!這意味著依賴注入和依賴倒置不足以解耦組件,我們需要某種架構結構。我們可能需要事件、共享內核、最終一致性,甚至發現服務!

在其他組件觸發邏輯

當我們的一個組件(組件B)需要在另一個組件(組件A)中發生其他事情時執行某個操作時,我們不能簡單地從組件A直接調用組件B中的類/方法,因為這樣A就會被耦合到B。

然而,我們可以使用事件分派器來分派一個應用程序事件,該應用程序事件將被交付給監聽它的任何組件,包括B,而B中的事件偵聽器將觸發所需的操作。這意味著組件A將依賴于事件分配器,但它將與B解耦。

然而,如果事件本身“存在”于A中,這意味著B知道A的存在,它與A是耦合的。這意味著組件都依賴于共享內核,但是它們之間是解耦的。共享內核將包含應用程序和域事件之類的功能,但它也可以包含規范對象,以及任何需要共享的內容,請記住,共享內核的任何更改都將影響到應用程序的所有組件,因此共享內核應該盡可能少。此外,如果我們有一個多語言系統,假設是一個微服務生態系統,其中它們是用不同的語言編寫的,那么共享內核需要是語言無關的,以便所有組件都可以理解它,無論它們是用什么語言編寫的。例如,它將包含事件描述,而不是包含事件類的共享內核。名稱、屬性、甚至方法(盡管這些在JSON之類的不可知語言中可能更有用),這樣所有組件/微服務都可以解釋它,甚至自動生成它們自己的具體實現。請在我的后續文章中相關內容:不僅僅是同心圓層。

這種方法既適用于單片應用程序,也適用于像微服務生態系統這樣的分布式應用程序。然而,當事件只能異步交付時,對于需要立即在其他組件中執行觸發邏輯的上下文,這種方法是不夠的!組件將需要一個直接的HTTP調用組件b。在這種情況下,解耦的組件,我們需要發現服務,將要求它應該發送請求來啟動所需的行動,或者使請求發現服務代理的相關服務,最終將響應返回給請求者。此方法將把組件耦合到發現服務,但將使它們彼此解耦。

從其他組件獲取數據

在我看來,一個組件不允許改變它不“擁有”的數據,但是它可以查詢和使用任何數據。

組件之間共享的數據存儲

當一個組件需要使用屬于另一個組件的數據時,假設一個賬單組件需要使用屬于accounts組件的客戶端名稱,賬單組件將包含一個查詢對象,該對象將查詢該數據的數據存儲。這僅僅意味著賬單組件可以知道任何數據集,但是它必須通過查詢的方式將不“擁有”的數據作為只讀數據使用。

每個組件隔離數據存儲

在本例中,應用了相同的模式,但是我們在數據存儲級別上更加復雜。組件擁有自己的數據存儲意味著每個數據存儲包含:

  • 它擁有的一組數據,并且是唯一允許更改的數據,使其成為唯一的真理來源;

  • 一組數據是其他組件數據的副本,它不能自己更改這些數據,但是組件功能需要它,并且需要在所有者組件中發生更改時對其進行更新。

每個組件將從其他組件創建所需數據的本地副本,以便在需要時使用。當擁有該組件的組件中的數據發生更改時,該所有者組件將觸發承載數據更改的域事件。持有該數據副本的組件將偵聽該域事件,并相應地更新其本地副本。

控制流

正如我上面所說的,控制流當然是從用戶到應用程序核心,再到基礎設施工具,最后回到應用程序核心,最后回到用戶。但是類到底是如何組合在一起的呢?哪些取決于哪些?我們如何組合它們?

在Bob叔叔關于干凈架構的文章中,我將嘗試用UMLish圖來解釋控制流……

沒有命令/查詢總線

在我們不使用命令總線的情況下,控制器將依賴于應用程序服務或查詢對象。

[編輯- 2017-11-18]我完全錯過了我用來從查詢返回數據的DTO,所以我現在添加了它。感謝MorphineAdministered公司為我指出了這一點。

在上面的圖中我們使用應用程序的接口服務,盡管我們可能認為這不是真正需要從應用程序服務是我們應用程序代碼的一部分,我們不會想交換另一個實現,盡管我們可能完全重構它。

查詢對象將包含一個優化的查詢,該查詢將簡單地返回一些原始數據以顯示給用戶。該數據將以DTO的形式返回,并注入到ViewModel中。這個視圖模型可能有一些視圖邏輯,它將被用來填充一個視圖。

另一方面,應用程序服務將包含用例邏輯,當我們希望在系統中執行某些操作時,而不是簡單地查看某些數據時,將觸發該邏輯。應用程序服務依賴于存儲庫,存儲庫將返回包含需要觸發的邏輯的實體。它還可能依賴于域服務來協調多個實體中的域流程,但情況并非如此。

在展開用例之后,應用程序服務可能希望通知整個系統該用例已經發生,在這種情況下,它還將依賴于事件分派器來觸發事件。

值得注意的是,我們在持久性引擎和存儲庫上都放置了接口。雖然看起來有些多余,但它們有不同的用途:

  • 持久性接口是ORM上的一個抽象層,因此我們可以交換正在使用的ORM,而不需要更改應用程序的核心。

  • repository接口是對持久性引擎本身的抽象。假設我們想從MySQL切換到MongoDB。持久性接口可以是相同的,如果我們想繼續使用相同的ORM,那么即使是持久性適配器也可以保持不變。但是,查詢語言是完全不同的,所以我們可以創建使用相同持久性機制的新存儲庫,實現相同的存儲庫接口,但是使用MongoDB查詢語言而不是SQL構建查詢。

使用命令/查詢總線

在我們的應用程序使用命令/查詢總線的情況下,除了控制器現在依賴于總線和命令或查詢外,關系圖幾乎保持不變。它將實例化命令或查詢,并將其傳遞給總線,總線將找到適當的處理程序來接收和處理命令。

在下面的關系圖中,命令處理程序然后使用應用程序服務。然而,這并不總是需要的,事實上在大多數情況下,處理程序將包含用例的所有邏輯。如果需要在另一個處理程序中重用相同的邏輯,則只需要將邏輯從處理程序提取到單獨的應用程序服務中。

[編輯- 2017-11-18]我完全錯過了我用來從查詢返回數據的DTO,所以我現在添加了它。感謝MorphineAdministered公司為我指出了這一點。

您可能已經注意到,總線與命令、查詢和處理程序之間沒有依賴關系。這是因為,為了提供良好的解耦,它們實際上應該彼此不了解。總線知道什么處理程序應該處理什么命令或查詢的方式應該通過簡單的配置來設置。

如您所見,在這兩種情況下,跨越應用程序核心邊界的所有箭頭和依賴項都指向內部。如前所述,這是端口和適配器體系結構、Onion體系結構和Clean體系結構的基本規則。

結論

一如既往,我們的目標是擁有一個松散耦合和高內聚的代碼庫,這樣修改起來就容易、快速和安全。

計劃是沒有價值的,但計劃就是一切。 -------------------------------艾森豪威爾

這個信息圖是一個概念圖。了解和理解所有這些概念將幫助我們規劃一個健康的架構,一個健康的應用程序。

然而:

地圖不是領土。 -----------------------阿爾弗雷德Korzybski

這意味著這些只是指導方針!應用程序是我們需要應用知識的領域、現實和具體用例,這就是定義實際體系結構的內容!

我們需要理解所有這些模式,但是為了解耦和內聚,我們還需要思考并準確地理解我們的應用程序需要什么,我們應該走多遠。這個決策可以依賴于許多因素,從項目功能需求開始,但是也可以包括諸如構建應用程序的時間框架、應用程序的生命周期、開發團隊的經驗等因素。

就是這樣,這就是我理解這一切的方式。這就是我在腦海里給它找的合理解釋。

我在后續的文章中進一步擴展了這些想法:不僅僅是同心圓層。

但是,我們如何在代碼庫中顯式地實現這一切呢?這是我下一篇文章的主題:如何在代碼中反映體系結構和域。

本文http://jiagoushi.pro/ddd-hexagonal-onion-clean-cqrs-how-i-put-it-all-together
討論:請加入知識星球【首席架構師圈】或者加微信小號【jiagoushi_pro】或者加QQ群【11107777】
公眾號

【jiagoushipro】
【超級架構師】
精彩圖文詳解架構方法論,架構實踐,技術原理,技術趨勢。
我們在等你,趕快掃描關注吧。
微信小號

【cea_csa_cto】
50000人社區,討論:企業架構,云計算,大數據,數據科學,物聯網,人工智能,安全,全棧開發,DevOps,數字化.

QQ群

【11107767】深度交流企業架構,業務架構,應用架構,數據架構,技術架構,集成架構,安全架構。以及大數據,云計算,物聯網,人工智能等各種新興技術。
加QQ群,有珍貴的報告和干貨資料分享。

視頻號【超級架構師】
1分鐘快速了解架構相關的基本概念,模型,方法,經驗。
每天1分鐘,架構心中熟。

知識星球向大咖提問,近距離接觸,或者獲得私密資料分享。知識星球【首席架構師圈】
微信圈子志趣相投的同好交流。微信圈子【首席架構師圈】
喜馬拉雅路上或者車上了解最新黑科技資訊,架構心得。【智能時刻,架構君和你聊黑科技】
知識星球認識更多朋友,職場和技術閑聊。知識星球【職場和技術】
微博【智能時刻】智能時刻
嗶哩嗶哩【超級架構師】
抖音【cea_csa_cto】超級架構師
快手【cea_csa_cto】超級架構師
小紅書【cea_csa_cto】超級架構師首席架構師智庫

謝謝大家關注,轉發,點贊和點在看。

總結

以上是生活随笔為你收集整理的「领域驱动设计」DDD,六边形架构,洋葱架构,整洁架构,CQRS的整合架构的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 91精品国产麻豆国产自产在线 | 亚洲一区二区三区久久久 | 多男调教一女折磨高潮高h 国内毛片毛片毛片毛片毛片 | 五月天丁香| www.伊人久久 | wwwav在线| 包射屋 | 久久丫精品国产亚洲av不卡 | 国产欧美一区二区三区国产幕精品 | 老外一级片 | 69国产精品| 国产高清二区 | av作品在线| a级无遮挡超级高清-在线观看 | 人人舔人人| 亚洲第一成人在线 | 丰满人妻综合一区二区三区 | 在线观看中文字幕av | 亚洲国产精品va在线 | 欧美黄色网络 | 亚洲射图 | 处女朱莉第一次 | 男女国产精品 | 夜夜操操操 | 久久婷婷五月综合色吧 | 国产欧美一区二区三区鸳鸯浴 | 国产精品一二区在线观看 | 欧美日本成人 | 在线观看成人黄色 | 国产一区二区三区麻豆 | 毛片在线看网站 | 欧美专区 日韩专区 | 国产美女在线观看 | 日韩午夜在线观看 | 国产午夜精品在线 | 亚洲男人的天堂网站 | 七仙女欲春2一级裸体片 | 国产又黄又粗又猛又爽的视频 | 可以看毛片的网站 | 亚洲精品网站在线 | 小小姑娘电影大全免费播放 | 国产成人av一区二区 | 久久久久久久网站 | 中文字幕999| 国产精品久久久久久久久夜色 | 超碰精品在线 | 国产在线1区 | 琪琪色影音先锋 | 日本无遮挡边做边爱边摸 | 亚洲三级视频 | 亚洲人吸女人奶水 | av官网在线观看 | 国产真人毛片 | 亚洲国产一区二区a毛片 | 老司机精品福利导航 | 五月婷婷激情综合网 | 久久久香蕉 | 91亚洲精华国产精华精华液 | 久久青草免费视频 | 国产成人午夜视频 | 久久精品国产99国产精品 | 日本黄色片免费看 | 粉嫩aⅴ一区二区三区 | 女人被男人操 | 怡红院av亚洲一区二区三区h | 日干夜操 | 国产午夜精品视频 | 亚洲影视在线 | 亚洲男人天堂电影 | 精品人妻无码一区 | 欧美成人做爰大片免费看黄石 | 亚洲最大色网站 | 国产高清视频在线免费观看 | 性精品 | 中文字幕岛国 | 欧美性猛交xxxx偷拍洗澡 | 国产奶头好大揉着好爽视频 | 亚洲AV无码成人片在线观看 | 国产精品成人网站 | 成人免费毛片xxx | 不卡中文一二三区 | 爱逼av| 日韩美女激情 | 国产av一区二区三区最新精品 | 九九视频这里只有精品 | 亚洲乱码国产乱码精品天美传媒 | 少妇做爰免费视频播放 | 麻豆免费观看视频 | 一区二区三区在线免费播放 | 国产1区2区3区中文字幕 | 99色网| 小说肉肉视频 | jzzijzzij日本成熟少妇 | 精品久久久久久久久久久久 | 私人网站| 黄色大片日本 | www.国产在线| 成人污污视频 | 国产经典久久久 |