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

關于MVC/MVP/MVVM的一些錯誤認識

移動開發 Android
在Android開發中使用MVP和MVVM模式早已不是新鮮事了,各種MVP/MVVM相關的文章、開源庫也已屢見不鮮,甚至是讓人眼花撩亂,那么我為什么還要在這個早已被畫滿涂鴉的黑板上再來涂涂畫畫呢?是想彰顯我的存在感嗎?

在Android開發中使用MVP和MVVM模式早已不是新鮮事了,各種MVP/MVVM相關的文章、開源庫也已屢見不鮮,甚至是讓人眼花撩亂,那么我為什么還要在這個早已被畫滿涂鴉的黑板上再來涂涂畫畫呢?是想彰顯我的存在感嗎?那當然!啊不不不……不完全是!我還想要警醒讀到這篇文章的各位:你們對于MVX的理解可能并不完全正確!

注:這篇文章里我將使用 MVX 做為MVC、MVP以及MVVM的統稱。

我們都知道MVX的進化過程是從滾球獸進化到MVC,然后從MVC進化到MVP,再從MVP超進化到MVVM。那么接下來,按照常規的套路,我應該要介紹什么是MVC,什么是MVP,以及什么是MVVM,并且分別介紹M、V、C/P/VM各自的職責了。

[[280783]]

我的目的是想要糾正一些對MVX的錯誤認識,所以前提是你要對MVX有一些了解。為了避免有人在使用MVX時走上彎路,所以決定對我看到的一些關于MVX的錯誤認識進行總結以及糾正。會產生這些錯誤認知的原因,經我分析,其實是:沒有真正領會到MVX主義的核心價值觀!其實MVX的核心思想也很簡單,不要誤會,不是富強、民主、……而是 將表現層和業務層分離 。

表現層和業務層分離

表現層和業務層分離,Matin Fowler稱之為Separated Presentation。這里的表現層就是VX,業務層就是M。如果有人看到這里發現了和你認為的MVX不一樣的話,那么你對MVX的認識很可能就存在錯誤,嚴重者還可能是走了修正主義路線!

從表現層和業務層分離的視角來看,M、V、X不是平等的身份,應該是M和V-X。自始自終M的職責都沒變,變的是V-X,隨著軟件開發技術的發展、交互形式或者交互媒介的不斷改變,表現層的邏輯也越來復雜,MVX的進化過程就是一個不斷探尋處理表現層復雜邏輯的過程。當然從一個形態進化到另一個形態,并不一定是為了解決更復雜的交互邏輯,也可能是有了一種“更優雅”的方式來處理表現層邏輯。

既然已經有表現層和業務層分離的概念了,那么第一個錯誤觀點就很好解釋了。

錯誤一:Presenter或者ViewModel負責處理業務邏輯

這是一個很常見的錯誤觀點,很多介紹MVP或者MVVM的文章都這么說過。正如前面所說,業務邏輯是屬于M層的,那Presenter或者ViewModel是干什么的,處理表現層邏輯的嗎?是的,或者說大部分表現層邏輯都是在Presenter或者ViewModel中處理的。之前我將業務層之上的這些邏輯稱之為視圖邏輯,現在為了統一就叫做表現層邏輯吧(加個吧字怎么感覺怪怪的)。

我在這里就簡單說一下什么是表現層邏輯,以及View和Presenter/ViewModel又是如何分工的。假設你的應用有一個個人資料的profile頁面,這個頁面有兩種狀態,一種是瀏覽狀態,一種是編輯狀態,通過一個編輯按鈕觸發狀態的轉換,編輯狀態時,部分信息項可以進行編輯。那這里就有一個明顯的表現層邏輯,那就是點擊按鈕切換瀏覽/編輯狀態。

現在的MVP的流行形態(或者變種)叫做Passive View,它和MVVM一樣現在都傾向于將幾乎所有的表現層邏輯交給Presenter或者ViewModel處理,View層需要做的事情很少,基本上就是接受用戶事件,然后將用戶事件傳遞給Presenter或者ViewModel。以上面的profile頁面的例子來解釋的話就是,View層負責接收編輯按鈕的點擊事件,然后通知Presenter/ViewModel,然后Presenter/ViewModel通知View是顯示瀏覽狀態的視圖還是編輯狀態的視圖。MVP的示例代碼大概是這樣的:

  1. public class ProfileView { 
  2.     void initView() { 
  3.         // 負責注冊點擊事件監聽器,并將點擊事件通知給presenter 
  4.         editStateButton.setOnClickListener(new OnClickListener() { 
  5.             presenter.onEditStateButtonClicked(); 
  6.         }) 
  7.         ... 
  8.     } 
  9.  // 顯示瀏覽狀態視圖,想不到好名字,就叫showNormalState吧 
  10.     public void showNormalState() { 
  11.         // 瀏覽狀態下編輯按鈕提示文字為“編輯”,所有項不可編輯 
  12.         editStateButton.setText("編輯"); 
  13.         nickName.setEditable(false); 
  14.         ... 
  15.     } 
  16.     public void showEditState() { 
  17.         // 瀏覽狀態下編輯按鈕提示文字為“完成”,部分項要設置為可編輯 
  18.         editStateButton.setText("完成"); 
  19.         nickName.setEditable(true); 
  20.         ... 
  21.     } 
  22.  
  23.  
  24. public class ProfilePresenter { 
  25.     private State curState = State.NORMAL; 
  26.     public void onEditStateButtonClicked() { 
  27.         // 按鈕被點擊時,根據當前狀態判斷View應該切換顯示的狀態 
  28.         // 這就是表現層邏輯 
  29.         if (isInEditState()) { 
  30.             curState = State.NORMAL; 
  31.             view.showNormalState(); 
  32.         } else { 
  33.             curState = State.EDIT; 
  34.             view.showEditState(); 
  35.         } 
  36.     } 
  37.     private boolean isInEditState() { 
  38.         return curState == State.EDIT; 
  39.     } 
  40.     @VisibleForTest 
  41.     void setState(State state) { 
  42.         curState = state; 
  43.     } 

注:這個示例代碼只是為了展示表現層邏輯,沒有涉及到Model層,編譯也不會通過的!

能感受到我想表達的意思嗎?就是Presenter/ViewModel根據當前交互狀態決定該顯示什么,而View要做的是如何顯示它們。再比如說下拉刷新的場景,由View告訴Presenter/ViewModel,它接收到了下拉事件,然后Presenter/ViewModel再告訴View,讓它去顯示刷新提示視圖,至于這個刷新提示長什么樣就由View來決定。當然Presenter/ViewModel也可能會判斷當前網絡不可用,而讓View顯示一個網絡不可用的提示視圖。

為什么要讓Presenter/ViewModel處理幾乎所有的表現層邏輯呢?主要是為了提高可測試性,將盡可能多的表現層邏輯納入到單元測試的范圍內。因為對視圖控件的顯示等等進行單元測試太難了,所以View是基本上沒法進行單元測試的,但是Presenter/ViewModel是完全可以進行單元測試的:

  1. public class ProfilePresenterTest { 
  2.     private ProfilePresenter presenter; 
  3.     private ProfileView view
  4.     @Test 
  5.     public void testShowEditStateOnButtonClick() { 
  6.         // 瀏覽狀態下點擊編輯按鈕,驗證View是否顯示了編輯狀態視圖 
  7.         // 也就是驗證view.showEditState()方法是否被調用了 
  8.         presenter.setState(State.NORMAL); 
  9.         presenter.onEditStateButtonClicked(); 
  10.         Mockito.verify(view).showEditState(); 
  11.     } 
  12.     @Test 
  13.     public void testShowNormalStateOnButtonClick() { 
  14.         // 編輯狀態下點擊完成按鈕,驗證View是否顯示了瀏覽狀態視圖 
  15.         // 也就是驗證view.showNormalState()方法是否被調用了 
  16.         presenter.setState(State.EDIT); 
  17.         presenter.onEditStateButtonClicked(); 
  18.         Mockito.verify(view).showNormalState(); 
  19.     } 

你看,這些表現層邏輯就都能進行單元測試了吧!大概懂我意思了吧?

[[280784]]

OK,現在你已經知道表現層了,那業務層又是干什么用的呢?現在我們就要開始談到M了。

M是什么?M是指那些喜歡從受虐中獲得性……哎呀,不好意思,搞混了!哎~學識淵博就是麻煩!M者,Model也,再長一點就是Domain Model,中文名字叫領域模型。我們看一下維基百科上對Domain model的定義:

  • In software engineering, a domain model is a conceptual model of the domain that incorporates both behaviour and data.

怎么樣,是不是很通俗易懂呀?當然不是!剛剛開始有點理解Model層是處理業務邏輯的,現在又來了個抖MMM……Domain,我都不知道該往哪里去想了!Domain,簡單點就把它理解成業務,我覺得都沒啥問題。我這里引用這句話,主要是想強調,Model層包含了業務數據以及對業務數據的操作(behaviour and data),也是為了引出第二個錯誤觀點。

錯誤二:Model就是靜態的業務數據

我們做業務模塊開發時,會經常定義一些數據結構類,比如個人資料可能會對應一個UserProfile類,一條訂單數據可能會對應一個Order類,這些類沒有任何邏輯,只有一些簡單的getter、setter方法。有些人會認為像UserProfile或者Order這樣的數據結構類就是Model。

我們已經強調了,Model層包含了業務數據以及對業務數據的操作。像UserProfile或者Order這樣的數據結構類的實例甚至都不能稱之為對象,可以看一下Uncle Bob的Classes vs. Data Structures這篇文章,對象是有行為的,一個數據結構實例沒有行為,連對象都稱不上,怎么能代表Model層呢!

靜態的業務數據不能代表Model層,業務數據以及針對業務數據的操作共同構成了Model層,這也就是業務邏輯。再舉個例子說一下吧,假設你在做一個叫“掘鐵”的app,這個app現在只有一個頁面,用來展示推薦的博客列表。OK,我們如果用MVP的形式該怎么寫呢?我們就先不管和Model層完全沒有交互的View了,Presenter層除了處理表現層邏輯外,還要向Model層發出業務指令,注意,Presenter并不處理業務邏輯,真正的業務邏輯還是由Model層完成。示例代碼大概是下面這樣:

  1. public class RecommendBlogFeedPresenter { 
  2.     private RecommendBlogFeedView view
  3.     private BlogMode model; 
  4.     public void onStart() { 
  5.         view.showLoadWait(); 
  6.         model.loadRecommendBlogs(new LoadCallback<>() { 
  7.             @Override 
  8.             public void onLoaded(List<Blog> blogs) { 
  9.                 view.showBlogs(blogs); 
  10.             } 
  11.         }) 
  12.     } 
  13.  
  14.  
  15. public interface BlogModel { 
  16.     void loadRecommendBlogs(LoadCallback<List<Blog>> callback); 
  17. public class BlogModelImpl implements BlogModel { 
  18.     private BlogFeedRepository repo; 
  19.     @Override 
  20.     public void loadRecommendBlogs(LoadCallback<List<Blog>> callback) { 
  21.         // BlogFeedRepository.fetch()很可能是耗時操作,所以實際寫的時候會在非主線程執行,這里只是示例 
  22.         callback.onLoaded(repo.fetch("recommend")); 
  23.     } 
  24. public interface BlogFeedRepository { 
  25.     List<Blog> fetch(String tag); 

什么?你這個BlogModelImpl里就這一行代碼,你跟我說這是業務邏輯?大家冷靜一下,把手里的板磚、砍刀、狼牙棒先放下來。BlogModelImpl類里面的邏輯雖然簡單,但是它的確是業務邏輯,也正是因為業務邏輯比較簡單,所以BlogModelImpl類才會很簡潔。

再從Presenter的角度看一下,為什么loadRecommendBlogs()屬于業務邏輯。博客這個概念毫無疑問屬于業務概念,根據前面的解釋應該可以判斷出來“獲取推薦的博客列表”不屬于表現層邏輯,那么這個邏輯的實現就不是Presenter需要關心的,那就應該是Model層的職責,既然是Model層的那就應該是業務邏輯了;再者,既然博客是業務概念,那么Blog就是業務數據的數據結構,loadRecommendBlogs()涉及到對業務數據Blog的創建及組裝等操作,所以也應該是業務邏輯。

看到這里,可能有些人會產生一些誤解:所謂的業務邏輯處理就是網絡請求、數據庫查詢等數據獲取邏輯,即Model層就是負責數據獲取的,這也是我要說的第三個錯誤觀點。稍等,我先寫個標題⬇

錯誤三:Model層就是負責數據獲取的

產生這種錯誤認識的,說白了還是沒有搞懂業務邏輯。當然了業務邏輯本身就是很抽象的概念,難理解,也很難區分,我也不敢往細了去說,因為說多了怕被你們發現其實我也是在裸泳。

業務邏輯層并不負責數據的獲取,數據的獲取職責還要在Model層的更下層,這也是為什么我要把的BlogModel的實現邏輯寫得如此簡單,因為數據獲取的職責全部交給了BlogFeedRepository類,Model層只處理業務邏輯。BlogFeedRepository是博客列表的倉儲類,BlogModel通過BlogFeedRepository的fetch()方法獲取標簽為recommend的博客列表,也就是推薦的博客列表。BlogModel不關心BlogFeedRepository是如何獲取對應博客數據的,它可以是從通過網絡請求獲取的,也可以是從本地數據庫中獲取的,數據源有任何改變也不應該影響到BlogModel中的業務邏輯。

那么既然BlogModel中的業務邏輯如此簡單,為什么要強行增加這么一個Model層,而不是讓Presenter直接使用BlogFeedRepository類去獲取數據呢?

當然是有原因的!假設我們剛才介紹的“掘鐵”app,在僅有一個博客列表頁面的情況下,依然吸引了很多用戶去使用,產品經理此時決定嘗試探索變現手段,首先是在博客推薦列表中添加廣告數據。再假設,由于廣告數據和博客數據分屬不同的后端團隊,兩邊數據尚未整合打通,暫時由客戶端負責把廣告數據添加到博客列表中。這個時候,BlogModel終于凸顯了它存在的必要性。表現層不負責廣告數據的獲取與整合,BlogFeedRepository也不能負責廣告數據的獲取與整合。廣告數據的整合是業務邏輯,由BlogModel負責,廣告數據的獲取由專門的數據倉儲類負責。示例代碼如下:

  1. public class BlogModelImpl implements BlogModel { 
  2.     private BlogFeedRepository blogRepo; 
  3.     private AdRepository adRepo; 
  4.     private BlogAdComposeStrategy composeStrategy; 
  5.     private AdBlogTransform transform; 
  6.     @Override 
  7.     public void loadRecommendBlogs(LoadCallback<List<Blog>> callback) { 
  8.         List<BlogAd> ads = adRepo.fetch("recommend"); 
  9.         List<Blog> blogs = blogRepo.fetch("recommend"); 
  10.         // 在這里把廣告數據整合到博客列表中 
  11.         blogs = composeStrategy.compose(blogs, ads, transform); 
  12.         callback.onLoaded(blogs); 
  13.     } 
  14. public interface AdRepository { 
  15.     List<BlogAd> fetch(String tag); 
  16. public interface BlogAdComposeStrategy { 
  17.     List<Blog> compose(List<Blog> blogs, List<BlogAd> ads, AdBlogTransform transoform); 
  18. public interface AdBlogTransform { 
  19.     Blog transform(BlogAd ad); 

考慮到廣告和博客可能有不同的整合策略,可以按需替換不同的實現,所以把整合策略封裝到了BlogAdComposeStrategy接口中。整合策略也屬于業務邏輯,但是因為整合策略的實現細節這里不需要關注,所以我覺得不寫出來也行,反正都是我編的。

這里我想表達的是,獲取廣告數據并將廣告數據整合到博客列表中也是業務邏輯的一部分,如果省略Model層將會造成得把廣告的整合邏輯放到Presenter或者Repository層,這必然都是不合適的。將業務邏輯放到了錯誤的層次里,勢必會造成后續的維護性和擴展性問題。

錯誤四:Model層依賴Presenter/ViewModel層

還有一些人沒有搞清楚Model層和上層的依賴關系,依賴關系寫成了雙向的,這是不對的,業務層不應該依賴表現層,而是應該反過來。

實際上應該是Presenter/ViewModel通過接口的形式依賴Model層,Model層完全不依賴Presenter/ViewModel。就像我前面的示例代碼里一樣,Model層必然不會出現任何presenter這樣的單詞,上層通過觀察者模式來監聽Model層的數據變化(LoadCallback接口也算是一種),Model層也不用關心上層是Presenter還是ViewModel。

最后

讀到這里,不知道你們對MVX的理解是不是更深了些呢?對表現層邏輯、業務邏輯是不是也有了更清晰的認識了呢?

其實關于MVX還有更多可以討論的,比如有些人認為Model層并不是真正處理業務邏輯的地方,它只是業務模塊的一個上層封裝層,我覺得也不無道理,在復雜業務模塊中,業務是存在層次的,MVX中的Model層是所有業務層中的最上層。

還有我剛剛提到的業務層之下還有數據層,這是典型的三層架構的概念,即表現層、業務層和數據層。邏輯存在分層,所以架構也必然要進行分層,MVX可以做為我們從代碼到業務甚至到架構的探索的開端。

 

責任編輯:未麗燕 來源: 安卓巴士
相關推薦

2010-01-15 10:26:08

2013-04-07 10:17:54

WindowsPhon

2017-03-31 20:45:41

MVCMVPMVVM

2020-08-04 10:31:53

JavaScriptthis開發

2011-07-04 08:51:27

編程

2015-06-11 10:33:58

企業級云計算混合云應用

2009-08-13 16:41:12

C#結構

2017-04-01 08:30:00

MVCMVPMVVM

2022-07-31 23:54:24

Linux操作系統

2020-08-20 10:16:56

Golang錯誤處理數據

2021-09-27 15:33:48

Go 開發技術

2021-09-27 10:04:03

Go程序處理

2019-11-18 14:27:01

虛擬化Intel VAMD SVM

2018-03-21 16:19:40

MVCMVPMVVM

2011-07-13 09:13:56

Android設計

2019-09-11 08:52:24

MVCMVPMVVM

2013-04-07 10:40:55

前端框架前端

2009-06-18 09:51:25

Java繼承

2011-07-14 14:15:40

ThreadLocal

2012-09-25 10:03:56

JavaJava封面Java開發
點贊
收藏

51CTO技術棧公眾號

久久精品亚洲一区二区三区浴池| 欧美色蜜桃97| 欧美日韩免费在线观看| 久久久影院一区二区三区| 中文字幕乱码人妻无码久久| 婷婷综合网站| 日韩av影片在线观看| 美女网站免费观看视频| 三级福利片在线观看| 91丝袜国产在线播放| 成人女保姆的销魂服务| 亚洲天堂一区在线观看| 亚洲色图欧美| 国产亚洲精品日韩| 国产精品一区二区人妻喷水| 成人四虎影院| 欧美日韩国产精品一区二区三区四区 | 成人一区二区三区在线观看| 青青草原一区二区| 欧美精品乱码视频一二专区| 国产欧美高清视频在线| 亚洲成人教育av| 极品粉嫩美女露脸啪啪| 欧美7777| 精品福利在线观看| 久久综合亚洲精品| 免费a级在线播放| 久久久久国产精品免费免费搜索| 成人一区二区在线| 国产男女裸体做爰爽爽| 女教师淫辱の教室蜜臀av软件| 国产成人77亚洲精品www| 亚洲国产精品久久一线不卡| mm131午夜| 免费在线你懂的| 国产欧美日韩在线视频| 欧美日韩精品不卡| 午夜福利理论片在线观看| 精品一二线国产| 国产精品久久久久久搜索 | 欧美亚洲禁片免费| 国产精品秘入口18禁麻豆免会员| 国模雨婷捆绑高清在线| 亚洲制服丝袜av| 国产人妻人伦精品| 菠萝蜜视频国产在线播放| 亚洲欧洲国产专区| 亚洲一卡二卡三卡| 秋霞午夜在线观看| 中文字幕在线免费不卡| 亚洲一区二区三区加勒比| 日本精品在线| 亚洲欧洲中文日韩久久av乱码| 国产又粗又爽又黄的视频| 成人免费高清| 亚洲综合久久久久| 缅甸午夜性猛交xxxx| sm性调教片在线观看 | 国产精品无码专区av在线播放| 色黄视频在线观看| 一本一本久久a久久精品综合麻豆| 国产精品va无码一区二区| 一级毛片久久久| 欧美亚洲尤物久久| www.日本久久| 中文无码日韩欧| 亚洲精品电影在线| 一色道久久88加勒比一| 久久看人人摘| 欧美激情精品久久久久| 久久免费播放视频| 久久国产日本精品| 国产精品第1页| 97人妻精品一区二区三区视频| 国产精品综合二区| 国产亚洲精品自在久久| 国产资源在线播放| 成人欧美一区二区三区1314| 日日噜噜夜夜狠狠久久丁香五月 | 国产激情久久久| 亚洲视频一区二区三区四区| 国产乱理伦片在线观看夜一区| 亚洲a成v人在线观看| 色窝窝无码一区二区三区成人网站| 91蝌蚪porny成人天涯| 亚洲日本精品国产第一区| 在线中文免费视频| 欧美性xxxxxxx| www.欧美激情.com| 婷婷综合成人| 日韩专区在线观看| 国产69精品久久久久久久久久| 日本免费新一区视频| 国产91色在线|亚洲| 国产高清一级毛片在线不卡| 亚洲精品欧美激情| 密臀av一区二区三区| 一区二区三区国产好| 亚洲欧洲一区二区三区在线观看| 肉色超薄丝袜脚交69xx图片| 国产欧美91| 91亚洲精品久久久| 邻居大乳一区二区三区| 欧美日本三级| 亚洲精选视频在线| 99草草国产熟女视频在线| 精品国产乱码久久久久久樱花| 日韩精品福利在线| 欧美精品xxxxx| 久久精品久久久精品美女| 久久艹中文字幕| 在线播放蜜桃麻豆| 欧美色视频在线观看| 朝桐光av一区二区三区| 欧美成人一品| 国产精品视频自在线| 欧洲一区av| 亚洲国产日韩在线一区模特| 福利视频999| 日韩国产欧美一区二区| 欧美亚洲另类视频| www.蜜臀av.com| 椎名由奈av一区二区三区| av丝袜天堂网| 国产欧美日韩| 热久久免费国产视频| 污污网站免费在线观看| 亚洲自拍偷拍图区| 国产老头和老头xxxx×| 亚洲精品国产成人影院| 国产精品中文字幕在线观看| 黄色在线视频观看网站| 欧美日韩在线视频首页| 波多野结衣视频播放| 伊人久久综合| 成人免费视频网站| 先锋影音在线资源站91| 日韩一区二区在线免费观看| 亚洲色偷偷综合亚洲av伊人| 久久国产精品99精品国产| 亚洲一区二区三区在线观看视频| 亚洲成av在线| 在线观看日韩欧美| 高潮无码精品色欲av午夜福利| 久久久久久免费| 国产91对白刺激露脸在线观看| 美女一区2区| 欧美性视频网站| 可以免费看污视频的网站在线| 欧美性生交xxxxxdddd| 波多野结衣a v在线| 日韩精品一二三区| 亚洲欧美日产图| 亚洲伦理一区二区| 欧美成人精品在线播放| 亚洲va欧美va| 中文国产字幕在线观看| 亚洲国产精品久久人人爱蜜臀| 黄色在线免费播放| 亚洲欧美高清| 日韩久久精品一区二区三区| 国产亚洲欧美日韩精品一区二区三区 | 天天干天天舔天天操| 日本人妖一区二区| 久久久国产精华液999999| 国产欧美视频在线| 97高清免费视频| 国产香蕉在线| 欧美日韩不卡在线| 免费在线观看亚洲| 久久在线观看免费| 中文字幕资源在线观看| 极品av少妇一区二区| 欧美日韩成人一区二区三区| 欧美a一级片| 欧美高清视频在线| 国产综合在线观看| 日韩欧美国产精品一区| 4438国产精品一区二区| 中文字幕一区在线观看视频| 亚洲成年人在线观看| 久久一区中文字幕| 大片在线观看网站免费收看| 日韩在线你懂的| 成人两性免费视频| 毛片在线网站| 日韩中文字幕在线播放| 四虎成人免费在线| 717成人午夜免费福利电影| 日韩精品无码一区二区| 国产精品美女www爽爽爽| 四虎成人免费视频| 免费成人在线网站| 免费一级特黄特色毛片久久看| 精品美女久久久| 国产经品一区二区| 日韩综合av| 国产91精品久久久久| 视频在线观看入口黄最新永久免费国产| 日韩福利视频在线观看| 99热在线只有精品| 91国产免费看| 国产精品theporn动漫| 国产精品短视频| 人妻丰满熟妇aⅴ无码| 国产精品影视天天线| 国产精品亚洲二区在线观看| 国产精品vvv| 91在线视频观看| 性色av浪潮av| 久久狠狠亚洲综合| 成人精品视频一区二区| 亚洲高清网站| a级片一区二区| 久久一区二区三区喷水| 欧美资源一区| 理论片一区二区在线| av在线亚洲男人的天堂| 国产精品色婷婷在线观看| 国产成人精品日本亚洲| 日韩av一卡| 国色天香2019中文字幕在线观看| а√天堂官网中文在线| 日韩视频在线免费| av在线1区2区| 国产香蕉一区二区三区在线视频| 色鬼7777久久| 亚洲国产成人精品久久| 亚洲精品一区二区口爆| 欧美一二三在线| 国产www免费观看| 91精品国产综合久久久久久| 伊人精品在线视频| 欧美日韩国产一区二区三区地区| 精品一区二区无码| 日本韩国精品在线| 国产精品xxxxxx| 在线影视一区二区三区| 97人妻一区二区精品视频| 一本色道综合亚洲| 波多野结衣不卡| 在线这里只有精品| 中文字幕欧美色图| 欧美精品在线一区二区| 国产精品久久久久久无人区 | 另类小说色综合| 免费高清视频精品| 亚洲高清视频免费| 大美女一区二区三区| 欧产日产国产精品98| 91视频精品在这里| 性欧美13一14内谢| 中文字幕精品—区二区四季| 青青青手机在线视频| 亚洲三级视频在线观看| 欧美卡一卡二卡三| 亚洲亚洲人成综合网络| 五月婷婷中文字幕| 色狠狠色噜噜噜综合网| 夜夜狠狠擅视频| 日韩精品一区二区三区老鸭窝| 亚洲精品字幕在线| 日韩的一区二区| 国产黄在线看| 美女扒开尿口让男人操亚洲视频网站| 日本在线观看高清完整版| 国内精品400部情侣激情| 成人性生交大片免费观看网站| 日韩一区二区高清| 国产 日韩 亚洲 欧美| 欧美视频成人| 免费在线a视频| 麻豆国产91在线播放| 野花视频免费在线观看| 26uuu欧美日本| 国产精品国产三级国产传播| 亚洲图片欧美综合| 激情五月婷婷网| 欧美精品一卡两卡| 午夜av免费在线观看| 日韩中文视频免费在线观看| www中文字幕在线观看| 国产精品九九九| 亚洲一区二区三区在线免费| 日韩电影大全在线观看| 亚洲国产一区二区三区在线播放| 青青草视频在线免费播放| 欧美aa在线视频| 天天躁日日躁狠狠躁av麻豆男男 | 日韩精品视频在线免费观看| 中文字幕在线播放| 性色av一区二区三区免费| 成人一区视频| 精品一区二区国产| 午夜激情久久| 国产日韩一区二区在线| 国产成a人亚洲| 蜜乳av中文字幕| 亚洲成人一区二区在线观看| 91精品国产乱码久久久| 日韩精品免费在线播放| 2024最新电影免费在线观看| 国产精品看片资源| 国偷自产视频一区二区久| 一区二区三区av在线| 一本久久综合| 日韩精品在线播放视频| 中文字幕免费不卡在线| 日本少妇裸体做爰| 欧美一二三在线| 午夜视频在线观看网站| 日韩av手机在线| 福利片一区二区| 日本黄网站色大片免费观看| 麻豆一区二区在线| 午夜时刻免费入口| 欧美三级免费观看| 人人妻人人澡人人爽精品日本| 日韩在线观看免费全| 户外露出一区二区三区| 久99久在线| 亚洲激情自拍| 激情综合激情五月| 亚洲精品久久久蜜桃| 96日本xxxxxⅹxxx17| 在线成人激情视频| 成人日韩在线观看| 日本一区免费观看| 美女国产一区| 久久av无码精品人妻系列试探| 午夜日韩在线观看| 色呦呦中文字幕| 高清在线视频日韩欧美| 1204国产成人精品视频| 黄色片免费在线观看视频| 国产乱码字幕精品高清av| 91黄在线观看| 伊人222成人综合网| 成人淫片在线看| 五月开心六月丁香综合色啪| 精品久久久99| 亚洲色图制服丝袜| 国产后入清纯学生妹| 欧美日本国产在线| 国产精品极品国产中出| 成人黄色av片| 国产午夜精品一区二区| 中文精品久久久久人妻不卡| 色噜噜亚洲精品中文字幕| 亚洲一区av| 蜜桃视频一区二区在线观看| 成人午夜短视频| 国产99久久久| 亚洲一区www| **国产精品| 少妇一晚三次一区二区三区| 成人久久视频在线观看| 欧美特黄aaaaaa| 亚洲性猛交xxxxwww| 久久91视频| 日韩欧美视频免费在线观看| 不卡视频一二三四| 最近免费中文字幕大全免费版视频| 永久免费精品影视网站| 亚洲老司机网| 男女啪啪免费视频网站| 久久久精品欧美丰满| 在线观看免费中文字幕| 欧美老妇交乱视频| 亚洲自拍电影| 欧美又黄又嫩大片a级| 亚洲高清免费观看高清完整版在线观看 | 日本不卡二区高清三区| 奇米888四色在线精品| 国产精品久久久久久久精| 亚洲第一网站免费视频| 日本精品裸体写真集在线观看| 综合视频在线观看| av一区二区三区黑人| 中文字幕一区二区人妻痴汉电车| 久99久在线视频| 国产最新精品| 日韩大尺度视频| 在线免费观看日本一区| 五月婷婷视频在线观看| 欧美色图亚洲自拍| 国产精品自拍一区| 五月天激情国产综合婷婷婷| 久久久91精品国产| 亚洲精品**不卡在线播he| 午夜免费一级片| 色综合久久66| 男人添女人下部高潮视频在线观看| 欧美日韩一区二区三区免费| 国产麻豆午夜三级精品| 国产午夜无码视频在线观看| 久久久久久成人精品| 久久国产精品亚洲人一区二区三区 | 中文字幕 欧美激情| 午夜精品美女自拍福到在线|