精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

編寫更清晰代碼:去掉所有多余的類型

譯文 精選
開發 前端
最近,在 r/swift 子論壇上,我偶然發現了一篇介紹“整潔架構”項目示例的帖子。這引起了我的興趣,于是我決定在 GitHub 上下載并仔細研究。

最近,在 r/swift 子論壇上,我偶然發現了一篇介紹“整潔架構”項目示例的帖子。這引起了我的興趣,于是我決定在 GitHub 上下載并仔細研究。

帖子截圖帖子截圖

初看代碼頗為復雜,讓我感到迷惑。但在下載和深入研究后,我發現所有組件都整合在一起,項目實現了想要的功能。但我發現該項目的網絡模塊的復雜性較高。僅兩個簡單的網絡查詢操作竟涉及如此多的文件,讓人難以理解,讓我頗為驚訝。

因此,我決定對網絡層進行重構,使其更加模塊化,并對整體組合和用戶界面進行了小幅優化。為此,我創建了獨立的項目對原始項目代碼進行重構,你可以在文末找到原始項目和我重構后的項目鏈接。

網絡層——消除嵌套和多余類型

原項目的網絡層通過協議和類型結構實現了高度模塊化,每個協議和類型分別負責特定功能,大致結構如下:

NetworkManager -> RequestManager -> RequestProtocol -> DataParser -> DataSource -> Repository -> UseCase

上述每一個類型都承擔了網絡過程的一部分職責,例如 DataParser 負責數據解析,如果想改變數據的解析方式,可以通過替換新的 DataParser 來實現,這種組合性是一項優點。

但問題在于,由于這些類型相互嵌套,使人難以整體理解,且每個類型都存于單獨的文件中。許多通過 Swinject 解析器進行注入,這使得整個網絡層的工作流程變得難以追蹤。正如 r/swift 中的一名評論者所言,這為代碼增加了一層不必要的“中間層”。

更令人費解的是,盡管作者增加了許多協議和類型來提高代碼的靈活性,但其中存在很多硬編碼的默認值。例如,DataParser 被直接編碼在代碼中,而 RequestProtocol.request() 的創建僅通過協議本身的擴展方法來實現。這種在增加了類型和復雜性后未充分利用它們的優勢的做法,實在讓人覺得可惜。

為了消除冗余的嵌套以及不必要的類型和協議,我們可以引入一個全新的方法:modelFetcher。

static func modelFetcher<T, U: Codable>(
    createURLRequest: @escaping (T) throws -> URLRequest,
    store: NetworkStore = .urlSession
) -> (T) async -> Result<BaseResponseModel<PaginatedResponseModel<U>>, AppError> {
    let networkFetcher = self.networkFetcher(store: store)
    let mapper: (Data) throws -> BaseResponseModel<PaginatedResponseModel<U>> = jsonMapper()

    let fetcher = self.fetcher(
        createURLRequest: createURLRequest,
        fetch: { request -> (Data, URLResponse) in
            try await networkFetcher(request)
           }, mapper: { data -> BaseResponseModel<PaginatedResponseModel<U>> in
                       try mapper(data)
                      })

    return { params in
          await fetcher(params)
         }
}

此函數的設計旨在保持與原代碼相同的組合功能,但未采用協議(protocols)和類型(types),而是通過直接注入操作行為來實現。需要說明的是,如果這樣更方便,你還可以將其構造成一個帶閉包的結構體,而不僅限于閉包。

接下來,實際的請求獲取閉包創建過程被大大簡化,唯一會變化的是請求創建部分。

static func characterFetcher(
    store: NetworkStore = .urlSession
) -> (CharacterFetchData) async -> Result<BaseResponseModel<PaginatedResponseModel<CharacterModel>>, AppError> {
    let createURLRequest = { (data: CharacterFetchData) -> URLRequest in
                          var urlParams = ["offset": "\(data.offset)", "limit": "\(APIConstants.defaultLimit)"]
                          if let searchKey = data.searchKey {
                              urlParams["nameStartsWith"] = searchKey
                          }

                          return try createRequest(
                              requestType: .GET,
                              path: "/v1/public/characters",
                              urlParams: urlParams
                          )
                         }

    return self.modelFetcher(createURLRequest: createURLRequest)
}

優化后,我們無需深入到許多不同的文件中,也無需理解眾多的協議和類型,因為我們可以通過直接注入閉包來實現相同的行為。NetworkStore 負責實際將數據發送到網絡,我們將其傳遞到構造函數中是為了方便后續的測試模擬(如果有需要的話)。

下面的例子展示了如何通過使用行為替代類型,將原始項目中的協議和類型進行轉換:

protocol NetworkManager {
    func makeRequest(with requestData: RequestProtocol) async throws -> Data
}

class DefaultNetworkManager: NetworkManager {
    private let urlSession: URLSession

    init(urlSession: URLSession = URLSession.shared) {
        self.urlSession = urlSession
    }

    func makeRequest(with requestData: RequestProtocol) async throws -> Data {
        let (data, response) = try await urlSession.data(for: requestData.request())
        guard let httpResponse = response as? HTTPURLResponse,
        httpResponse.statusCode == 200 else { throw NetworkError.invalidServerResponse }
        return data
    }
}

這段代碼還可以繼續優化變得更簡潔:

static func networkFetcher(
    store: NetworkStore
) -> (URLRequest) async throws -> (Data, URLResponse) {
    { request in
     let (data, response) = try await store.fetchData(request)
     if let httpResponse = response as? HTTPURLResponse,
     httpResponse.statusCode != 200 {
         throw NetworkError.invalidServerResponse
     }

     return (data, response)
    }
}

可以看出,我們在移除類型和協議的情況下實現了相同的功能。

另一個案例是通過函數創建一個 JSON 映射器,并將其作為閉包返回,保留協議的靈活性,卻不依賴協議。例如:

static func jsonMapper<T: Decodable>() -> (Data) throws -> T {
    let decoder = JSONDecoder()
    decoder.keyDecodingStrategy = .convertFromSnakeCase
    return { data in
            try decoder.decode(T.self, from: data)
           }
}

在我看來,與基于協議/類型的方法相比,這種組合方式讓網絡層的實現變得更為直觀和簡潔。

這并不意味著你不應使用協議,但在選擇使用協議和類型時,應明確了解其用途,并思考是否真的需要為每 2-3 行代碼創建一個完整的類型。

項目模塊劃分

總體上,應用程序的模塊劃分還算理想。然而,我覺得可以進一步完善項目,方法是對網絡模塊進行明確的劃分。讓我們思考一下:應用程序真的需要了解它將使用哪個 JSON 映射器作為網絡特性嗎?我們是否可以更改網絡特性的JSON映射器而不破壞整個結構?如果網絡模塊能夠自主處理這些內容,那就更好了,這樣我們可以專注于使用它的主要目的:獲取超級英雄數據。

我們應該限制網絡模塊接收的內容,僅限于有意識地改變的部分,如用于測試的輸入,而不過多暴露。此外,我們可以只公開實際使用的部分,例如fetcher功能,而不是整個NetworkStore模塊的所有底層特性,并將其設為public。

值得注意的是,網絡模塊不應涉及域的內容,最好將ArkanaKeys依賴從整個項目中獨立出來,單獨置于網絡模塊中。擁有一個完全隔離的網絡模塊,可以讓我們在制作任何關于漫威超級英雄的應用時,輕松地復用所有的網絡邏輯。

在提供的示例代碼中,我僅進行了“虛擬模塊化”操作,沒有為網絡模塊創建獨立的框架,也沒有將ArkanaKeys的依賴關系轉移到那里。相反,我創建了一個文件夾并加入了訪問控制,模擬了完全獨立框架的情形。這樣做是為了使演示項目簡潔,實際上,你只需創建一個框架并添加到項目中即可。

另一個更遠大的目標是將 UI 和演示邏輯進行分離。目前這兩者相當耦合,我覺得這并不是問題。我刪除了 Presentation 文件夾,并把它們和 UI 層放在一起,因為在這一點上,很難想象使用 HomeViewModel來做除了 HomeView以外的事情,但這是一個組織代碼的個人喜好問題。

我最終使用了一個簡單的 Container類來代替 Swinject,但這也是個人喜好的問題。無論如何,解析器/容器應該避免嘗試解析太多具體的網絡類型,比如 NetworkManager, DataSource, Repositories和UseCases。在這種情況下,讓我們注入 NetworkStore(我用來替換 NetworkManager的類型)并直接解析UseCase 的依賴。

UI 層的優化更新

以下是關于 UI 層的一些優化更新,通過減少縮進和刪除 AnyView類型來提高可讀性和性能。將 View從 body中提取出來以提高可讀性,在我看來,盡可能減少縮進到只有幾個級別是有幫助的。原始應用程序在 HomeView中達到了 13 個縮進級別!而且,它是應用程序的根視圖,所以從一開始就盡可能地使其可讀是一個好主意。通過將 homeView提取為一個計算屬性,我們可以很容易地將縮進減少到只有五個級別。
示例如下:

public var body: some View {
    NavigationStack {
        ZStack {
            BaseStateView(
                viewModel: viewModel,
                successView: homeView,
                emptyView: BaseStateDefaultEmptyView(),
                createErrorView: { errorMessage in
                                    BaseStateDefaultErrorView(errorMessage: errorMessage)
                                   },
                loadingView: BaseStateDefaultLoadingView()
            )
        }
    }
    .task {
        await viewModel.loadCharacters()
    }
}

我想最后提一下的是,這個應用使用了一個 BaseStateView,它接受四個不同的 AnyView來表示應用的不同狀態,比如成功、空、錯誤等。BaseStateView使用泛型來代替 AnyView會更合適,因為 AnyView對于 SwiftUI 來說并不總是性能很好。這樣會提高性能,但是一個缺點是,它讓我們必須傳入我們想要的具體的 View,比如成功/空/創建/加載,而不是讓它們在構造函數中自動為我們完成。
示例如下:

struct BaseStateView<S: View, EM: View, ER: View, L: View>: View {
    @ObservedObject var viewModel: ViewModel
    let successView: S
    let emptyView: EM?
    let createErrorView: (_ errorMessage: String?) -> ER?
    let loadingView: L?
    ...
}

為了提高可讀性,你可以使用如SuccessView、EmptyView等名稱。

在 SwiftUI 的上下文中,使用單一基礎控制器/視圖的方法可能不太符合習慣。與直接將所有這些狀態處理器添加到基礎視圖上相比,以 ViewModifiers的形式將它們組合起來并添加感覺更為自然。不過,每種方法都有其優劣之處。如果你想強調構造函數的使用,并且想通過減少 ZStacks 的使用來實現,那么這種方法也是可取的。

struct ErrorStateViewModifier<ErrorView: View>: ViewModifier {
    @ObservedObject var viewModel: ViewModel
    let errorView: (String) -> ErrorView

    func body(content: Content) -> some View {
        ZStack {
            content
            if case .error(let message) = viewModel.state {
                errorView(message)
            }
        }
    }
}

結論

衷心感謝 mohaned_y98 提供的啟發和出色的示例項目!本文基于清晰的架構原則,采用了與原始項目不同的風格進行探索。相較于我所重構的項目,原始項目有其獨特的優勢,你可根據項目需求選擇適合的設計方案。

在盡量保留初衷的同時,我對項目進行了重構,增強了其人體工程學和可讀性。鑒于用戶界面或展示層已經構建得非常穩固,我未在這些方面投入過多精力。如果從頭開始,我可能會選擇不同的編碼方式,但現有的代碼編寫得恰到好處,且運作正常。

原始項目和我重構后的項目鏈接放在下方,歡迎下載閱讀我重構后的項目。你認為我忽略了哪些方面?你會有哪些不同的實現方法?

原始項目: https://github.com/Mohanedy98/swifty-marvel我重構后的項目:https://github.com/terranisaur/Demo-SwiftyMarvelous

譯者介紹

劉汪洋,51CTO社區編輯,昵稱:明明如月,一個擁有 5 年開發經驗的某大廠高級 Java 工程師,擁有多個主流技術博客平臺博客專家稱號。

原文標題:Clean Code Review: Removing All the Extra Types,作者:Alex Thurston

責任編輯:華軒 來源: 51CTO
相關推薦

2020-12-08 05:45:16

JavaScript代碼開發

2023-07-30 17:10:32

TypeScript開發

2024-11-26 11:39:29

2020-08-06 16:34:48

Python開發工具

2022-08-28 19:03:18

JavaScript編程語言開發

2020-02-25 20:55:20

JavaScript開發 技巧

2020-10-04 13:15:37

代碼技術開發

2014-08-19 09:39:46

程序員

2022-05-10 10:28:21

JavaScript代碼

2023-12-18 10:01:40

Golang代碼開發

2023-12-19 22:40:23

Golang編程函數

2022-01-13 14:06:37

Python 開發編程語言

2023-09-19 23:30:25

單元測試代碼

2025-02-03 10:04:47

擴散模型數據分布

2019-10-22 13:34:06

SQL數據庫語句解讀

2016-10-19 15:42:08

聯想

2019-11-08 09:20:57

代碼開發工具

2020-10-22 09:13:14

NVIDIA

2023-06-12 15:01:07

縮放神器Web工具

2012-01-12 14:51:15

傲游網絡
點贊
收藏

51CTO技術棧公眾號

日本高清视频精品| 亚洲第一二三四五区| 一区二区三区的久久的视频| 国产一区二区三区四区视频| 狠狠综合久久| 亚洲香蕉伊综合在人在线视看| 色天使在线观看| 欧洲成人综合网| 国产日韩成人精品| 97久久精品午夜一区二区| 久久中文字幕免费| 欧美久久九九| 中日韩午夜理伦电影免费| av地址在线观看| 亚洲高清黄色| 亚洲一区日韩精品中文字幕| 日韩妆和欧美的一区二区| 国产高清第一页| 日本麻豆一区二区三区视频| 亚州欧美日韩中文视频| 中国毛片直接看| 欧美禁忌电影| 亚洲国产成人精品一区二区| 青青草久久伊人| 亚洲风情在线资源| 亚洲综合999| 特级黄色录像片| 国产高清av在线| 91视频国产资源| 高清一区二区三区视频| 91中文字幕在线视频| 亚洲欧美卡通另类91av| 久久久久中文字幕2018| 精品一区在线观看视频| 成人中文在线| 一级做a爰片久久毛片美女图片| 2一3sex性hd| 精品午夜视频| 在线成人av影院| www.99r| 欧美××××黑人××性爽| 欧美日韩国产一区二区| 18禁裸男晨勃露j毛免费观看| 免费看a在线观看| 国产精品久久午夜| 日韩精品电影网站| 在线观看xxx| 91在线一区二区三区| 国产麻豆乱码精品一区二区三区| 国产女同91疯狂高潮互磨| 免费高清成人在线| 国产美女直播视频一区| 在线亚洲欧美日韩| 日本欧洲一区二区| 国产精品美乳一区二区免费 | 亚洲成人1区2区| 天天综合五月天| 中文在线字幕免费观看| 亚洲桃色在线一区| 干日本少妇视频| 亚洲91av| 亚洲成人www| 欧美 日韩 国产一区| 亚洲最大成人| 欧洲日韩一区二区三区| 一级片视频免费观看| 久久亚洲精品人成综合网| 欧美日韩色综合| 91免费视频污| 9l视频自拍蝌蚪9l视频成人| 精品粉嫩超白一线天av| 玖玖爱在线精品视频| 奇米777国产一区国产二区| 日韩精品免费在线| 日本一级免费视频| 日韩电影一区| 欧美成人合集magnet| 久久久久久天堂| 夜夜精品视频| 国产精品日韩在线观看| 国产精品主播一区二区| 丁香一区二区三区| 麻豆成人小视频| 成人精品一区二区三区免费 | 亚洲免费av电影| 日本乱子伦xxxx| 亚洲一区 二区 三区| 久久人人爽人人| 国产精品熟女视频| 狠狠色综合播放一区二区| 成人av蜜桃| 九色网友自拍视频手机在线| 成人欧美一区二区三区小说| 日韩精品在线视频免费观看| 日本综合久久| 欧美成人激情免费网| 加勒比一区二区| 欧美一区在线看| 国产成人精品视频在线| 99久久免费国产精精品| www国产成人免费观看视频 深夜成人网| 日韩少妇中文字幕| 污污在线观看| 欧美艳星brazzers| 男人的天堂影院| 香蕉久久网站| 日本一区二区在线免费播放| 国产农村老头老太视频| 久久久精品影视| 99热这里只有精品免费| 国产精品亚洲成在人线| 日韩av在线高清| 免费一级全黄少妇性色生活片| 久久精品亚洲| 国产精品 日韩| 免费在线看a| 日本精品视频一区二区三区| 免费啪视频在线观看| 日韩一区三区| 日韩69视频在线观看| 后入内射欧美99二区视频| 国产精品狼人久久影院观看方式| 国产 福利 在线| 97品白浆高清久久久久久| yellow中文字幕久久| 国产一卡二卡三卡| 91蜜桃在线观看| 激情小视频网站| 视频免费一区二区| 免费av一区二区| 国产精品久久久久久无人区| 中文字幕精品一区二区三区精品| 男人操女人逼免费视频| 哺乳一区二区三区中文视频| 久久av红桃一区二区小说| 中文字幕在线观看国产| 国产日韩欧美综合在线| 久久久久久久久久久福利| 中文字幕视频精品一区二区三区| 久久久精品日本| 夜夜嗨aⅴ一区二区三区| 久久综合久久鬼色中文字| 91免费黄视频| 成人看片黄a免费看视频| 欧美黑人xxxx| 殴美一级特黄aaaaaa| 亚洲综合av网| 中文字幕18页| 1024日韩| 久久免费99精品久久久久久| 欧美成人精品一区二区男人小说| 日韩禁在线播放| 丁香社区五月天| 国产亚洲一本大道中文在线| 在线免费视频a| 色偷偷综合网| 亚洲最大激情中文字幕| 在线黄色网页| 亚洲国产精久久久久久| 日韩av大片在线观看| 99国产精品国产精品毛片| 国产亚洲综合视频| 美女亚洲一区| 国产精品综合网站| 成人直播在线| 亚洲精品在线观看网站| 日韩和一区二区| 国产亚洲欧美色| jizz18女人| 欧美久久99| 久久精品五月婷婷| av亚洲一区| 欧美插天视频在线播放| 熟妇人妻av无码一区二区三区| 疯狂蹂躏欧美一区二区精品| 亚洲国产日韩一区无码精品久久久| 麻豆精品新av中文字幕| 日本福利视频在线观看| 欧美三级午夜理伦三级在线观看| 国产成人精品视| av观看在线| 亚洲欧美国产一本综合首页| 伊人影院中文字幕| 亚洲一卡二卡三卡四卡无卡久久 | 97国产精品人人爽人人做| 麻豆影视在线| 91精品国产福利在线观看 | 一本色道久久| 亚洲高清在线播放| 91精品国产自产在线丝袜啪 | 亚洲亚洲一区二区三区| 日本国产一区二区三区| 国产三区在线观看| 亚洲毛片在线观看| 99久久国产热无码精品免费| 欧美午夜美女看片| 久久久久久视频| 久久精品一区蜜桃臀影院| 在线视频一二区| 日韩影院免费视频| 蜜桃网站在线观看| 欧美午夜精品一区二区三区电影| 99九九视频| 国产精品美女午夜爽爽| 91精品国产高清| av香蕉成人| 中文字幕无线精品亚洲乱码一区 | 亚洲夜晚福利在线观看| 亚洲欧美另类综合| 欧美日韩激情一区二区三区| 久久狠狠高潮亚洲精品| 一区二区三区四区在线免费观看| 日韩人妻无码精品综合区| www.日韩精品| 男人的天堂免费| 精品一区二区在线视频| 精品久久久久av| 一区二区精品| 东北少妇不带套对白| 欧美一区亚洲| 91免费网站视频| 精品国产日韩欧美| 美国av一区二区三区| 亚洲一区二区三区四区电影| 成人免费黄色网| 欧美91在线|欧美| 国产成人综合精品| 悠悠资源网亚洲青| 91精品国产成人www| 91资源在线观看| 欧美精品久久一区二区| 手机av免费在线| 久久精品久久久久| yourporn在线观看视频| 亚洲天堂2020| 国产在线视频网| 亚洲人免费视频| 欧洲天堂在线观看| 精品亚洲aⅴ在线观看| 五月婷婷深深爱| 欧美tk—视频vk| 黄色片一区二区三区| 精品福利在线导航| 天天干天天草天天射| 精品国产乱码久久久久久久久| 国产草草影院ccyycom| 日韩三级高清在线| www.激情五月| 精品美女被调教视频大全网站| 丰满少妇高潮在线观看| 精品国产污网站| 五月婷中文字幕| 国产视频在线观看一区二区| 视频二区在线| 亚洲人成电影网站色| 邻家有女韩剧在线观看国语| 国产亚洲精品激情久久| 在线观看完整版免费| 日韩在线观看免费全集电视剧网站 | 韩国av一区二区三区四区| 中文字幕一区二区在线观看视频 | 中日韩高清电影网| 久久69精品久久久久久久电影好| 日本h片在线观看| 久久久亚洲福利精品午夜| 性欧美18xxxhd| 国产精品美乳一区二区免费| 99久久这里有精品| 国产传媒一区二区三区| 欧美一区二区三区红桃小说| 欧美一区二区三区成人久久片| 色88久久久久高潮综合影院| 日本国产中文字幕| 亚洲欧美日韩国产综合精品二区| 日韩一级免费在线观看| 国产一区在线视频| 国产精品一区二区人妻喷水| 久久先锋影音av| 成人欧美一区二区三区黑人一 | 久久久久久这里只有精品| h片在线观看视频免费免费| 日本久久久久久久| 亚洲三级电影| 久久国产精品免费一区| 日韩国产一区二区三区| 九九热只有这里有精品| 青青草国产精品亚洲专区无| 91香蕉视频在线观看视频| 91在线看国产| 91n在线视频| 无码av免费一区二区三区试看| 中文字幕二区三区| 日韩欧美你懂的| 国产日本在线| 久久久久中文字幕| 91精品国产一区二区在线观看| 狠狠色综合欧美激情| 99久久影视| 亚洲国产精品久久久久爰色欲| 久久66热re国产| 白丝女仆被免费网站| 夜夜爽夜夜爽精品视频| 羞羞色院91蜜桃| 日韩成人网免费视频| 91麻豆一二三四在线| 国产成人精品综合| 精品五月天堂| 美女黄色片网站| 日韩1区2区3区| 菠萝菠萝蜜网站| 一区二区三区四区高清精品免费观看 | **女人18毛片一区二区| 丁香婷婷激情网| 91丨九色丨蝌蚪富婆spa| 久久久久97国产| 91麻豆精品国产91久久久资源速度 | 懂色av一区二区三区四区| 日韩一区视频在线| 午夜精品久久久久久久久久蜜桃| 国产精品v欧美精品∨日韩| 四虎8848精品成人免费网站| 欧美激情成人网| 99免费精品视频| 久草成人在线视频| 日韩一级成人av| 麻豆网站视频在线观看| 国产va免费精品高清在线观看 | 日韩高清人体午夜| 丰满诱人av在线播放| 91亚洲精品在线| 99久精品视频在线观看视频| 国产一区二区在线免费播放| 国产午夜精品久久| √资源天堂中文在线| 精品亚洲va在线va天堂资源站| 久草在线中文最新视频| 黑人巨大精品欧美一区二区小视频| 激情欧美国产欧美| 91超薄肉色丝袜交足高跟凉鞋| 一区二区三区鲁丝不卡| 国产精品无码免费播放| 久久艳片www.17c.com| 96视频在线观看欧美| 欧美性受xxxx黑人猛交88| 国产一区二区中文字幕| 欧美国产日韩在线观看成人| 欧美一区二区网站| 亚洲91av| 国产综合av一区二区三区| 99精品久久久| 国产偷人妻精品一区| 一本到高清视频免费精品| 国自产拍在线网站网址视频| 国产精品美女免费视频| 欧美aaaaaaaaaaaa| 成人免费黄色av| 亚洲高清久久久| 日本韩国一区| 国产日本欧美一区| 综合激情在线| a天堂视频在线观看| 色综合久久综合中文综合网| av中文资源在线| 亚洲jizzjizz日本少妇| 影音先锋亚洲精品| 人妻体内射精一区二区| 欧美日韩国产免费| 牛牛电影国产一区二区| 精品欧美国产| 欧美aa在线视频| 国产1区2区3区4区| 日韩精品极品视频免费观看| 最新日韩一区| 欧美黄色免费网址| 92国产精品观看| 国产精品自拍电影| 2021国产精品视频| 久久在线电影| 青青草视频网站| 欧美日韩黄色影视| 国产盗摄一区二区| 欧美综合77777色婷婷| 国产精品主播直播| 免费黄色网址在线| 久久婷婷国产麻豆91天堂| 欧美丝袜美腿| 久久婷婷中文字幕| 欧美性xxxx极品hd欧美风情| 成年人在线视频| 国产精品一区二区免费看| 日本午夜精品视频在线观看| 久久综合加勒比| 国产一区二区三区丝袜| 成人精品毛片| 亚洲欧美手机在线| 岛国av一区二区在线在线观看| 日本天堂在线观看| 老牛影视免费一区二区| 国内精品自线一区二区三区视频| 五月天婷婷久久|