成人性生交大片免费看视频r_亚洲综合极品香蕉久久网_在线视频免费观看一区_亚洲精品亚洲人成人网在线播放_国产精品毛片av_久久久久国产精品www_亚洲国产一区二区三区在线播_日韩一区二区三区四区区区_亚洲精品国产无套在线观_国产免费www

主頁 > 知識(shí)庫(kù) > 淺析MVP模式中V-P交互問題及案例分享

淺析MVP模式中V-P交互問題及案例分享

熱門標(biāo)簽:騰訊地圖標(biāo)注手機(jī) 百度地圖怎樣做地圖標(biāo)注 柳州電銷機(jī)器人公司 征途美甲店地圖標(biāo)注 電銷語音機(jī)器人型號(hào)參數(shù) 浦發(fā)電話機(jī)器人提醒還款 昆明語音電銷機(jī)器人價(jià)格 太原400電話上門辦理 400電話如何申請(qǐng)取消

在差不多兩年的時(shí)間內(nèi),我們項(xiàng)目組幾十來號(hào)人都撲在一個(gè)項(xiàng)目上面。這是一個(gè)基于微軟SCSF(Smart Client Software Factory)的項(xiàng)目,客戶端是墨爾本一家事業(yè)單位。前兩周,我奉命負(fù)責(zé)對(duì)某個(gè)模塊進(jìn)行Code Review工作,在此期間,發(fā)現(xiàn)了一些問題,也有了一些想法。不過,有些想法可能還不是很成熟,不能完全保證其正確性,有機(jī)會(huì)寫出來討論一下。今天來說說關(guān)于MVP的一些想法。

一、簡(jiǎn)單講講MVP是什么玩意兒
如果從層次關(guān)系來講,MVP屬于Presentation層的設(shè)計(jì)模式。對(duì)于一個(gè)UI模塊來說,它的所有功能被分割為三個(gè)部分,分別通過Model、View和Presenter來承載。Model、View和Presenter相互協(xié)作,完成對(duì)最初數(shù)據(jù)的呈現(xiàn)和對(duì)用戶操作的響應(yīng),它們具有各自的職責(zé)劃分。Model可以看成是模塊的業(yè)務(wù)邏輯和數(shù)據(jù)的提供者;View專門負(fù)責(zé)數(shù)據(jù)可視化的呈現(xiàn),和用戶交互事件的相對(duì)應(yīng)。一般地,View會(huì)實(shí)現(xiàn)一個(gè)相應(yīng)的接口;Presenter是一般充當(dāng)Model和View的紐帶。

MVP具有很多的變體,其中最為常用的一種變體成為Passive View(被動(dòng)視圖)。對(duì)于Passive View,Model、View和Presenter之間的關(guān)系如下圖所示。View和Modell之間不能直接交互,View通過Presenter與Model打交道。Presenter接受View的UI請(qǐng)求,完成簡(jiǎn)單的UI處理邏輯,并調(diào)用Model進(jìn)行業(yè)務(wù)處理,并調(diào)用View將相應(yīng)的結(jié)果反映出來。View直接依賴Presenter,但是Presenter間接依賴View,它直接依賴的是View實(shí)現(xiàn)的接口。關(guān)于MVP和Passive View基本的常識(shí)性東西,不是本篇文章論述的重點(diǎn),對(duì)此不清楚的讀者相信可以Google出很多相關(guān)的資料來,所以在這里就再多做介紹了。



二、Passive View模式的基本特征總結(jié)

Passive View,顧名思義,View是被動(dòng)的。那么主動(dòng)是誰呢?答案是Presenter。對(duì)于Presenter的主動(dòng)性,我個(gè)人是這么理解的:

•Presenter是整個(gè)MVP體系的控制中心,而不是單純的處理View請(qǐng)求的人;
•View僅僅是用戶交互請(qǐng)求的匯報(bào)者,對(duì)于響應(yīng)用戶交互相關(guān)的邏輯和流程,View不參與決策,真正的決策者是Presenter;
•View向Presenter發(fā)送用戶交互請(qǐng)求應(yīng)該采用這樣的口吻:“我現(xiàn)在將用戶交互請(qǐng)求發(fā)送給你,你看著辦,需要我的時(shí)候我會(huì)協(xié)助你”,不應(yīng)該是這樣:“我現(xiàn)在處理用戶交互請(qǐng)求了,我知道該怎么辦,但是我需要你的支持,因?yàn)閷?shí)現(xiàn)業(yè)務(wù)邏輯的Model只信任你”;
•對(duì)于綁定到View上的數(shù)據(jù),不應(yīng)該是View從Presenter上“拉”回來的,應(yīng)該是Presenter主動(dòng)“推”給View的;
•View盡可能不維護(hù)數(shù)據(jù)狀態(tài),因?yàn)槠浔旧韮H僅實(shí)現(xiàn)單純的、獨(dú)立的UI操作;Presenter才是整個(gè)體系的協(xié)調(diào)者,它根據(jù)處理用于交互的邏輯給View和Model安排工作。

三、理想與現(xiàn)實(shí)的距離

上面對(duì)Passive View MVP特征的羅列,我覺得是一種理想狀態(tài)。是在大型項(xiàng)目中,尤其是項(xiàng)目的開發(fā)者自身并不完全理解MVP原理的情況下,要整體實(shí)現(xiàn)這樣的一種理想狀態(tài)是一件很難的事情。有人可能會(huì)說,在開發(fā)人員不了解MVP的情況下要求他們用好MVP,你這不是扯淡嗎?實(shí)際上,在這里并不是說開發(fā)人員完全沒有MVP關(guān)于關(guān)注點(diǎn)分離的概念,只是對(duì)MVP中的三元角色并沒有非常清晰的界定(實(shí)際上也沒有一個(gè)明確的規(guī)范對(duì)Model、View和Presenter具體的職責(zé)范圍進(jìn)行明確的劃分),在開發(fā)的時(shí)候,會(huì)不自覺地受傳統(tǒng)編程習(xí)慣的影響,將Presenter單純地當(dāng)成是View調(diào)用Model的中介。我經(jīng)常這么說:如果以View為中心,將Presenter當(dāng)成是View和Model的中間人,這也叫MVP模式,不過這里的P不是Presenter,而是Proxy,是Model在View的代理而已。

從Passive View中Model、View和Presenter三者之間的依賴關(guān)系來看,這個(gè)模型充分地給了開發(fā)者犯這樣錯(cuò)誤的機(jī)會(huì)。注意上面的圖中View到Presenter的箭頭表明View是可以任意的調(diào)用Presenter的。開發(fā)人員完全有可能將大部分UI處理邏輯寫在View中,而Presenter僅僅對(duì)Model響應(yīng)操作的簡(jiǎn)單調(diào)用。因?yàn)樵谖襌eview的各種所謂的MVP編程方式中,有不少是這么寫的。在很多情況下,甚至不用認(rèn)真去分析具體的代碼,從View和Presenter中代碼的行數(shù)就可以看出來,因?yàn)閂iew的代碼和Presenter的代碼都不在一個(gè)數(shù)量級(jí)。

我現(xiàn)在的一個(gè)目的是提出一種編程模式,杜絕開發(fā)人員將程序?qū)懗苫赑roxy的MVP,在我看來,唯一的辦法就是盡量弱化(不可能剔除)View對(duì)Presenter的依賴。實(shí)際上,對(duì)于MVP來說,View僅僅向Presenter遞交用戶交互請(qǐng)求,僅此而已。如果我們將View對(duì)Presenter的這點(diǎn)依賴關(guān)系實(shí)現(xiàn)在框架層次中,最終開發(fā)人員的編程來說就不需要這種依賴了。那么我就可以通過一定的編程技巧使View根本無法訪問Presenter,從而避免Presenter成為Proxy的可能的。

那么,如果在不能獲得Presenter的情況下,使View能夠正常將請(qǐng)求遞交給Presenter呢?很簡(jiǎn)單,通過事件訂閱機(jī)制就可以了,雖然View不可以獲取到Presenter,但是Presenter卻可以獲取到View,讓Presenter訂閱View的相關(guān)事件就可以的。

四、讓View不再依賴Presenter的編程模型

現(xiàn)在,我們就來如果通過一種簡(jiǎn)單的編程模式就能夠讓View對(duì)Presenter的依賴完全地從中最終開發(fā)者的源代碼中移除。為此,我們需要定義一系列的基類,首先我為所有的View創(chuàng)建基類ViewBase,在這里我們直接用Form作為View,而在SCSF中View一般是通過UserControl來表示的。ViewBase定義如下,為了使View中不能調(diào)用Presenter,我將其定義成私有字段。那么,如何讓View和Presenter之間建立起關(guān)聯(lián)呢?在這里通過虛方法CreatePresenter,具體的View必須重寫該方法,不然會(huì)拋出一個(gè)NotImplementedException異常。在構(gòu)造函數(shù)中,調(diào)用該方法比用返回值為Presenter賦值。

復(fù)制代碼 代碼如下:

 using System;
 using System.ComponentModell;
 using System.Windows.Forms;
 namespace MVPDemo
 {
     public class ViewBase: Form
     {
         private object _presenter;

         public ViewBase()
         {
             _presenter = this.CreatePresenter();
         }

         protected virtual object CreatePresenter()
         {
             if (LicenseManager.CurrentContext.UsageModel == LicenseUsageModel.Designtime)
             {
                 return null;
             }
             else
             {
                 throw new NotImplementedException(string.Format("{0} must override the CreatePresenter method.", this.GetType().FullName));
             }
         }      
     }
 }

然后,我們也為所有的Presenter創(chuàng)建基類PresenterIView>,泛型類型IView表示具體View實(shí)現(xiàn)的接口。表示View的同名只讀屬性在構(gòu)造函數(shù)中賦值,賦值完成之后調(diào)用調(diào)用虛方法OnViewSet。具體的Presenter可以重寫該方法進(jìn)行對(duì)View進(jìn)行事件注冊(cè)工作。但是需要注意的是,Presenter的創(chuàng)建是在ViewBase的構(gòu)造函數(shù)中通過調(diào)用CreatePresenter方法實(shí)現(xiàn),所以執(zhí)行OnViewSet的時(shí)候,View本身還沒有完全初始化,所以在此不能對(duì)View的控件進(jìn)行操作。

復(fù)制代碼 代碼如下:

 namespace MVPDemo
 {
     public class PresenterIView>
     {
         public IView View { get; private set; }

         public Presenter(IView view)
         {
             this.View = view;
             this.OnViewSet();
         }
         protected virtual void OnViewSet()
         { }
     }
 }

由于,Presenter是通過接口的方式與View進(jìn)行交互的。在這里,由于View通過Form的形式體現(xiàn),有時(shí)候我們要通過這個(gè)接口訪問Form的一些屬性、方法和事件,需要將相應(yīng)的成員定義在接口上面,比較麻煩。此時(shí),我們可以選擇將這些成員定義在一個(gè)接口中,具體View的接口繼承該接口就可以了。在這里,我們相當(dāng)是為所有的View接口創(chuàng)建了“基接口”。作為演示,我現(xiàn)在了Form的三個(gè)事件成員定義在街口IViewBase中。

復(fù)制代碼 代碼如下:

 using System;
 using System.ComponentModell;
 namespace MVPDemo
 {
    public interface IViewBase
     {
        event EventHandler Load;
        event EventHandler Closed;
        event CancelEventHandler Closing;
     }
 }

五、實(shí)例演示

上面我通過定義基類和接口為整個(gè)編程模型搭建了一個(gè)框架,現(xiàn)在我們通過一個(gè)具體的例子來介紹該編程模型的應(yīng)用。我們采用的是一個(gè)簡(jiǎn)單的Windows Forms應(yīng)用,模擬管理客戶信息的場(chǎng)景,邏輯很簡(jiǎn)單:程序啟動(dòng)的時(shí)候顯示出所有的客戶端列表;用戶選擇某一客戶端,將響應(yīng)的信息顯示在TextBox中以供編輯;對(duì)客戶端信息進(jìn)行相應(yīng)修改之后,點(diǎn)擊OK按鈕進(jìn)行保存。整個(gè)操作界面如下圖所示:


首先,我們創(chuàng)建實(shí)體類Customer,簡(jiǎn)單起見,僅僅包含四個(gè)屬性:Id、FirstName、LastName和Address:

復(fù)制代碼 代碼如下:

 using System;
 namespace MVPDemo
 {
     public class Customer: ICloneable
     {
         public string Id
         { get; set; }

         public string FirstName
         { get; set; }

         public string LastName
         { get; set; }

         public string Address
         { get; set; }      

         object ICloneable.Clone()
         {
             return this.Clone();
         }

         public Customer Clone()
         {
             return new Customer {
                 Id          = this.Id,
                 FirstName   = this.FirstName,
                 LastName    = this.LastName,
                 Address     = this.Address
             };
         }
     }
 }

然后,為了真實(shí)模擬MVP三種角色,特意創(chuàng)建一個(gè)CustomerModel類型,實(shí)際上在真實(shí)的應(yīng)用中,并沒有單獨(dú)一個(gè)類型來表示Model。CustomerModel維護(hù)客戶列表,體統(tǒng)相關(guān)的查詢和更新操作。CustomerModel定義如下:

復(fù)制代碼 代碼如下:

 using System.Collections.Generic;
 using System.Linq;
 namespace MVPDemo
 {
     public class CustomerModel
     {
         private IListCustomer> _customers = new ListCustomer>{
             new Customer{ Id = "001", FirstName = "San", LastName = "Zhang", Address="Su zhou"},
             new Customer{ Id = "002", FirstName = "Si", LastName = "Li", Address="Shang Hai"}
         };

         public void UpdateCustomer(Customer customer)
         {
             for (int i = 0; i _customers.Count; i++)
             {
                 if (_customers[i].Id == customer.Id)
                 {
                     _customers[i] = customer;
                     break;
                 }
             }
         }

         public Customer GetCustomerById(string id)
         {
             var customers = from customer in _customers
                             where customer.Id == id
                             select customer.Clone();
             return customers.ToArrayCustomer>()[0];
         }

         public Customer[] GetAllCustomers()
         {
             var customers = from customer in _customers
                             select customer.Clone();
             return customers.ToArrayCustomer>();
         }
     }
 }

接著,我們定義View的接口ICustomerView。ICustomerView定義了兩個(gè)事件,CustomerSelected在用戶從Gird中選擇了某個(gè)條客戶記錄是觸發(fā),而CustomerSaving則在用戶完成編輯點(diǎn)擊OK按鈕視圖提交修改時(shí)觸發(fā)。ICustomerView還定義了View必須完成的三個(gè)基本操作:綁定客戶列表(ListAllCustomers);顯示單個(gè)客戶信息到TextBox(DisplayCustomerInfo);保存后清空可編輯控件(Clear)。

復(fù)制代碼 代碼如下:

 using System;
 namespace MVPDemo
 {
     public interface ICustomerView : IViewBase
     {
         event EventHandlerCustomerEventArgs> CustomerSelected;

         event EventHandlerCustomerEventArgs> CustomerSaving;

         void ListAllCustomers(Customer[] customers);

         void DisplayCustomerInfo(Customer customer);

         void Clear();
     }
 }

事件參數(shù)的類型CustomerEventArgs定義如下,兩個(gè)屬性CustomerId和Customer分別代表客戶ID和具體的客戶,它們分別用于上面提到的CustomerSelected和CustomerSaving事件。

復(fù)制代碼 代碼如下:

 using System;
 namespace MVPDemo
 {
     public class CustomerEventArgs : EventArgs
     {
         public string CustomerId
         { get; set; }

         public Customer Customer
         { get; set; }
     }
 }

而具體的Presenter定義在如下的CustomerPresenter類型中。在重寫的OnViewSet方法中注冊(cè)View的三個(gè)事件:Load事件中調(diào)用Model獲取所有客戶列表,并顯示在View的Grid上;CustomerSelected事件中通過事件參數(shù)傳遞的客戶ID調(diào)用Model獲取相應(yīng)的客戶信息,顯示在View的可編輯控件上;CustomerSaving則通過事件參數(shù)傳遞的被更新過的客戶信息,調(diào)用Model提交更新。

復(fù)制代碼 代碼如下:

 using System.Windows.Forms;

 namespace MVPDemo
 {  
     public class CustomerPresenter: PresenterICustomerView>
     {
         public CustomerModel Model
         { get; private set; }

         public CustomerPresenter(ICustomerView view)
             : base(view)
         {
             this.Model = new CustomerModel();
         }

         protected override void OnViewSet()
         {
             this.View.Load += (sender, args) =>
                 {
                     Customer[] customers = this.Model.GetAllCustomers();
                     this.View.ListAllCustomers(customers);
                     this.View.Clear();
                 };
             this.View.CustomerSelected += (sender, args) =>
                 {
                     Customer customer = this.Model.GetCustomerById(args.CustomerId);
                     this.View.DisplayCustomerInfo(customer);
                 };
             this.View.CustomerSaving += (sender, args) =>
                 {
                     this.Model.UpdateCustomer(args.Customer);
                     Customer[] customers = this.Model.GetAllCustomers();
                     this.View.ListAllCustomers(customers);
                     this.View.Clear();
                     MessageBox.Show("The customer has been successfully updated!", "Successfully Update", MessageBoxButtons.OK, MessageBoxIcon.Information);
                 };
         }      
     }
 }

對(duì)于具體的View來說,僅僅需要實(shí)現(xiàn)ICustomerView,并處理響應(yīng)控件事件即可(主要是用戶從Grid中選擇某個(gè)記錄觸發(fā)的RowHeaderMouseClick事件,以及點(diǎn)擊OK的事件)。實(shí)際上不需要View親自處理這些事件,而僅僅需要觸發(fā)相應(yīng)的事件,讓事件訂閱者(Presenter)來處理就可以了。此外還需要重寫CreatePresenter方法完成對(duì)CustomerPresenter的創(chuàng)建。CustomerView定義如下:

復(fù)制代碼 代碼如下:

 using System;
 using System.Windows.Forms;

 namespace MVPDemo
 {
     public partial class CustomerView : ViewBase, ICustomerView
     {
         public CustomerView()
         {
             InitializeComponent();           
         }

         protected override object CreatePresenter()
         {
             return new CustomerPresenter(this);
         }

         #region ICustomerView Members

         public event EventHandlerCustomerEventArgs> CustomerSelected;

         public event EventHandlerCustomerEventArgs> CustomerSaving;

         public void ListAllCustomers(Customer[] customers)
         {
             this.dataGridViewCustomers.DataSource = customers;
         }

         public void DisplayCustomerInfo(Customer customer)
         {
             this.buttonOK.Enabled = true;
             this.textBoxId.Text = customer.Id;
             this.textBox1stName.Text = customer.FirstName;
             this.textBoxLastName.Text = customer.LastName;
             this.textBoxAddress.Text = customer.Address;
         }

         public void Clear()
         {
             this.buttonOK.Enabled       = false;
             this.textBox1stName.Text    = string.Empty;
             this.textBoxLastName.Text   = string.Empty;
             this.textBoxAddress.Text    = string.Empty;
             this.textBoxId.Text         = string.Empty;
         }

         #endregion

         protected virtual void OnCustomerSelected(string customerId)
         {
             var previousId = this.textBoxId.Text.Trim();
             if (customerId == previousId)
             {
                 return;
             }
             if(null != this.CustomerSelected)
             {
                 this.CustomerSelected(this, new CustomerEventArgs{ CustomerId = customerId});
             }
         }

         protected virtual void OnCustomerSaving(Customer customer)
         {
             if(null != this.CustomerSaving)
             {
                 this.CustomerSaving(this, new CustomerEventArgs{ Customer = customer});
             }
         }

         private void dataGridViewCustomers_RowHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
         {  
             var currentRow = this.dataGridViewCustomers.Rows[e.RowIndex];
             var customerId = currentRow.Cells[0].Value.ToString();
             this.OnCustomerSelected(customerId);
         }

         private void buttonOK_Click(object sender, EventArgs e)
         {
             var customer        = new Customer();
             customer.Id         = this.textBoxId.Text.Trim();
             customer.FirstName  = this.textBox1stName.Text.Trim();
             customer.LastName   = this.textBoxLastName.Text.Trim();
             customer.Address    = this.textBoxAddress.Text.Trim();
             this.OnCustomerSaving(customer);
         }
     }
 }

您可能感興趣的文章:
  • Android開發(fā)之文件操作模式深入理解
  • android開發(fā)中使用java觀察者模式
  • ASP.NET小結(jié)之MVC, MVP, MVVM比較以及區(qū)別(一)
  • ASP.NET小結(jié)之MVC, MVP, MVVM比較以及區(qū)別(二)
  • Android開發(fā)中的MVC設(shè)計(jì)模式淺析
  • 詳解Android MVP開發(fā)模式

標(biāo)簽:德陽 張家界 天門 江蘇 蘭州 陽泉 新疆 白山

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《淺析MVP模式中V-P交互問題及案例分享》,本文關(guān)鍵詞  淺析,MVP,模式,中,V-P,交互,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《淺析MVP模式中V-P交互問題及案例分享》相關(guān)的同類信息!
  • 本頁收集關(guān)于淺析MVP模式中V-P交互問題及案例分享的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    中国女人一级毛片| 亚洲在线网站| 国产大屁股喷水视频在线观看| 久久草av在线| caoporn超碰国产公开| 欧美激情 亚洲| 久久精品国产成人精品| 精品夜色国产国偷在线| 久久影院一区二区| 日本欧美一区二区三区| 顶级网黄在线播放| 欧洲亚洲精品视频| 丁香婷婷激情网| 国产suv精品一区二区33| 国产欧美一区二区精品仙草咪| 亚洲精品tv久久久久久久久| 日韩av男人天堂| 揉丰满老妇老女人的毛片| 免费视频网站在线观看入口| www.一区| 亚洲女厕所小便bbb| 欧美大片高清| 亚洲久久在线| 亚洲精品在线观看视频| 日本一本a高清免费不卡| 性欧美18xxxhd| 欧美午夜性生活| 日本小视频网站| 视频一区二区三区国产| 国产精品69久久久久水密桃| 视频在线一区二区| 中文字幕日韩免费| 韩日电影在线观看| 欧洲美熟女乱又伦| 国产精品吊钟奶在线| 欧美一区91| 特级西西444www大胆免费看| 久久九九国产精品怡红院| 国产老头老太做爰视频| 在线观看亚洲精品福利片| 亚洲精品国产精品国自产网站按摩| www..com久久爱| 日韩精品伦理第一区| 男人日女人网站| 国产aa精品| 一区二区三区在线视频看| 91成人午夜| 蜜臀精品一区二区| 欧美视频中文字幕在线| 久久伊人精品视频| 精品欧美一区二区久久| jizz在线免费播放| caoporm超碰国产精品| 久久这里只有精品视频首页| 免费黄色一级网站| 香蕉视频黄在线观看| www.久久精品.com| 国产欧美va欧美va香蕉在线| 国内精品久久久久国产| 国产精品久久网| 97视频在线观看播放| 国产精品一区二区三区在线观| 欧美三级午夜理伦三级中视频| 欧美一区二区大片| 91精品国产91久久久久久三级| 色先锋最新资源| 欧美成人视屏| 99精品国产福利在线观看免费| 亚洲大胆人体视频| 91美女主播在线视频| 国产真人真事毛片视频| 成人国产亚洲欧美成人综合网| 草民福利视频| 男人的天堂成人在线| 丰满少妇一区二区三区| 欧美不卡1区2区3区| 亚洲综合色在线| 成人羞羞视频在线看网址| 国产精品免费观看久久| 国产av麻豆mag剧集| 欧美伦理91| 久久九九亚洲综合| 天天av综合| 理论片播放午夜国外| 亚洲爱爱综合网| 欧美成人影院在线播放| 国产天堂av在线| 超碰在线观看免费版| 国产精品污视频| 国产乱码字幕精品高清av| 久久婷婷五月综合| 午夜一区二区三区在线观看| 天天干天天干天天干| 99视频精品全部免费看| 97精品国产97久久久久久久久久久久| 国产欧美一区二区三区在线看蜜臀| 在线精品免费视| 嫩草影院入口一二三免费| 天天摸天天碰天天爽天天弄| 欧美不卡福利| 日本精品在线观看| 黄色春季福利在线看| 日韩精品一区二区三区免费观看| 激情校园亚洲图片| 农村老熟妇乱子伦视频| 欧美一级特黄aaa| 欧美福利网址| 天天免费亚洲黑人免费| 999久久久亚洲| 亚洲经典一区| 欧美老女人在线| 美女福利视频在线| 国产在线视频在线观看| 岛国精品一区二区三区| 免费永久网站黄欧美| 在线黄色的网站| 97久久精品人搡人人玩| 99在线|亚洲一区二区| 亚洲美女15p| 91亚洲精品久久久蜜桃| 亚洲国产免费av| 青春草在线视频免费观看| 免费看av成人| 青春草在线视频免费观看| 亚洲第一区第二区第三区| 中文字幕在线观看视频免费| 无码人妻精品一区二区蜜桃百度| 99视频一区| www.91在线播放| 精品无码一区二区三区| 性做久久久久久久免费看| 99国产高清| 日本成人黄色网| 亚洲福利电影网| 先锋资源中文字幕| 国产曰肥老太婆无遮挡| 国产精品二区影院| 美女又黄又免费| 日韩成人激情| 91人人爽人人爽人人精88v| 波多野结衣中文字幕在线播放| 日本精品一区| 久久综合99| 国产最新精品精品你懂的| 亚洲色图图片专区| www.夜夜操| 99麻豆久久久国产精品免费优播| 免费一区二区三区在线观看| 国产精品免费99久久久| 国产va免费精品高清在线| 99热在线播放| 一区二区免费在线观看| 久久国产精品久久精品| 亚洲免费专区| 在线观看国产精品入口男同| 久久久久久亚洲中文字幕无码| 日韩欧美在线免费观看视频| 在线日韩精品视频| 午夜一区二区三区| 欧美性生活一级片| 日韩av首页| 黄色三级高清在线播放| 亚洲欧洲国产精品一区| 三区在线观看| 亚洲免费精品视频| 久久综合免费视频| 成人综合日日夜夜| 日韩中文字幕组| 日韩欧美一区二区三区免费观看| 二区在线播放| 日韩国产欧美视频| 无码人妻丰满熟妇区五十路百度| 国产综合久久久久久久久久久久| 亚洲国产欧美国产综合一区| 在线免费观看日本一区| 91精品在线观| 色综合一区二区| 欧洲精品二区| 久久免费激情视频| 色妞在线综合亚洲欧美| 欧美精品国产精品日韩精品| 久久99精品久久久久久青青91| 日韩电影精品| 伦理中文字幕亚洲| 日本久久久久久久久久久| 7777奇米亚洲综合久久| zzijzzij亚洲日本少妇熟睡| 日韩欧美国产精品| 日韩毛片无码永久免费看| 激情四射综合网| 7799精品视频天天看| 黄网在线免费看| 欧美三级乱人伦电影| 亚洲成人最新网站| 成人小电影网站| 黄色三级电影网| 99国产精品一区二区| 99久久免费看精品国产一区| jizzjizzjizz中国免费| 国产精品青草久久久久福利99| 日韩男人的天堂| 97精品国产97久久久久久春色| 久久久久免费精品国产| 成网站在线观看人免费| 草裙成人精品一区二区三区| h网站视频在线观看| 国产精品久久色| 色综合欧美在线视频区| 日韩欧美色综合网站| 欧美高清视频www夜色资源网| 日本一区高清在线视频| 成人小视频在线观看| 欧美系列一区二区| 色涩视频在线观看| 香蕉加勒比综合久久| 成人黄色在线网站| 久久品道一品道久久精品| 亚洲精品九九| 亚洲伊人一本大道中文字幕| 国产欧美日韩91| 91麻豆精品成人一区二区| 大色综合视频网站在线播放| 欧美日韩精品免费观看视完整| 免费成人深夜夜行p站| 2021天堂中文幕一二区在线观| 免费成人av电影| 国产精品白嫩白嫩大学美女| 国产无色aaa| aa片在线观看视频在线播放| 亚洲男同gay网站| 亚洲无线看天堂av| 瑟瑟视频在线观看| 亚洲欧美综合一区二区| 久久久爽爽爽美女图片| 黄色在线播放网站| 中文字幕日韩精品在线观看| 色欧美片视频在线观看在线视频| 亚洲娇小xxxx欧美娇小| 熟妇人妻久久中文字幕| 四虎永久在线精品无码视频| 欧美在线精品一区二区三区| 先锋影音av资源站| 欧美精品18videos性欧美| av一区二区在线观看| 青少年xxxxx性开放hg| 69久久精品无码一区二区| 日韩一区二区三区免费视频| 无码国产精品久久一区免费| 在线观看视频免费一区二区三区| 992kp快乐看片永久免费网址| 懂色av懂色av粉嫩av| 精品国产免费av| 国产亚洲激情视频在线| 男人的天堂亚洲在线| 亚洲乱码国产乱码精品精的特点| 91丝袜美腿美女视频网站| 五月婷婷丁香综合网| 91麻豆精品国产无毒不卡在线观看| 欧美1—12sexvideos| 亚洲国产尤物| 中文字幕天堂网| 91情侣偷在线精品国产| 亚洲精品视频中文字幕| 国产又大又黑又粗免费视频| 欧美一区二区久久| 91色精品视频在线| 黄色软件在线| 国产在线日韩欧美| 日韩综合一区| 欧美性高潮在线| 97精品国产97久久久久久免费| 国产97在线播放| 欧美在线播放一区| 亚洲综合视频网| 91精品国产综合久久小美女| 亚洲小说区图片区| 丝袜国产日韩另类美女| 国产激情久久久久久熟女老人av| 中文字幕日本人妻久久久免费| 大地资源二中文在线影视观看| 国产精品三上| 中文字幕资源在线观看| 欧美v国产在线一区二区三区| 免费一区二区视频| 国产精品中文字幕亚洲欧美| 亚洲国产另类精品专区| 欧美亚洲综合另类| 91精品一区国产高清在线gif| 人妻av无码一区二区三区| 亚洲国产一区在线观看| 国内精品久久久久久久影视蜜臀| 国产一精品一av一免费爽爽| 久久久久久久久久久久久女国产乱| 国产精品久久久久久久龚玥菲| 国产激情视频在线看| 日本不卡一二三区黄网| 另类ts人妖一区二区三区| 午夜精品免费在线观看| 中文无码精品一区二区三区| 国产白浆在线免费观看| 亚洲国产剧情在线观看| 欧美9999| 中文字幕在线高清| 久久伊人精品天天| 99精品视频国产| 亚洲成人aaa| 欧美日韩xx| www.成年人视频| 国产日韩欧美高清| 国产美女高潮视频| 污视频网站在线免费观看| 欧美伊人精品成人久久综合97| 成人影院免费观看| 手机看片国产精品| 国产三级精品三级在线观看国产| 亚洲欧美aaa| 久久成人综合视频| 在线观看日韩专区| 美女爆乳18禁www久久久久久| 亚洲v日韩v欧美v综合| 日韩一区二区三区在线观看| 欧美在线3区| 国产高清在线免费观看| 欧美成人aaa片一区国产精品| 亚洲综合国产| 麻豆电影在线| 日本伦理一区二区| 国产精品欧美一区喷水|