一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

基于AngularJS的企業(yè)軟件前端架構(gòu)

 綠野星蹤 2014-05-15

這篇是我參加QCon北京2014的演講內(nèi)容:

提綱:

企業(yè)應(yīng)用在軟件行業(yè)中占有很大的比重,而這類軟件多數(shù)現(xiàn)在也都采用B/S的模式開發(fā),在這個日新月異的時代,它們的前端開發(fā)技術(shù)找到了什么改進點呢?

B/S企業(yè)軟件前端開發(fā)模式大體上與桌面軟件類似,都是偏重量級的,在前端可能會有較多的業(yè)務(wù)邏輯,這些業(yè)務(wù)邏輯如何被合理模塊化,與界面分離,以便測試,成為這個領(lǐng)域的一個重要挑戰(zhàn)。另一方面,由于企業(yè)應(yīng)用的界面相對規(guī)整,偏重的是數(shù)據(jù)存取,沒有太多花哨的東西,所以常見的界面控件也是可枚舉的,如何讓開發(fā)界面的工作能更快完成,甚至由不擅長編寫代碼的業(yè)務(wù)設(shè)計人員來做,與界面原型的工作合二為一,能提高不少開發(fā)效率。

在AngularJS等MV*框架出現(xiàn)之后,給這個領(lǐng)域帶來一些契機,架構(gòu)師們能夠有機會去重新規(guī)劃前端的架構(gòu),甚至是開發(fā)流程,從而讓整個軟件的生產(chǎn)更為高效。

本文將探討它給這個領(lǐng)域帶來的變化。

正文:

企業(yè)應(yīng)用前端的特點

企業(yè)應(yīng)用系統(tǒng)是一種很常見的軟件系統(tǒng),這類系統(tǒng)的特點是面向某個行業(yè),功能較復(fù)雜,對界面的要求一般是整齊,不追求花哨。這類系統(tǒng)通常有C/S和B/S兩個流派,其中的B/S方式因為部署和集成的便利,使用得較為普遍。

同樣是在瀏覽器中做東西,寫企業(yè)應(yīng)用和網(wǎng)站的差別也很明顯。企業(yè)應(yīng)用的業(yè)務(wù)邏輯較重,前端有一定的厚重性,但是對效果并不追求很多,主要是各類控件的使用,表單的存取值等等。

企業(yè)應(yīng)用產(chǎn)品的一些特點如下:

  • 獨占模式——一般用戶使用互聯(lián)網(wǎng)產(chǎn)品,都是片段時間使用,比如購物或者閱讀,做完之后就刷新或者關(guān)閉瀏覽器了,而企業(yè)應(yīng)用往往是工作的全部,從早上上班開始打開,到下班才關(guān)掉,一天絕大部分工作都在上面完成,比如一個呼叫中心的操作員。
  • 重業(yè)務(wù),輕視覺——企業(yè)應(yīng)用對視覺的追求是比較低的,一般不會要求花哨效果,以業(yè)務(wù)操作的流暢性為第一目標(biāo)。
  • 界面規(guī)整,單一模式——企業(yè)應(yīng)用的界面布局相對有模式可循,可以用很少的場景來窮舉,界面橫平豎直,比較規(guī)整,使用到的控件元素也是可窮舉的,基本沒有什么特效。
  • 鍵盤操作——由于企業(yè)應(yīng)用的用戶都相對比較專業(yè),在上崗之前需要經(jīng)過統(tǒng)一培訓(xùn),而且每個用戶使用的頻度較高,很多時候他們會用盡量快捷的方式來做操作,比如鍵盤,這一點在互聯(lián)網(wǎng)產(chǎn)品中比較少見。所以,有時候大家為了追求好看,把系統(tǒng)原生的select用div來替換,在這種情況下反而增加了用戶的麻煩。
  • 邏輯復(fù)雜——我之前所在的行業(yè)中,業(yè)務(wù)邏輯很復(fù)雜,前端可能會需要寫很多復(fù)雜的邏輯,JS代碼大部分是在處理邏輯,而不是界面交互。
  • 加載速度的側(cè)重不同——互聯(lián)網(wǎng)產(chǎn)品往往很重視首屏優(yōu)化,但是其策略可能與企業(yè)應(yīng)用不同。比如說,3個200k的模塊,在網(wǎng)站型產(chǎn)品中可能優(yōu)化成一個100k加三個150k的模塊,但在企業(yè)應(yīng)用中,很可能優(yōu)化成一個400k加三個50k的模塊。為什么會這樣呢?因為內(nèi)容型的網(wǎng)站講究的優(yōu)化策略是分攤,如果首次加載太慢,會很影響用戶的信心,但企業(yè)應(yīng)用用戶的容忍度是較高的,他并不在乎剛打開的時候慢一些,因為打開了之后就要用一天,對于之后每步操作的模塊加載速度倒是要求很高。另外,對于內(nèi)存泄露的處理,也要求得比較高一些。整個這些策略,其實是來源于C/S系統(tǒng)的影響。
  • 瀏覽器版本相對寬松——很多時候提到企業(yè)應(yīng)用,大家的想法就是低端,IE6,但其實這個的原因是客戶只購買軟件,運維一般自己做,每年不會有很多持續(xù)的投入來改進,所以導(dǎo)致很多老系統(tǒng)不能持續(xù)升級。軟件廠商其實反倒可以用更激進的策略去升級瀏覽器,用戶對這個的接受度還是比較高的,使用系統(tǒng)的群體也是比互聯(lián)網(wǎng)用戶小很多的,拋棄老舊瀏覽器的事情也確實可以干,比如我就見過幾年前某電信營業(yè)系統(tǒng)預(yù)裝的都是Firefox。

企業(yè)應(yīng)用常見的前端框架

在開發(fā)B/S企業(yè)應(yīng)用前端的人群中,有很大一部分群體選擇了服務(wù)端的組件化方式,比如JSF之類,它的弊端是與異構(gòu)服務(wù)端的第三方系統(tǒng)集成比較麻煩。也有不少人使用Bindows和ExtJS這樣的框架,最近的KendoUI也是個不錯的選擇。

每種類型選一個有代表性的來說說:

  • HTC 在瀏覽器端擴展標(biāo)簽——早期有些團隊采用的方式,一般會跟XMLHTTP等結(jié)合使用,易于使用,界面代碼整潔,但已被主流瀏覽器拋棄。
  • JSF等 在服務(wù)端生成界面——以后端為主的架構(gòu)師最推崇的方式,受Struts的MVC模型影響很深,弱化了前端,使得前端蛻化為后端的一種附屬。
  • GWT 編譯階段生成界面——寫其他語言來生成HTML和JS,一般會依賴于一種前端UI庫。這種方式也比較受后端架構(gòu)師喜歡,因為他們覺得寫JS很頭疼,寧可寫Java。
  • ExtJS 用JS封裝界面組件,干脆就不要HTML了——這是另外一種極端,從Bindows開始,使用純邏輯代碼來描述界面,走著跟Java Swing一樣的道路,也有不少人喜歡。但這種方式在沒有好用的界面設(shè)計器的情況下非常痛苦。
  • Flex等 脫離HTML體系,另辟蹊徑——這條路其實是對Java Applet的一種延續(xù),好處是可以不受HTML體系的制約,獨立發(fā)展,所以其實這些體系在企業(yè)應(yīng)用領(lǐng)域的成熟度遠超HTML體系。

曾經(jīng)的企業(yè)B/S應(yīng)用幾件寶

有一段時間,我們幾乎只有IE6,所以那個時候的前端開發(fā)人員很快樂,沒有兼容的壓力。那時候,我們?nèi)绾螛?gòu)建前端應(yīng)用呢?參見這里的分享。

  • HTC——這是最好用的聲明控件的方式。
  • XMLHTTP——盡管還沒有AJAX的概念,但我們已經(jīng)可以用它做前后端分離的傳輸機制了。
  • VML——在IE里面畫矢量圖,不使用插件,有其他選擇嗎?
  • XSLT——把XML數(shù)據(jù)轉(zhuǎn)換成HTML,跟現(xiàn)在的前端模板像嗎?
  • popup——創(chuàng)建右鍵菜單最好的方式。

具體實例請參考用這些技術(shù)構(gòu)建的一個典型企業(yè)應(yīng)用

單頁應(yīng)用和前端分層

當(dāng)時這些系統(tǒng)的構(gòu)建方式也可以算單頁應(yīng)用,我們用iframe來集成菜單,每個菜單有自己獨立的功能,整個主界面是始終不會刷新的。

時光飛逝,這些年,前端有了什么本質(zhì)的改變,產(chǎn)生了翻天覆地的變化嗎?有時候我們回顧一下,卻發(fā)現(xiàn)多數(shù)都是在增加完善一些細節(jié),真正有顛覆性的有比如以RequireJS和SeaJS為代表的模塊定義和加載庫,npm這樣的包管理器,grunt,gulp,百度fis這樣的集成開發(fā)模式。為什么它們算是本質(zhì)改進呢?因為這些標(biāo)志著前端開發(fā)從粗放的模式,逐漸變化到精確控制的形態(tài)。比如我們再也不能不管代碼的依賴關(guān)系,也不能一打開界面就不分青紅皂白把所有可能要用到的代碼都立刻加載過來,那個時代已經(jīng)過去了,從任何角度講,現(xiàn)代的前端開發(fā)都在精細化,從代碼的可控,到界面體驗的精細優(yōu)化,到整個團隊甚至公司甚至互聯(lián)網(wǎng)上的組件共享,以及前端團隊協(xié)作流程的改進,這已經(jīng)是一個很成規(guī)模的產(chǎn)業(yè)了。

我們把眼光放到2013年,在這一年里最火的前端技術(shù)莫過于NodeJS和AngularJS,前者給我們帶來的是一種開發(fā)方式的改變,后者是一種典型的前端分層方案。Angular是前端MV*框架的一個流派,用過的人都會覺得很爽。它爽在什么地方呢?因為它幫我們做的事情太多了,一個雙向綁定,無所不包,凡是存取值相關(guān)的操作,基本都不用自己寫代碼。在企業(yè)應(yīng)用前端功能里,表單的存取值和校驗占據(jù)了很大的比例,這些事都不用干了,那簡直太好了。如果就因為這個用Angular,那還有些早。有一些第三方代碼被稱為庫,另外一些稱為框架,Angular是框架而不是庫??蚣艿暮x是,有更強的約束性,并非作為輔助功能來提供的。

先看一下企業(yè)應(yīng)用的通常形態(tài)吧,會有一個可配置的菜單,然后多半會采用MDI的形式,能打開多個業(yè)務(wù)功能,用選項卡的形式展示起來,可以隨時切換操作。每個人每天常用的功能是可以窮舉的,他進入系統(tǒng)之后,一般要用到下班才關(guān)掉。所以這種系統(tǒng)非常適合做成單頁應(yīng)用,開始的時候加載一個總體框架,每點擊一個菜單,就加載這個菜單對應(yīng)的功能模塊,放在一個新的選項卡或者別的什么地方展示出來。

在早期做這種系統(tǒng)的時候,一般都會用iframe來集成菜單,這種方式很方便,但是每個菜單頁都要載入共同的框架文件,初始化一個環(huán)境,數(shù)據(jù)之間也不能精確共用。所以現(xiàn)在我們做企業(yè)信息系統(tǒng),不再適合用iframe來集成菜單,所有菜單的業(yè)務(wù)代碼,會在同一個頁面的作用域中共存。這在某些方面是便利,比如數(shù)據(jù)的共享,一個選擇全國城市的下拉框,在多個功能中都存在,意味著這些城市的數(shù)據(jù)我們可以只加載一次。但從另外一個角度來說,也是一種挑戰(zhàn),因為數(shù)據(jù)之間產(chǎn)生干擾的可能性大大增加了。

我們回顧一下在傳統(tǒng)的客戶端開發(fā)中是怎么做的,早在經(jīng)典的《設(shè)計模式》一書中,就提到了MVC模式,這是一種典型的分層模式。長期以來,在Web開發(fā)人員心中的MVC,指的都是Struts框架的那張圖,但我們單頁應(yīng)用中的MVC,其實更接近最原始的《設(shè)計模式》書中概念。所以我們要在前端分層,而不僅僅把整個前端都推到視圖層。

做單頁應(yīng)用,前端不分層是很難辦的,當(dāng)規(guī)模擴大的時候,很難處理其中一些隱患。分層更重要的好處是能夠從全盤考慮一些東西,比如說數(shù)據(jù)的共享。跨模塊的數(shù)據(jù)共享是一個比較復(fù)雜的話題,搞得不好就會導(dǎo)致不一致的情況,如果考慮到在分層的情況下,把各種數(shù)據(jù)來源都統(tǒng)一維護,就好辦多了。

所以,以AngularJS為代表的前端MV*框架最重要的工作就是做了這些對于分層的指導(dǎo)和約束性工作,在此基礎(chǔ)上,我們可以進一步優(yōu)化單頁應(yīng)用這類產(chǎn)品。

前端的自定義標(biāo)簽體系

構(gòu)建一個大型企業(yè)應(yīng)用,最重要的是建立整套組件體系。一般針對某行業(yè)的軟件,長期下來都會有很多固定的模式,可以提煉成組件和規(guī)則,從前端來看,體現(xiàn)為控件庫和前端邏輯??丶爝@個是老生常談,在很多框架里都有這個概念,但各自對應(yīng)的機制是不同的。

從寫一個界面的角度來講,最為便利的方式是基于標(biāo)簽的聲明式代碼,比如我們常見的HTML,還有微軟的XAML,F(xiàn)lex中的MXML等,都很直接,設(shè)想一下在沒有可視化IDE的情況用類似Java Swing和微軟WinForm這樣的方式編寫界面,毫無疑問寫XML的方式更易被接受。所以,我們可以得出初步的結(jié)論,界面的部分應(yīng)該寫標(biāo)簽。

很遺憾,HTML自帶的標(biāo)簽是不足的,它有基本表單輸入控件,但是缺乏DataGrid,Tree之類更富有表現(xiàn)性的控件。所以絕大多數(shù)界面庫,都采用某種使用JavaScript的方式來編寫這類控件,比如:

<div id="tabs">
  <ul>
    <li><a href="#tabs-1">Nunc tincidunt</a></li>
    <li><a href="#tabs-2">Proin dolor</a></li>
    <li><a href="#tabs-3">Aenean lacinia</a></li>
  </ul>
  <div id="tabs-1">
  </div>
  <div id="tabs-2">
  </div>
  <div id="tabs-3">
  </div>
</div>
$(function() {
    $( "#tabs" ).tabs();
});

如果這樣,這些復(fù)雜控件就都要通過JavaScript來創(chuàng)建和渲染了,這與我們剛才提到的原則是違背的。那我們尋找的是什么呢,是一種能擴展已有HTML體系的東西。在早期,IE瀏覽器中有HTC,可以通過引入命名空間來聲明組件,現(xiàn)在的標(biāo)準瀏覽器中又引入了Web Components,在Polymer這個框架中可以看到更多的細節(jié)。說到底,這類方式要做些什么事情呢?

  • 隔離組件的實現(xiàn),讓使用變得簡單
  • 支持自行擴展新的組件
  • 作一些作用域上的隔離,比如Web Components里面,style標(biāo)簽上可以加作用域,表示這個樣式只生效于組件內(nèi)部

從另外一個角度講,為什么我們非要這么做不可?最大好處來自哪里?對于大型項目而言,管理成本和變更成本都是需要認真考慮的。如果一個組件,需要在DOM中聲明一個節(jié)點, 然后再用一個js去獲取DOM,把DOM渲染出來,再填充數(shù)據(jù)的話,這個過程的管理成本是很大的,因為HTML和JS這兩個部分丟了一個都會有問題,無論在什么時候,維護一個文件總是比維護多個文件要強的,我們看HTC那種方式,為什么它的使用成本很低,因為它可以把控件自身的DOM、邏輯、樣式全部寫在自己內(nèi)部,整個一個文件被人引用就可以了。在現(xiàn)在這個階段不存在這么好用的技術(shù)了,只能退而求其次。

所以,在這個點上,Angular帶來的好處是可擴展的標(biāo)簽體系,這也就是標(biāo)簽的語義化。Angular的主打功能之一是指令,使用這種方式,可以很容易擴展標(biāo)簽或者屬性。比如,業(yè)務(wù)開發(fā)人員可以直接寫:

<panel>
     <tree data="{{data}}"></tree>
</panel>

這樣多么直觀,而且可以跟原有的HTML代碼一起編寫,不造成任何負擔(dān)。語義化的標(biāo)簽是快速編寫界面的不二法門。

業(yè)務(wù)邏輯

有了語義化標(biāo)簽之后,如果我們只寫界面不寫邏輯,那也夠了,但現(xiàn)實往往沒有這么美好,我們還要來考慮一下業(yè)務(wù)邏輯怎么辦。

企業(yè)應(yīng)用一般都是面向某行業(yè)的,在這個行業(yè)內(nèi)部,會有一些約定俗成的業(yè)務(wù)模型和流程,這些東西如何復(fù)用,一直是一個難題。以往的做法,會把這些東西都放在服務(wù)端,用類似Java這樣的語言來實現(xiàn)業(yè)務(wù)元素、業(yè)務(wù)規(guī)則和業(yè)務(wù)流程的管理。這種做法所帶來的一個缺點就是對界面層的忽視,因為他只把界面層當(dāng)作展示,對其中可能出現(xiàn)的大量JavaScript邏輯感到無所適從。很多從事這一領(lǐng)域的架構(gòu)師不認同界面層的厚度,他們認為這一層只應(yīng)當(dāng)是很薄的,純展示相關(guān)的,但在這個時代,已經(jīng)不存在真正輕量級的界面了。

前面提到,我們在前端作分層,把展現(xiàn)層跟業(yè)務(wù)邏輯層完全隔離,帶來的好處就是邏輯層不存在對DOM的操作,只有純粹的邏輯和遠程調(diào)用,這么一來,這一層的東西都可以很容易做測試。對于一個大型產(chǎn)品來說,持續(xù)集成是很有必要的,自動化測試是持續(xù)集成中不可缺少的一環(huán)。如果不做分層,這個測試可能就比較難做,現(xiàn)在我們能把容易的先做掉,而且純邏輯的代碼,還可以用更快的方式來測試。

之前我們做前端的單元測試,都需要把代碼加載到瀏覽器來執(zhí)行,或者自行封裝一些“無頭瀏覽器”,也就是不打開實際的展示,模擬這個測試過程。這個過程相對來說還是有些慢,因為它還有加載的這個網(wǎng)絡(luò)傳輸?shù)倪^程,如果我們能在服務(wù)端做這個事情呢?我們看到,最近很火的NodeJS,它從很多方面給了前端工程師一個機會,去更多地把控整個開發(fā)流程,在我們這個場景下,如果能把針對前端邏輯的單元測試都放在node里做,那效率就會更高。

二次開發(fā)平臺

我們來看看,有了這么一套分層機制,又有了界面標(biāo)簽庫之后,該做些什么呢?做企業(yè)軟件的公司,有不少會做二次開發(fā)平臺,這個平臺的目標(biāo)是整合一些已有的行業(yè)組件,讓業(yè)務(wù)開發(fā)人員甚至是不懂技術(shù)的業(yè)務(wù)人員通過簡單的拖拉、配置的形式,組合生成新的業(yè)務(wù)功能。

從界面的角度看,拖拽生成很容易,很多界面原型工具都可以做,但要如何整合數(shù)據(jù)和業(yè)務(wù)?因為你要生成的這個功能,是實實在在要拿去用,不是有個樣子看就可以,所以要能跟真實數(shù)據(jù)結(jié)合起來。 但這事情談何容易!就比如說,界面上有一個選擇所屬行業(yè)的下拉框,里面數(shù)據(jù)是配置出來的,對這個數(shù)據(jù)的查詢操作在后端,作為一個查詢服務(wù)或者是業(yè)務(wù)對象管理起來,有些傳統(tǒng)的方式可能是在后端作這個關(guān)聯(lián),Angular框架可以把這個事情推到前端來。相比Backbone這樣的框架來說,Angular由于有雙向綁定,這個過程會變得特別省事。一個界面片段想要和數(shù)據(jù)關(guān)聯(lián)起來,要做的事情就是各種屬性的設(shè)置,所以動態(tài)加載和動態(tài)綁定都會比較容易。

比如:

partial.html

<ul>
     <li ng-repeat="item in items">{{item.name}}</li>
</ul>

main.html

...
<div ng-include="'partial.html'" ng-controller="CtrlA"></div>
...

a.js

function CtrlA($scope) {
    $scope.items = [{name:"Tom"}, {name:"Jerry"}];
}

b.js

function CtrlB($scope) {
    $scope.items = [{name:"Donald"}, {name:"Micky"}];
}

在上面的例子里,這個列表顯示什么,完全取決于ng-controller="CtrlA"這句,如果我們把這句搞成配置的,就很容易把數(shù)據(jù)源換成另外一個CtrlB,甚至說,即使在同一版本上做項目化,引入另外一個包含CtrlA其他版本的js文件,也基本無需更改其他代碼,這就達到了二次開發(fā)的一個目的:盡可能以配置而不是編碼去新增、維護新功能。

移動開發(fā)

現(xiàn)在的企業(yè)軟件已經(jīng)不能只考慮PC的瀏覽器了,很多客戶都會有移動辦公的需求。響應(yīng)式設(shè)計是一種常見的解決方案,但是在企業(yè)應(yīng)用領(lǐng)域,想要把復(fù)雜的業(yè)務(wù)功能設(shè)計成響應(yīng)式界面的代價太大了,況且界面設(shè)計本身就是開發(fā)企業(yè)軟件的這些公司的短板,所以我們的比較簡單的辦法是對PC和移動終端單獨設(shè)計界面,這樣就有了一個問題了,這兩種界面的業(yè)務(wù)邏輯并沒有差別,如果我們要維護兩套代碼,代價是非常大的,能有什么辦法共用一些東西呢?

如果不采用分層的形式,那這個很麻煩,我們注意到兩種系統(tǒng)的差異只在UI層,如果我們用分層的模式,可以共用UI層以外的東西。具體到Angular里面來說,比如service,factory,甚至controller都是可以共用的,只有directive和HTML模板隨設(shè)備產(chǎn)生差異就可以了。

之前我們很少看到有基于Angular的移動端開發(fā)框架,但現(xiàn)在有了,比如Ionic,使用這樣的框架,可以直接引用已有的業(yè)務(wù)邏輯代碼,只在展示上作一些調(diào)整。這么做有很多好處,同時也對代碼的架構(gòu)水準有一定要求,需要把業(yè)務(wù)邏輯跟界面展示完全切割開。

這樣帶來的好處也是很明顯的,獨立的業(yè)務(wù)邏輯,因為它不依賴于界面了,所以很容易控制,做單元測試,集成測試,打樁等等,總之它是純邏輯的東西,在后端可以用什么方式保證代碼質(zhì)量,在前端的業(yè)務(wù)邏輯也一樣可以用,業(yè)務(wù)邏輯可以因此而清晰穩(wěn)定。對于企業(yè)應(yīng)用而言,這么做可以極大程度地復(fù)用以往的業(yè)務(wù)邏輯,只在負責(zé)最終展示的代碼部分作差異化。

工程化

上面這些技術(shù)性的問題都解決了,剩下的都是規(guī)模帶來的邊際效應(yīng),這需要我們從工程化角度去考慮很多問題:

  • 某個JS模塊被修改,如何得知會影響誰?
  • 某個界面片段被調(diào)整,會影響什么界面?
  • 如何最小化發(fā)布?
  • 如何一鍵測試、打包、壓縮?

這些話題,篇幅所限,不在本文中敘述,可以查看我另外的關(guān)于Web應(yīng)用組件化的文章。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    午夜国产福利在线播放| 日韩中文字幕视频在线高清版| 老熟妇乱视频一区二区| 成人国产一区二区三区精品麻豆| 精品日韩中文字幕视频在线| 久久热中文字幕在线视频| 日本人妻中出在线观看| 精品少妇人妻av一区二区蜜桃| 字幕日本欧美一区二区| 懂色一区二区三区四区| 久久碰国产一区二区三区| 亚洲精品中文字幕在线视频| 噜噜中文字幕一区二区| 国产一区二区三区四区中文| 日韩美成人免费在线视频| 99视频精品免费视频播放| 日本欧美在线一区二区三区| 老司机精品线观看86| 老富婆找帅哥按摩抠逼视频| 69老司机精品视频在线观看| 中文精品人妻一区二区| 国产精品亚洲综合天堂夜夜| 精品一区二区三区乱码中文| 国产又粗又猛又爽又黄的文字| 国产亚洲精品香蕉视频播放| 日本不卡一本二本三区| 欧美激情区一区二区三区| 很黄很污在线免费观看| 好吊日在线视频免费观看| 国产又粗又猛又爽又黄的文字| 精品少妇人妻一区二区三区| 亚洲一区二区三区三区| 日本一二三区不卡免费| 久久热这里只有精品视频| 日本少妇三级三级三级| 在线观看免费无遮挡大尺度视频| 国产又色又爽又黄又免费| 在线日韩中文字幕一区| 国产精品伦一区二区三区在线| 欧美精品亚洲精品日韩专区| 精品久久少妇激情视频|