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

嵌入式軟件設計原則隨想

開發 架構
重構是持續進行的,好比用餐后對廚房的清理工作。第一次沒有清理用餐會快一點,但是由于沒有對盤碟和用餐環境進行清潔,第二天做準備工作的時間就要更長一點。這會再一次促使放棄清潔工作。

1 設計原則

SRP 單一職責原則 Single Responsibility Principle
每個函數或者功能塊只有一個職責,只有一個原因會使其改變。

OCP 開放一封閉原則 The Open-Closed Principle
對于擴展是開放的,對于修改是封閉的。

DIP 依賴倒置原則 Dependency Inversion Principle
高層模塊和低層模塊應該依賴中間抽象層(即接口),細節應該依賴于抽象。

ISP 接口隔離原則 Interface Segregation Principle
接口盡量細化,同時方法盡量少,不要試圖去建立功能強大接口供所有依賴它的接口去調用。

LKP 最少知道原則  Least Knowledge Principle
一個子模塊應該與其它模塊保持最少的了解。

圖片圖片

微信公眾號【嵌入式系統】個人想法,設計原則主要是可在有限范圍內指導功能模塊劃分,作為提高軟件復用度和質量的思路。

2 單一職責原則 (SRP)

函數或功能應該僅有一個引起它變化的原因。單一職責原則是最簡單但又最難運用的原則,需要按職責分割大模塊,如果一個子模塊承擔的職責過多,就等于把這些職責耦合在一起,一個職責的變化可能會削弱或抑制這個模塊完成其他職責的能力。劃分依據是影響它改變的只有一個原因,并不是單純理解的一個模塊只實現一個功能,對函數層面也是如此。

2.1 什么是職責

在 SRP 中把職責定義為“變化的原因”(a reason for change),如果有可能存在多于一個的動機去改變一個子模塊,表明這個模塊就具有多個職責。有時很難注意到這點,習慣以組的形式去考慮職責。例如Modem 程序接口,大多數人會認為這個接口看起來非常合理。

//interface Modem 違反 SRP
void connect();
void disconnect();
void send();
void recv();

然而,該接口中卻顯示出兩個職責。第一個職責是連接管理,第二個職責是數據通信,connect和 disconnect函數進行調制解調器的連接處理,send 和 recv函數進行數據通信。

這兩個職貴應該被分開嗎?這依賴于應用程序變化的方式。如果應用程序的變化會影響連接函數,如外設與主機熱插拔,連接后是數據收發,則需要分開。如果是socket,其本身連接狀態與數據交互是綁定的關系,應用程序的變化總是導致這兩個職責同時變化,那沒必分離它們,強行分割反而會引入復雜性。

2.2 分離耦合

多個職責耦合不是所希望的,但有時無法避免,有些和硬件或操作系統有關的原因,迫使把不愿耦合在起的東西耦合在一起。然而,對于應用部分來說應當盡量分離解耦。軟件前期模塊設計真正要做的許多內容,就是發現職責并把那些職責相互分離。

3 開放-封閉原則 (OCP)

如果期望開發的軟件不會在第一版后就被拋棄,就必須牢牢地記住這點。那怎樣的設計才能面對需求改變卻可以保持相對穩定,從而使得系統可以在第一個版本以后不斷推出新的版本呢?開放-封閉原則為我們提供了指引。

軟件實體(模塊、函數等)應該是可以擴展的,但是不可修改的。如果程序中的一處改動會產生連鎖反應,導致相關模塊的改動,那么設計就具有僵化性的臭味。OCP 建議應該對系統進行重構,這樣以后對系統再進行那樣的改動時,就只需要添加新的代碼,而不必改動已經正常運行的代碼。

3.1 特性

開放-封閉原則設計出的模塊具有兩個主要的特征。

  1. 對于護展是開放的 (Open  for  extension)
    模塊的行為是可以擴展的,當應用需求改變時,可以對模塊進行擴展,使其滿足新需求。
  2. 對于更改是封閉的(Closed   for   modificaiton)
    模塊的源代碼是不能被侵犯的,不允許修改已有源代碼。

兩個特征看似互相矛盾,擴展模塊行為的通常方式就是修改該模塊的源代碼,不允許修改的模塊常常都被認為是具有固定的行為。怎樣可能在不改動模塊源代碼的情況下去更改它的行為呢?關鍵是抽象。

3.2 抽象隔離

在 C++等面向對象設計技術時,可以創建出固定卻能夠描述一組任意個可能行為的抽象體,這個抽象體就是抽象基類,而這一組任意個可能的行為則表現為可能的派生類。模塊可以操作抽象體,由于模塊依賴于一個固定的抽象體,所以它對于更改可以是關閉的。同時通過從這個抽象體派生,也可以擴展此模塊的行為。

面向對象的語言多態特性很容易實現,而嵌入式的C該如何呢?一個函數接口或功能,不要直接固化相關邏輯,而是把具體實現細節對外開放可擴展的,便于后期添加功能,且不影響其它的功能。

3.3 違反 OCP

一個應用程序需要在窗口上繪制圓形(Circle)和方形(Square),圓形和方形會被創建在同一個列表中,并保持適當的順序,程序按順序遍歷列表并繪制所有的圓形和方形。

如果使用C語言,并采用不遵循OCP的過程化方法,一組數據結構,它的第一個成員都相同,但是其余的成員都不同。每個結構中的第一個成員都是一個用來標識該結構是代表圓或方形的類型碼。DrawAllShapes 函數遍歷數組,該數組的元素是指向這些數據結構的指針,根據類型碼調用對應的函數 (DrawCircle 或 DrawSquare)。

typedef enum
{
    CIRCLE,
    SQUARE,
} ShapeType;

typedef struct
{
    ShapeType itsType;
} Shape;

typedef struct
{
    double x;
    double y;
} Point;

typedef struct
{
    ShapeType itsType;
    double itsSide;
    Point itsTopLeft;
} Square;

typedef struct
{
    ShapeType itsType;
    double itsRadius;
    Point itsCenter;
} Circle;

void DrawSquare(struct Square*);
void DrawCircle(struct Circle*);

void DrawAllShapes(Shape **list, int n)
{
    int i;
    Shape* s;

    for(i = 0; i < n; i++)
    {
        s = (Shape*)list[i];
        switch(s->itsType)
        {
            case SQUARE:
                DrawSquare((struct Square*)s);
                break;
            case CIRCLE:
                DrawCircle((struct Circle*)s);
                break;
        }
    }
}

DrawAllShapes 函數不符合 OCP,如果希望函數能夠繪制包含有三角形的列表,就必須得更改這個函數,擴展switch增加三角形。事實上,每增加一種新的形狀類型,都必須要更改這個函數。在這樣的應用程序中增加一種新的形狀類型,就意味著要找出所有包含上述 switch(或 if else 語句)的函數,在每一處都添加對新增的形狀類型的判斷。

在嵌入式數據流中,數據解析是常見情景,如果新手開發,可能是一個萬能長函數完成全部解析功能。比如不同類型的數據解析錯誤樣例:

typedef int int32_t;
typedef short int16_t;
typedef char int8_t;
typedef unsigned int uint32_t;
typedef unsigned short uint16_t;
typedef unsigned char uint8_t;

#define NULL ((void *)(0))

//違反OCP的樣例
//微信公眾號【嵌入式系統】,不同類型的數據集中在一起,使用switch-case處理,與前面DrawAllShapes一樣,后續擴展會影響既有函數。
int16_t cmd_handle_body_v1(uint8_t type, uint8_t *data, uint16_t len)
{
    switch(type)
    {
        case 0:
            //handle0
            break;
        case  1:
            //handle1
            break;
        default:
            break;
    }
    return -1;
}

3.4 遵循 OCP

上面的數據解析樣例調整后:

//遵守OCP原則
//微信公眾號【嵌入式系統】
typedef int16_t (*cmd_handle_body)(uint8_t *data, uint16_t len);
typedef struct
{
    uint8_t type;
    cmd_handle_body hdlr;
} cmd_handle_table;

static int16_t cmd_handle_body_0(uint8_t *data, uint16_t len)
{
    //handle0
    return 0;
}

static int16_t cmd_handle_body_1(uint8_t *data, uint16_t len)
{
    //handle1
    return 0;
}

//擴展新指令只需要在這里加上就行,不會影響先前的
static cmd_handle_table cmd_handle_table_map[] =
{
    {0, cmd_handle_body_0},
    {1, cmd_handle_body_1}
};

int16_t handle_cmd_body_v2(uint8_t type, uint8_t *data, uint16_t len)
{
    int16_t ret=-1;
    uint16_t i = 0;
    uint16_t size = sizeof(cmd_handle_table_map) / sizeof(cmd_handle_table_map[0]);

    for(i = 0; i < size; i++)
    {
        if((type == cmd_handle_table_map[i].type) && (cmd_handle_table_map[i].hdlr != NULL))
        {
            ret=cmd_handle_table_map[i].hdlr(data, len);
        }
    }
    return ret;
}

雖然不如C++抽象與多態,但整體實現了OCP的效果,在不修改handle_cmd_body_v2的情況下,擴展cmd_handle_table_map。這個模式其實是通用的表驅動法。可參考微信公眾號【嵌入式系統】的文章嵌入式軟件的設計模式(下) 第4章。OCP有時也可以采用回調函數的方式,底層不變,由應用層自身擴展實現差異化部分。

3.5 策略性的閉合

上面的例子其實并非是100%封閉。一般而言,無論模塊是多么的“開放-封閉”,都會存在一些無法對之封閉的變化,沒有對所有的情況都貼切的模型。既然不可能完全封閉,那么就必須有策略地對待這個問題。也就是說,設計人員必須對模塊應該對哪種變化封閉做出選擇。必須先預估最有可能發生的變化,然后構造隔離這些變化,這需要設計人員具備一些行業經驗及預測能力。

遵循OCP 的代價也是昂貴的,肆無忌憚的從軟件角度進行抽象隔離,創建抽象隔離要花費開發時間和代碼空間,同時也增加了軟件設計的復雜性。比如前面handle_cmd_body_v1比handle_cmd_body_v2,如果明確需求或者硬件資源緊缺,后者從設計原則角度更合理,但前者更直接且符合資源緊缺且需求固定的場景。對于嵌入式軟件應該對程序中頻繁變化的部分提取抽象。

4 依賴倒置原則 (DIP)

依賴倒置原則即高層模塊(調用者)不依賴于低層模塊(被調用者),二者都應該依賴于抽象。

結構化程序分析和設計,總是傾向于創建高層模塊依賴低層模塊,策略依賴于細節的結構,這是大部分嵌入式軟件的結構,從業務層到組件層,再到驅動層,自頂向下的設計思維。良好的面向對象的程序,其依賴結構相對于傳統的過程式方法設計的結構而言就是被“倒置”了。

高層模塊依賴于低層模塊,意味著低層模塊的改動會直接影響到高層模塊,從而迫使它們依次做出改動,在不同的上下文中重用高層模塊就會變得困難。

4.1 倒置的接口所有權

“Don't  call  us,we'll  call  you.”(不要調用我們,我們會調用你),低層模塊實現在高層模塊中聲明并被高層模塊調用的接口,也就是低層模塊按高層模塊的需求來實現功能。通過這種倒置的接口所有權,滿足高層在任何上下文的重用。事實上,即使是嵌入式軟件,開發的重點是隨時變化的高層模塊,一般都是相似的上層應用軟件在不同的硬件環境運行,所以高層的復用更能提高軟件質量。

4.2 樣例對比

假設控制熔爐調節器的軟件,從外界通道中讀取當前的溫度,并通過向另一個通道發送命令來控制熔爐加熱的開或關。按數據流的結構大概如下:

//溫度調節器的調度算法
//檢測到當前溫度在設定范圍外,開啟或關閉熔爐的加熱器
void temperature_regulate(int min_temp, int max_temp)
{
    int tmp;
    while(1)
    {
        tmp = read_temperature();//讀取溫度
        if(tmp < min_temp)
        {
            furnace_enable();//啟動加熱
        }
        else if(tmp > max_temp)
        {
            furnace_disable();//停止加熱
        }
        wait();
    }
}

算法的高層意圖是清楚的,但是實現代碼中卻夾雜著低層細節。導致這段代碼(控制算法)根本不能重用于不同的硬件,只是代碼很少,算法實現容易,看起來不會造成太大的損害。如果一個復雜的溫度控制算法,需要移植到不同平臺,或者需求改變,要求在溫度異常時發出額外警示呢?

void temperature_regulate_v2(Thermometers *t,Heaterk *h,int min_temp, int max_temp)
{
    int tmp;
    while(1)
    {
        tmp = t->read();
        if(tmp < min_temp)
        {
            h->enable();
        }
        else if(tmp > max_temp)
        {
            h->disable();
        }
        wait();
    }
}

這就倒置了依賴關系,使得高層的調節策略不再依賴于任何溫度計或者熔爐的特定細節。該算法具有較好的可重用性,算法不依賴細節。

依賴倒置尤其可以解決嵌入式軟件中硬件頻繁變更對軟件復用帶來的問題。比如運動手環的計步器,在面向過程的開發按從高到低的調用關系,如果后續因為物料等原因更換加速度傳感器,則會導致上層必須修改,尤其是沒有內部封裝,應用層直接調用驅動接口的方式,需要逐個替換。如果后續不確定傳感器可能用哪顆,軟件需要根據傳感器特性自動調整,則需要大量switch-case來替換。

app  -> drv_pedometer_a
//調用關系全部替換為
app  -> drv_pedometer_b

如果采用依賴倒置,兩者依賴于抽象:

app  -> get_pedometer_interface
//底層依賴抽象
drv_pedometer_a  -> get_pedometer_interface
drv_pedometer_b  -> get_pedometer_interface

依賴倒置,即不同的硬件驅動均依賴抽象的接口,上層業務也依賴抽象層,所有的開發都圍繞get_pedometer_interface來設計,這樣硬件變化不會影響上層軟件的復用。這個實現其實是通用的代理模式。

4.3 結論

使用傳統的過程化程序設計所創建出來的依賴關系結構,策略是依賴于細節的,這樣會使策略受到細節改變的影響。事實上,使用何種語言來編寫程序是無關緊要的。即使是嵌入式C,如果程序的依賴關系是倒置的,它就是面向對象的設計思維。

依賴倒置原則是實現面向對象技術宣稱的好處的基本機制,正確應用對于創建可重用的框架來說是必須的,同時它對于構建在變化面前富有彈性的代碼也是非常重要的;由于抽象和細節被彼此隔離,所以代碼也容易維護。

5 接口隔離原則 (ISP)

使用多個專門的接口,而不使用單一的總接口,即客戶端不應該依賴那些它不需要的接口。面向對象開發時,繼承的基類中包含本不需要的接口,原本特定需求擴展的接口成了通用,導致所有派生類都要去實現沒有意義的接口,即為接口污染。

5.1 接口污染

接口隔離原則”的重點是“接口”二字,在嵌入式C層面有兩種理解:
1、如果把“接口”理解為一組API接口集合,可以是某個子功能的一系列接口。如果部分接口只被部分調用者使用,就需要將這部分接口隔離出來,單獨給這部分調用者使用,而不強迫其它調用者也依賴這部分本不會被用到的接口。類似購物,不需要捆綁銷售,只買自己需要的。
2、如果把“接口”理解為單個API接口或函數,部分調用者只需要函數中的部分功能,可把函數拆分成粒度更細的多個函數,讓調用者只依賴它需要的那個細粒度函數。即一個函數不要傳入過多的參數配置,寧可拆分為多個同類接口簡化調用,也不要提供一個萬能的需要一些不相關參數的接口。模塊對外接口不要過度封裝,參數太多也不便于閱讀和使用。

5.2 風險與解決

如果一個程序依賴于部分它不使用的方法,這程序就面臨著由于這些未使用方法的改變所帶來的變更,這無意中導致了所有相關程序之間的耦合。換種說法,如果一個客戶程序依賴于它不使用的方法,但是其他客戶程序卻要使用這些方法,那當其他客戶要求這個方法改變時,就會影響到這個客戶程序。應該盡可能地避免這種耦合,分離接口。

在嵌入式C中,隨著迭代升級,也會擴展新功能,或者直接為函數增加傳入參數,或者函數內部增加額外的處理,導致接口產生冗余,對不同版本的調用者并不友好(如果本身是功能迭代升級沒問題,避免不同版本的差異是平級關系)。更改的代價和影響就變得不可預測,并且更改所附帶的風險也會增加。更改一個和自己不相關的功能也可能產生影響,表面是修改A功能卻導致B功能異常,“城門失火,殃及池魚”,這種對單元測試覆蓋也難以把握。

模塊層面,不相關的接口可以使用預編譯宏屏蔽,這樣也節省代碼空間;函數層面擴展新功能時可以新建接口,重新實現和原來接口功能平級的擴展版或者v2,盡量不要通過傳參合并,除非明確兩者是遞進關系而不是并列關系。

6 最少知道原則(LKP)

迪米特法則(Law of Demeter,縮寫是 LOD),也叫最小知道(知識)原則,一個功能對其依賴的子功能知道的越少越好,對于被依賴的子功能無論邏輯多么復雜,都盡量將邏輯封裝在內部。通俗的解釋就是,使用某個子模塊,不需要關注其內部實現,調用盡可能少的API接口。

比如執行A操作需要按順序調用1-2-3-4四個接口,執行B操作需要按順序調用1-2-4-3四個接口,對于調用者需要清楚知道模塊內細節才能正確使用,這種完全可以合并接口,封裝A和B兩個動作,在其內部執行具體的細節,對外隱藏封閉,外界使用時無需關注。

最少知道原則(迪米特原則)的初衷在于降低模塊間的耦合,模塊更好的信息隱藏和更少的信息重載,將部分信息固化封閉。但過度的封閉也有缺點,一旦客制化需求變更,如果新增C操作是4-3-2-1就需要擴展新接口。

7  重構

重構是持續進行的,好比用餐后對廚房的清理工作。第一次沒有清理用餐會快一點,但是由于沒有對盤碟和用餐環境進行清潔,第二天做準備工作的時間就要更長一點。這會再一次促使放棄清潔工作。的確,跳過清潔工作能夠很快用餐,但是臟亂在逐漸積累。最終,得花費大量的時間去尋找合適的烹飪器具,鑿去盤碟上已經干硬的食物殘余,并把它們洗擦干凈。飯是天天要吃的,忽略掉清潔工作并不能真正加快做飯速度,片面追求速度早晚要翻車,欲速則不達。重構的目的就是為了每天清潔代碼,保持代碼的清潔。


責任編輯:武曉燕 來源: 嵌入式系統
相關推薦

2022-12-14 08:06:08

2023-01-04 09:37:16

2023-07-16 22:48:59

2015-05-07 10:10:28

嵌入式設計軟件

2011-04-18 11:34:34

嵌入式軟件測試

2023-04-27 07:06:18

2012-06-07 10:17:55

軟件設計設計原則Java

2023-05-04 00:27:40

2024-07-04 09:27:57

2011-05-24 17:34:38

嵌入式系統

2012-03-05 15:45:32

嵌入式開源軟件

2022-04-13 09:34:52

軟件開發嵌入式軟件

2011-01-14 13:13:23

嵌入式Linux開發

2010-12-14 11:10:25

嵌入式系統設計師

2010-12-14 11:12:36

嵌入式系統設計師

2010-12-23 11:11:58

嵌入式系統設計師

2011-01-28 11:11:48

嵌入式系統設計師

2010-12-16 10:54:03

嵌入式系統設計師

2010-12-27 10:42:42

嵌入式系統設計師

2011-01-07 11:19:44

嵌入式系統設計師
點贊
收藏

51CTO技術棧公眾號

日韩av不卡在线观看| 日韩免费成人| 亚洲视频狠狠干| 国产精品综合久久久久久| 精品免费囯产一区二区三区| 偷拍亚洲色图| 4438x成人网最大色成网站| 久久视频免费在线| 神马久久久久| 激情综合亚洲精品| 91sa在线看| 登山的目的在线| 欧美一区自拍| 91精品国产丝袜白色高跟鞋| 日韩人妻精品无码一区二区三区| 日本精品在线| 成人小视频在线| 国产精品视频99| 国产污污视频在线观看| 亚洲国产一区二区三区在线播放| 日韩高清人体午夜| 中文字幕无码毛片免费看| 国产超碰精品| 亚洲成av人片一区二区三区 | 中文字幕在线日亚洲9| 国产精品vip| 搡老女人一区二区三区视频tv| 午夜免费福利影院| 国产剧情一区二区在线观看| 色婷婷综合久色| 成人免费毛片在线观看| 国产一二区在线| 日本一区二区三区高清不卡| 开心色怡人综合网站| 亚洲成人黄色片| 日本成人在线电影网| 91超碰中文字幕久久精品| 精品欧美一区二区久久久久| 日韩精品免费| 国产午夜精品一区理论片飘花| 亚洲精品第二页| 精品国产亚洲一区二区三区| 欧美视频三区在线播放| 中文字幕无码精品亚洲35| 青草av在线| 亚洲免费大片在线观看| 手机福利在线视频| 午夜视频在线看| 欧美激情一区二区三区不卡 | 天堂中文字幕在线| 成人av免费在线播放| 99理论电影网| 亚洲国产精品久久人人爱潘金莲 | 在线国产亚洲欧美| 国产a视频免费观看| 亚洲精品**中文毛片| 欧美日韩另类字幕中文| 久色视频在线播放| 蜜桃视频www网站在线观看| 亚洲国产成人av| 欧美深夜福利视频| 亚洲精品88| 91久久精品日日躁夜夜躁欧美| 成年人网站大全| 免费污视频在线一区| 欧美日韩在线电影| 日本黄色福利视频| 日韩最新av| 亚洲国产私拍精品国模在线观看| 久久久久9999| 国产成人影院| 久久久精品视频在线观看| 欧美极品视频在线观看| 激情婷婷亚洲| 日本久久91av| 一级片视频播放| 国产精品91一区二区| 国产另类自拍| 黄网站在线观看| ...xxx性欧美| 轻点好疼好大好爽视频| 欧美亚洲日本精品| 欧美日韩国产一级| 男男受被啪到高潮自述| 国内毛片久久| 中文字幕日韩av| 久久国产精品波多野结衣| 国产综合网站| 国产成人精品视频| aa视频在线免费观看| 91在线观看地址| 在线丝袜欧美日韩制服| 19禁羞羞电影院在线观看| 欧美在线短视频| 激情av中文字幕| 禁果av一区二区三区| 欧美另类交人妖| 中文字幕黄色片| 国产精品一区在线| 欧美一区观看| 麻豆av在线播放| 欧美伊人久久久久久午夜久久久久| 99九九精品视频| 欧美女优在线视频| 久久99国产精品久久久久久久久| 亚洲欧美综合自拍| 国产精品一二一区| 日本一区二区精品视频| 免费在线中文字幕| 精品视频999| 给我看免费高清在线观看| 亚洲欧洲中文字幕| 国产精品成人观看视频国产奇米| 精品毛片在线观看| 国产精品色哟哟网站| 欧美成人精品免费| 人人玩人人添人人澡欧美| 亚洲精品电影网在线观看| 乱h高h女3p含苞待放| 日韩精品91亚洲二区在线观看| 成人情视频高清免费观看电影| 在线日本中文字幕| 一本到不卡免费一区二区| 欧美性猛交乱大交| 99久久99热这里只有精品 | 特黄视频免费看| 粉嫩蜜臀av国产精品网站| 在线观看日本一区| 日本一道高清亚洲日美韩| 亚洲精品久久久久久久久久久久| 欧美高清视频一区二区三区| 久久精品久久久精品美女| 奇米影视首页 狠狠色丁香婷婷久久综合 | 精品人妻无码一区二区| 国产精品对白交换视频| 91视频免费版污| 国产精品欧美在线观看| 欧美一级在线播放| 天堂v在线观看| 亚洲电影在线免费观看| 熟妇女人妻丰满少妇中文字幕| 亚洲成人tv| 91久久久国产精品| 美女国产在线| 欧美人与性动xxxx| www.黄色com| 久久超碰97中文字幕| 亚洲欧美综合一区| 欧美大陆国产| 久久精品这里热有精品| 国产美女主播在线观看| 亚洲日本中文字幕区| 天堂av.com| 女生裸体视频一区二区三区| 91免费看蜜桃| gogo高清在线播放免费| 亚洲精品99久久久久中文字幕| 国产亚洲欧美精品久久久久久 | 欧美性大战久久久久久久| 亚洲自拍偷拍图| 秋霞电影一区二区| 亚洲一区美女| 日韩综合一区二区三区| 91黑丝高跟在线| 九色网友自拍视频手机在线| 欧洲精品视频在线观看| 911国产在线| 国产精品一区专区| 日韩av三级在线| 国产一区毛片| 91麻豆国产精品| a级片免费在线观看| 亚洲精品一区在线观看香蕉| 嫩草影院一区二区三区| 中文字幕一区三区| 欧美日韩一区二区区| 亚洲国产网站| 日韩精品一区二区三区色偷偷| 69堂精品视频在线播放| 精品国产欧美一区二区三区成人| www.日韩高清| 欧美日韩中文字幕在线视频| 你懂得视频在线观看| 国产精品一二三| 男人操女人逼免费视频| 久久网站免费观看| 国产精品99久久久久久久| 综合日韩av| 久久精品国产久精国产思思| 色综合免费视频| 欧美色国产精品| 国产小视频在线看| 欧美激情综合在线| 丰满人妻一区二区三区免费视频棣| 老牛嫩草一区二区三区日本| 无码人妻精品一区二区三区99v| 日韩三级av| 91九色国产在线| 我爱我色成人网| 欧美黑人xxx| 3d成人动漫在线| 日韩精品久久久久久福利| 国产又粗又长视频| 色综合久久综合网| 一区二区三区免费高清视频| 中文字幕第一区二区| 人妻av一区二区| 寂寞少妇一区二区三区| 久久精品99国产| 亚洲一级一区| 久久av秘一区二区三区| 亚洲动漫在线观看| 不卡视频一区二区三区| 日韩电影免费观看高清完整版在线观看| 久久久久五月天| 国产在线1区| 正在播放亚洲1区| 日本大臀精品| 亚洲精品aⅴ中文字幕乱码 | 亚洲视频免费一区| 天天摸夜夜添狠狠添婷婷| 欧美一区二区成人6969| 中文精品久久久久人妻不卡| 精品久久久久久久久久久久| www.99re7| 综合久久给合久久狠狠狠97色| 国产肥白大熟妇bbbb视频| av中文字幕在线不卡| wwwxxxx在线观看| 国模一区二区三区白浆| 尤物国产在线观看| 免费在线看成人av| 亚洲精品高清无码视频| 久久都是精品| 欧美啪啪免费视频| 亚洲精品乱码久久久久久蜜桃麻豆| 日韩video| 五月久久久综合一区二区小说| 亚洲成人自拍视频| 成人激情视频| 亚洲精品一区二| 日韩高清欧美| 一本一道久久a久久精品综合| 精品久久久久久久久久久aⅴ| 欧美一区二区福利| 国产在线日韩精品| 少妇免费毛片久久久久久久久| 九九免费精品视频在线观看| 欧美乱偷一区二区三区在线| 免费久久久久久久久| 女人一区二区三区| 国内精品久久久久久久影视简单| 日本黄网免费一区二区精品| 精品视频久久| 中国一区二区三区| 欧美一区亚洲| 国产妇女馒头高清泬20p多| 日韩午夜精品| 99久久国产宗和精品1上映| 可以看av的网站久久看| 人人干人人视频| 六月丁香综合在线视频| 激情文学亚洲色图| 国产高清不卡二三区| 亚洲视频在线播放免费| 久久久精品人体av艺术| 超薄肉色丝袜一二三| 1区2区3区精品视频| 欧美日韩免费一区二区| 天天av天天翘天天综合网色鬼国产 | 国产美女久久久| 麻豆精品久久| 精品国产日本| 欧美视频网址| 久久www视频| 午夜亚洲激情| 日本中文字幕二区| 国产.精品.日韩.另类.中文.在线.播放| 在线观看成人动漫| 国产欧美日韩另类视频免费观看| 成人做爰视频网站| 五月婷婷综合在线| 久久久久精彩视频| 欧美一级生活片| 亚欧在线观看视频| 日韩小视频在线观看| 美女91在线| 国产精品一二三在线| 91九色鹿精品国产综合久久香蕉| 久久久免费看| 91精品一区二区三区综合在线爱| 亚洲不卡中文字幕无码| 蜜桃视频在线一区| 人妻体内射精一区二区三区| 国产欧美综合在线观看第十页| 成年人一级黄色片| 色综合天天狠狠| 国产suv一区二区| 亚洲无线码在线一区观看| 特级毛片在线| 国产精品九九九| 另类尿喷潮videofree| 麻豆中文字幕在线观看| 国产精品毛片在线| 青娱乐精品在线| 亚洲国产高清不卡| 国产性xxxx高清| 4438x亚洲最大成人网| 伦理片一区二区三区| 欧美高清性猛交| japansex久久高清精品| 色狠狠久久av五月综合| 99在线|亚洲一区二区| 欧美国产在线一区| 国产喷白浆一区二区三区| 国产欧美日韩另类| 欧美一级欧美三级在线观看| 国产黄在线看| 777国产偷窥盗摄精品视频| 日韩精品三级| 一区精品在线| 青椒成人免费视频| 免费黄色在线视频| 午夜精品福利久久久| 国产成人三级一区二区在线观看一| 亚洲午夜精品视频| 欧美亚洲日本精品| 精品综合久久| 最新国产拍偷乱拍精品 | 91浏览器在线视频| 亚洲国产综合久久| 日韩一级视频免费观看在线| 麻豆传媒视频在线观看免费| 国产精品99久久99久久久二8| 私拍精品福利视频在线一区| 欧美一级视频免费看| 国产成a人亚洲| 欧美日韩成人免费观看| 日韩欧美一卡二卡| 四季久久免费一区二区三区四区| 亚洲va欧美va国产综合剧情| 香蕉av一区二区| 欧美一级xxxx| 综合在线观看色| 亚洲一区中文字幕在线| 一区二区三区精品99久久| 四虎4545www精品视频| 日本婷婷久久久久久久久一区二区| 久久久久久久欧美精品| 神马久久久久久久久久久| 欧美系列在线观看| 91精彩视频在线播放| 国产一区二中文字幕在线看| 99精品小视频| 久久无码专区国产精品s| 亚洲国产精品嫩草影院| 国产91免费在线观看| 久久免费福利视频| 奇米影视777在线欧美电影观看| 国产精品一区二区免费在线观看| 久久久国产精品麻豆| 中文字幕+乱码+中文| 久久久精品在线观看| 亚洲精品在线国产| 国产视频九色蝌蚪| 国产日本一区二区| 亚洲一线在线观看| 久久久久国产一区二区三区| 网红女主播少妇精品视频| 激情综合网俺也去| 亚洲欧洲综合另类| 免费看av毛片| 国产成人精品在线视频| 91视频精品| 无码av免费精品一区二区三区| 欧美日韩中文字幕在线| avtt亚洲| 国产精成人品localhost| 免费在线观看成人av| 国产又黄又粗又猛又爽的 | 色哟哟在线观看| 国产精品女人久久久久久| 欧美黄免费看| 免费黄色在线视频| 欧美一二三在线| 一区二区三区电影大全| 91手机视频在线| 久久只精品国产| 国产农村妇女毛片精品| 91av在线影院| 中文字幕一区二区三区欧美日韩| 国产原创剧情av| 欧美日本在线播放| 国产ktv在线视频| 综合视频免费看| www国产精品av| 国产成人三级在线播放| 国产国产精品人在线视| 欧美日韩日本国产亚洲在线 | 特黄视频在线观看|