中文字幕日韩一区二区_国产一区二区av_国产毛片av_久久久久国产一区_色婷婷电影_国产一区二区精品

面向對象設計的設計原則

  在設計面向對象的程序的時,模式不是一定要套的,但是有一些原則最好是遵守。這些原則已知的有七個,包括:開閉原則、里氏代換原則、依賴倒轉原則、合成/聚合復用原則、迪米特法則、接口隔離原則,單一職責原則。

  原則簡介

  其中Robert C. Martin引入了SOLID的說法,包括了其中的五個原則。另外兩個,這里把他們算成額外的兩個規(guī)則。具體如下。

  S . Single Responsibility Principle - SRP
  An object should have only a single responsibility.

  O . Open-Closed Principle - OCP
  Software entities should be opened for extension, but closed for modification.

  L . Liskvo Substitution Principle - LSP
  If S is a subtype of T, the objects of T in a program may be replaced by objects of Type S.

  I . Interface Segregation Principle - ISP
  many client specific interfaces are better than one general purpose interface.

  D . Dependency Inversion Principle - DIP
  Depend upon abstractions. Do not depend upon concretions.
  Program to an interface, not an implementation.

  Ex1 . Law of Demeter - LoD
    -- Principle of Least Knowledge
  A given object should assume as little as possible about the structure or properties of anything else.

  Ex2 . Composite/Aggregate Reuse Principle - CARP
  Use most composition and aggregation, less inheritance.

  按照個人理解,把這七個原則分成了以下兩個部分。

  Design Method: SRP ISP DIP CARP
  Design Goal:   OCP LSP LoD

  各規(guī)則詳細(本部分為轉載)

  正如牛頓三大定律在經(jīng)典力學中的位置一樣,“開-閉”原則(Open-Closed Principle)是面向對象的可復用設計(Object Oriented Design或OOD)的基石。其他設計原則(里氏代換原則、依賴倒轉原則、合成/聚合復用原則、迪米特法則、接口隔離原則)是實現(xiàn)“開-閉”原則的手段和工具。

  一、“開- 閉”原則(Open-Closed Principle,OCP 

  1.1 “開- 閉” 原則的定義及優(yōu)點

  1)定義:一個軟件實體應當對擴展開放,對修改關閉( Software entities should be open for extension, but closed for modification.)。即在設計一個模塊的時候,應當使這個模塊可以在不被修改的前提下被擴展。

  2)滿足“開-閉”原則的系統(tǒng)的優(yōu)點

    a) 通過擴展已有的軟件系統(tǒng),可以提供新的行為,以滿足對軟件的新需求,使變化中的軟件系統(tǒng)有一定的適應性和靈活性。

    b) 已有的軟件模塊,特別是最重要的抽象層模塊不能再修改,這就使變化中的軟件系統(tǒng)有一定的穩(wěn)定性和延續(xù)性。

    c) 這樣的系統(tǒng)同時滿足了可復用性與可維護性。

  1.2 如何實現(xiàn)“開-閉” 原則

  在面向對象設計中,不允許更改的是系統(tǒng)的抽象層,而允許擴展的是系統(tǒng)的實現(xiàn)層。換言之,定義一個一勞永逸的抽象設計層,允許盡可能多的行為在實現(xiàn)層被實現(xiàn)。

  解決問題關鍵在于抽象化,抽象化是面向對象設計的第一個核心本質。

  對一個事物抽象化,實質上是在概括歸納總結它的本質。抽象讓我們抓住最最重要的東西, 從更高一層去思考。這降低了思考的復雜度,我們不用同時考慮那么多的東西。換言之,我們封裝了事物的本質,看不到任何細節(jié)。

  在面向對象編程中,通過抽象類及接口,規(guī)定了具體類的特征作為抽象層,相對穩(wěn)定,不需更改,從而滿足“對修改關閉”;而從抽象類導出的具體類可以改變系統(tǒng)的行為,從而滿足“對擴展開放”。

  對實體進行擴展時,不必改動軟件的源代碼或者二進制代碼。關鍵在于抽象。

  1.3 對可變性的封裝原則

  “開-閉”原則也就是“對可變性的封裝原則”(Principle of Encapsulation of Variation ,EVP)。即找到一個系統(tǒng)的可變因素,將之封裝起來。換言之,在你的設計中什么可能會發(fā)生變化,應使之成為抽象層而封裝,而不是什么會導致設計改變才封裝。

      “對可變性的封裝原則”意味著:

  a) 一種可變性不應當散落在代碼的許多角落,而應當被封裝到一個對象里面。同一可變性的不同表象意味著同一個繼承等級結構中的具體子類。因此,此處可以期待繼承關系的出現(xiàn)。繼承是封裝變化的方法,而不僅僅是從一般的對象生成特殊的對象。

  b) 一種可變性不應當與另一種可變性混合在一起。作者認為類圖的繼承結構如果超過兩層,很可能意味著兩種不同的可變性混合在了一起。

  使用“可變性封裝原則”來進行設計可以使系統(tǒng)遵守“開-閉”原則。

  即使無法百分之百的做到“開-閉”原則,但朝這個方向努力,可以顯著改善一個系統(tǒng)的結構。

  二、里氏代換原則(Liskov Substitution Principle, LSP)

  2.1 概念

  定義:如果對每一個類型為 T1 的對象 O1 ,都有類型為 T2 的對象 O2 ,使得以 T1 定義的所有程序 P 在所有的對象 O1 都代換為 O2 時,程序 P 的行為沒有變化,那么類型 T2 是類型 T1 的子類型。

  即,一個軟件實體如果使用的是一個基類的話,那么一定適用于其子類。而且它覺察不出基類對象和子類對象的區(qū)別。 也就是說,在軟件里面,把基類都替換成它的子類,程序的行為沒有變化。

  反過來的代換不成立,如果一個軟件實體使用的是一個子類的話,那么它不一定適用于基類。

  任何基類可以出現(xiàn)的地方,子類一定可以出現(xiàn)。

  基于契約的設計、抽象出公共部分作為抽象基類的設計。

  2.2 里氏代換原則與“開- 閉” 原則的關系

  實現(xiàn)“開-閉”原則的關鍵步驟是抽象化。基類與子類之間的繼承關系就是抽象化的體現(xiàn)。因此里氏代換原則是對實現(xiàn)抽象化的具體步驟的規(guī)范。

  違反里氏代換原則意味著違反了“開-閉”原則,反之未必。

  三、 依賴倒轉原則  dependence inversion principle, DIP 

  3.1 概念

  依賴倒轉原則就是要依賴于抽象,不要依賴于實現(xiàn)。(Abstractions should not depend upon details. Details should depend upon abstractions.)要針對接口編程,不要針對實現(xiàn)編程。(Program to an interface, not an implementation.)

  也就是說應當使用接口和抽象類進行變量類型聲明、參數(shù)類型聲明、方法返還類型說明,以及數(shù)據(jù)類型的轉換等。而不要用具體類進行變量的類型聲明、參數(shù)類型聲明、方法返還類型說明,以及數(shù)據(jù)類型的轉換等。要保證做到這一點,一個具體類應當只實現(xiàn)接口和抽象類中聲明過的方法,而不要給出多余的方法。

  傳統(tǒng)的過程性系統(tǒng)的設計辦法傾向于使高層次的模塊依賴于低層次的模塊,抽象層次依賴于具體層次。倒轉原則就是把這個錯誤的依賴關系倒轉過來。

  面向對象設計的重要原則是創(chuàng)建抽象化,并且從抽象化導出具體化,具體化給出不同的實現(xiàn)。繼承關系就是一種從抽象化到具體化的導出。

  抽象層包含的應該是應用系統(tǒng)的商務邏輯和宏觀的、對整個系統(tǒng)來說重要的戰(zhàn)略性決定,是必然性的體現(xiàn)。具體層次含有的是一些次要的與實現(xiàn)有關的算法和邏輯,以及戰(zhàn)術性的決定,帶有相當大的偶然性選擇。具體層次的代碼是經(jīng)常變動的,不能避免出現(xiàn)錯誤。

  從復用的角度來說,高層次的模塊是應當復用的,而且是復用的重點,因為它含有一個應用系統(tǒng)最重要的宏觀商務邏輯,是較為穩(wěn)定的。而在傳統(tǒng)的過程性設計中,復用則側重于具體層次模塊的復用。

  依賴倒轉原則則是對傳統(tǒng)的過程性設計方法的“倒轉”,是高層次模塊復用及其可維護性的有效規(guī)范。

  特例:對象的創(chuàng)建過程是違背“開—閉”原則以及依賴倒轉原則的,但通過工廠模式,能很好地解決對象創(chuàng)建過程中的依賴倒轉問題。

  3.2 關系

  “開-閉”原則與依賴倒轉原則是目標和手段的關系。如果說開閉原則是目標,依賴倒轉原則是到達"開閉"原則的手段。如果要達到最好的"開閉"原則,就要盡量的遵守依賴倒轉原則,依賴倒轉原則是對"抽象化"的最好規(guī)范。

  里氏代換原則是依賴倒轉原則的基礎,依賴倒轉原則是里氏代換原則的重要補充。

  3.3 耦合(或者依賴)關系的種類:

  零耦合(Nil Coupling)關系:兩個類沒有耦合關系。

  具體耦合(Concrete Coupling)關系:發(fā)生在兩個具體的(可實例化的)類之間,經(jīng)由一個類對另一個具體類的直接引用造成。

  抽象耦合(Abstract Coupling)關系:發(fā)生在一個具體類和一個抽象類(或接口)之間,使兩個必須發(fā)生關系的類之間存有最大的靈活性。

  3.3.1 如何把握耦合

  我們應該盡可能的避免實現(xiàn)繼承,原因如下:

  1) 失去靈活性,使用具體類會給底層的修改帶來麻煩。

  2) 耦合問題,耦合是指兩個實體相互依賴于對方的一個量度。程序員每天都在(有意識地或者無意識地)做出影響耦合的決定:類耦合、API耦合、應用程序耦合等等。在一個用擴展的繼承實現(xiàn)系統(tǒng)中,派生類是非常緊密的與基類耦合,而且這種緊密的連接可能是被不期望的。如B extends A ,當B不全用A中的所有methods時,這時候,B調用的方法可能會產生錯誤!

  我們必須客觀的評價耦合度,系統(tǒng)之間不可能總是松耦合的,那樣肯定什么也做不了。

  3.3.2 我們決定耦合的程度的依據(jù)何在呢 ?

  簡單的說,就是根據(jù)需求的穩(wěn)定性,來決定耦合的程度。對于穩(wěn)定性高的需求,不容易發(fā)生變化的需求,我們完全可以把各類設計成緊耦合的(我們雖然討論類之間的耦合度,但其實功能塊、模塊、包之間的耦合度也是一樣的),因為這樣可以提高效率, 而且我們還可以使用一些更好的技術來提高效率或簡化代碼,例如c#中的內部類技術。可是,如果需求極有可能變化,我們就需要充分的考慮類之間的耦合問題,我們可以想出各種各樣的辦法來降低耦合程度,但是歸納起來,不外乎增加抽象的層次來隔離不同的類,這個抽象層次可以是抽象的類、具體的類,也可以是接口,或是一組的類。我們可以用一句話來概括降低耦合度的思想:“針對接口編程,而不是針對實現(xiàn)編程。”

  在我們進行編碼的時候,都會留下我們的指紋,如public的多少,代碼的格式等等。 我們可以耦合度量評估重新構建代碼的風險。因為重新構建實際上是維護編碼的一種形式,維護中遇到的那些麻煩事在重新構建時同樣會遇到。我們知道在重新構建 之后,最常見的隨機bug大部分都是不當耦合造成的 。

  如果不穩(wěn)定因素越大,它的耦合度也就越大。

  某類的不穩(wěn)定因素=依賴的類個數(shù)/被依賴的類個數(shù)

  依賴的類個數(shù)= 在編譯此類的時被編譯的其它類的個數(shù)總和

  3.3.3 怎樣將大系統(tǒng)拆分成小系統(tǒng)

  解決這個問題的一個思路是將許多類集合成一個更高層次的單位,形成一個高內聚、低耦合的類的集合,這是我們設計過程中應該著重考慮的問題!

  耦合的目標是維護依賴的單向性,有時我們也會需要使用壞的耦合。在這種情況下,應當小心記錄下原因,以幫助日后該代碼的用戶了解使用耦合真正的原因。

  3.4 怎樣做到依賴倒轉?

  以抽象方式耦合是依賴倒轉原則的關鍵。抽象耦合關系總要涉及具體類從抽象類繼承,并且需要保證在任何引用到基類的地方都可以改換成其子類,因此,里氏代換原則是依賴倒轉原則的基礎。

  在抽象層次上的耦合雖然有靈活性,但也帶來了額外的復雜性,如果一個具體類發(fā)生變化的可能性非常小,那么抽象耦合能發(fā)揮的好處便十分有限,這時可以用具體耦合反而會更好。

  層次化:所有結構良好的面向對象構架都具有清晰的層次定義,每個層次通過一個定義良好的、受控的接口向外提供一組內聚的服務。

  依賴于抽象:建議不依賴于具體類,即程序中所有的依賴關系都應該終止于抽象類或者接口。盡量做到:

  1、任何變量都不應該持有一個指向具體類的指針或者引用。

  2、任何類都不應該從具體類派生。

  3、任何方法都不應該覆寫它的任何基類中的已經(jīng)實現(xiàn)的方法。

  3.5 依賴倒轉原則的優(yōu)缺點

  依賴倒轉原則雖然很強大,但卻最不容易實現(xiàn)。因為依賴倒轉的緣故,對象的創(chuàng)建很可能要使用對象工廠,以避免對具體類的直接引用,此原則的使用可能還會導致產生大量的類,對不熟悉面向對象技術的工程師來說,維護這樣的系統(tǒng)需要較好地理解面向對象設計。

  依賴倒轉原則假定所有的具體類都是會變化的,這也不總是正確。有一些具體類可能是相當 穩(wěn)定,不會變化的,使用這個具體類實例的應用完全可以依賴于這個具體類型,而不必為此創(chuàng)建一個抽象類型。

  四、合成/聚合復用原則( Composite/Aggregate Reuse Principle  CARP 

      4.1 概念

  定義:在一個新的對象里面使用一些已有的對象,使之成為新對象的一部分;新的對象通過向這些對象的委派達到復用這些對象的目的。

  應首先使用合成/聚合,合成/聚合則使系統(tǒng)靈活,其次才考慮繼承,達到復用的目的。而使用繼承時,要嚴格遵循里氏代換原則。有效地使用繼承會有助于對問題的理解,降低復雜度,而濫用繼承會增加系統(tǒng)構建、維護時的難度及系統(tǒng)的復雜度。

  如果兩個類是“Has-a”關系應使用合成、聚合,如果是“Is-a”關系可使用繼 承。"Is-A"是嚴格的分類學意義上定義,意思是一個類是另一個類的"一種"。而"Has-A"則不同,它表示某一個角色具有某一項責任。

  4.2 什么是合成?什么是 聚合?

  合成(Composition)和聚合(Aggregation)都是關聯(lián) (Association)的特殊種類。

  聚合表示整體和部分的關系,表示“擁有”。如奔馳S360汽車,對奔馳S360引擎、奔馳S360輪胎的關系是聚合關系,離開了奔馳S360汽車,引擎、輪胎就失去了存在的意義。在設計中, 聚合不應該頻繁出現(xiàn),這樣會增大設計的耦合度。

  合成則是一種更強的“擁有”,部分和整體的生命周期一樣。合成的新的對象完全支 配其組成部分,包括它們的創(chuàng)建和湮滅等。一個合成關系的成分對象是不能與另一個合成關系共享的。

    換句話說,合成是值的聚合(Aggregation by Value),而一般說的聚合是引用的聚合(Aggregation by Reference)。

  明白了合成和聚合關系,再來理解合成/聚合原則應該就清楚了,要避免在系統(tǒng)設計中出現(xiàn),一個類的繼承層次超過3層,則需考慮重構代碼,或者重新設計結構。當然最好的辦法就是考慮使用合成/聚合原則。

  4.3 通過合成/聚合的優(yōu)缺點

  優(yōu)點:

  1) 新對象存取成分對象的唯一方法是通過成分對象的接口。

  2) 這種復用是黑箱復用,因為成分對象的內部細節(jié)是新對象所看不見的。

  3) 這種復用支持包裝。

  4) 這種復用所需的依賴較少。

  5) 每一個新的類可以將焦點集中在一個任務上。

  6) 這種復用可以在運行時間內動態(tài)進行,新對象可以動態(tài)的引用與成分對象類型相同的對象。

  7) 作為復用手段可以應用到幾乎任何環(huán)境中去。

  缺點:就是系統(tǒng)中會有較多的對象需要管理。

  4.4 通過繼承來進行復用的優(yōu)缺點

  優(yōu)點:

  1) 新的實現(xiàn)較為容易,因為超類的大部分功能可以通過繼承的關系自動進入子類。

  2) 修改和擴展繼承而來的實現(xiàn)較為容易。

  缺點 :

  1) 繼承復用破壞封裝,因為繼承將超類的實現(xiàn)細節(jié)暴露給子類。由于超類的內部細節(jié)常常是對于子類透明的,所以這種復用是透明的復用,又稱“白箱”復用。

  2) 如果超類發(fā)生改變,那么子類的實現(xiàn)也不得不發(fā)生改變。

  3) 從超類繼承而來的實現(xiàn)是靜態(tài)的,不可能在運行時間內發(fā)生改變,沒有足夠的靈活性。

  4) 繼承只能在有限的環(huán)境中使用。

  五、 迪米特法則( Law of Demeter LoD )

  5.1 概述

  定義:一個軟件實體應當盡可能少的與其他實體發(fā)生相互作用。

  這樣,當一個模塊修改時,就會盡量少的影響其他的模塊。擴展會相對容易。

  這是對軟件實體之間通信的限制。它要求限制軟件實體之間通信的寬度和深度。

  5.2 迪米特法則的其他表述

  1)只與你直接的朋友們通信。

  2)不要跟“陌生人”說話。

  3)每一個軟件單位對其他的單位都只有最少的知識,而且局限于那些與本單位密切相關的軟件單位。

  5.3 狹義的迪米特法則

  如果兩個類不必彼此直接通信,那么這兩個類就不應當發(fā)生直接的相互作用。如果其中的一個類需要調用另一個類的某一個方法的話,可以通過第三者轉發(fā)這個調用。

  朋友圈的確定,“朋友”條件:

  1)當前對象本身(this)

  2)以參量形式傳入到當前對象方法中的對象

  3)當前對象的實例變量直接引用的對象

  4)當前對象的實例變量如果是一個聚集,那么聚集中的元素也都是朋友

  5)當前對象所創(chuàng)建的對象

  任何一個對象,如果滿足上面的條件之一,就是當前對象的“朋友”;否則就是“陌生 人”。

  缺點:會在系統(tǒng)里造出大量的小方法,散落在系統(tǒng)的各個角落。

  與依賴倒轉原則互補使用。

  5.4 狹義的迪米特法則的缺點:

  在系統(tǒng)里造出大量的小方法,這些方法僅僅是傳遞間接的調用,與系統(tǒng)的商務邏輯無關。

  遵循類之間的迪米特法則會是一個系統(tǒng)的局部設計簡化,因為每一個局部都不會和遠距離的對象有直接的關聯(lián)。但是,這也會造成系統(tǒng)的不同模塊之間的通信效率降低,也會使系統(tǒng)的不同模塊之間不容易協(xié)調。

  5.5 迪米特法則與設計模式

  門面(外觀)模式和調停者(中介者)模式實際上就是迪米特法則的具體應用

  5.6 廣義的迪米特法則

  迪米特法則的主要用意是控制信息的過載。在將迪米特法則運用到系統(tǒng)設計中時,要注意下面的幾點:

  1)在類的劃分上,應當創(chuàng)建有弱耦合的類。

  2)在類的結構設計上,每一個類都應當盡量降低成員的訪問權限。

  3)在類的設計上,只要有可能,一個類應當設計成不變類。

  4)在對其他類的引用上,一個對象對其對象的引用應當降到最低。

  5.7 廣義迪米特法則在類的設計的體現(xiàn)

  1)優(yōu)先考慮將一個類設置成不變類

  2)盡量降低一個類的訪問權限

  3)謹慎使用Serializable

  4)盡量降低成員的訪問權限

  5)取代C Struct

  迪米特法則又叫作最少知識原則(Least Knowledge Principle或簡寫為LKP),就是說一個對象應當對其他對象有盡可能少的了解。

  5.8 如何實現(xiàn)迪米特法則

  迪米特法則的主要用意是控制信息的過載,在將其運用到系統(tǒng)設計中應注意以下幾點:

  1) 在類的劃分上,應當創(chuàng)建有弱耦合的類。類之間的耦合越弱,就越有利于復用。

  2) 在類的結構設計上,每一個類都應當盡量降低成員的訪問權限。一個類不應當public自己的屬性,而應當提供取值和賦值的方法讓外界間接訪問自己的屬性。

  3) 在類的設計上,只要有可能,一個類應當設計成不變類。

  4) 在對其它對象的引用上,一個類對其它對象的引用應該降到最低。

  六、 接口隔離原則(Interface Segregation Principle, ISP 

      6.1 概念

  接口隔離原則:使用多個專門的接口比使用單一的總接口要好。也就是說,一個類對另外一個類的依賴性應當是建立在最小的接口上。     

  這里的"接口"往往有兩種不同的含義:一種是指一個類型所具有的方法特征的集合,僅僅是一種邏輯上的抽象;另外一種是指某種語言具體的"接口"定義,有嚴格的定義和結構。比如C#語言里面的Interface結構。對于這兩種不同的含義,ISP的表達方式以及含義都有所不同。(上面說的一個類型,可以理解成一個類,我們定義了一個 類,也就是定義了一種新的類型)     

  當我們把"接口"理解成一個類所提供的所有方法的特征集合的時候,這就是一種邏輯上的 概念。接口的劃分就直接帶來類型的劃分。這里,我們可以把接口理解成角色,一個接口就只是代表一個角色,每個角色都有它特定的一個接口,這里的這個原則可以叫做"角色隔離原則"。

  如果把"接口"理解成狹義的特定語言的接口,那么ISP表達的意思是說,對不同的客戶端,同一個角色提供寬窄不同的接口,也就是定制服務,個性化服務。就是僅僅提供客戶端需要的行為,客戶端不需要的行為則隱藏起來。

  應當為客戶端提供盡可能小的單獨的接口,而不要提供大的總接口。

  這也是對軟件實體之間通信的限制。但它限制的只是通信的寬度,就是說通信要盡可能的窄。

  遵循迪米特法則和接口隔離原則,會使一個軟件系統(tǒng)功能擴展時,修改的壓力不會傳 到別的對象那里。

  6.2 如何實現(xiàn)接口隔離原則

  不應該強迫用戶依賴于他們不用的方法。

  1、利用委托分離接口。

  2、利用多繼承分離接口。

  七、單一職責原則(SRP)

  單一職責原則(SRP),就一個類而言,應該僅有一個引起它變化的原因。也就是說,不要把變化原因各不相同的職責放在一起,因為不同的變化會影響到不相干的職責。再通俗一點地說就是,不該你管的事情你不要管,管好自己的事情就可以了,多管閑事害了自己也害了別人。

  在軟件設計中,如果一個類承擔的職責過多,就等于吧這些職責耦合在一起,而一個職責的變化可能會削弱和抑制這個類完成其他職責的能力。這耦合會導致脆弱的設計,當變化發(fā)生時,設計會遭受到意想不到的破壞。 

  軟件設計真正要做的許多內容,就是發(fā)現(xiàn)職責并把那些職責相互分離。如果多于一個的動機去改變一個類,那么這個類就具有多余一個的職責,就應該要考慮類的職責分離。

  小結

  在我們進行面向對象系統(tǒng)的設計時,可以不去特意的考慮使用哪些設計模式,但是一定要盡量遵守這些設計原則。這樣做的話,即使是設計經(jīng)驗不足,也比較容易設 計出易擴展的系統(tǒng),并且可能自然的實現(xiàn)了某些模式。這種情況,恐怕算是很理想的一種設計了。

  參考資料

  1. 面向對象設計模式原則

  2. SOLID (object-oriented design)

it知識庫面向對象設計的設計原則,轉載需保留來源!

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 中文字幕av亚洲精品一部二部 | 一区二区三区四区免费观看 | 综合久久99| 亚洲日产精品 | 午夜免费观看体验区 | 日韩国产在线观看 | 亚洲午夜精品视频 | 一级毛片成人免费看a | 日韩国产欧美 | 国产精品v | 91美女在线 | 久久亚洲综合 | 又爽又黄axxx片免费观看 | 超碰免费观看 | 欧美在线日韩 | 先锋资源网站 | 久久成人一区 | 欧美精品啪啪 | 久久久91精品国产一区二区三区 | 91在线观看 | 日韩精品在线播放 | www.国产精品 | 久久久久精 | 日韩第一夜 | 蜜桃视频在线观看免费视频网站www | 婷婷综合久久 | 欧美一级www片免费观看 | 一区二区三区免费观看 | 国产精品久久久久久久久免费樱桃 | 国产精品一区二区精品 | 国产精品视频500部 a久久 | 国产激情精品视频 | 亚洲最色网站 | 日日操视频 | 亚洲国产精品久久 | 人成在线| 99草免费视频 | 久草精品视频 | 亚洲一区二区三区四区视频 | 国产精品揄拍一区二区 | 国产婷婷 |