激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

香港云服务器
服務(wù)器之家 - 編程語言 - Java教程 - Java設(shè)計模式之java中介者模式詳解

Java設(shè)計模式之java中介者模式詳解

2022-01-04 00:46大忽悠愛忽悠 Java教程

這篇文章主要為大家詳細(xì)介紹了23種設(shè)計模式之java中介者模式,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助

 

引言

一般來說,同事類之間的關(guān)系是比較復(fù)雜的,多個同事類之間互相關(guān)聯(lián)時,他們之間的關(guān)系會呈現(xiàn)為復(fù)雜的網(wǎng)狀結(jié)構(gòu),這是一種過度耦合的架構(gòu),即不利于類的復(fù)用,也不穩(wěn)定。例如在下圖中,有六個同事類對象,假如對象1發(fā)生變化,那么將會有4個對象受到影響。如果對象2發(fā)生變化,那么將會有5個對象受到影響。也就是說,同事類之間直接關(guān)聯(lián)的設(shè)計是不好的。

Java設(shè)計模式之java中介者模式詳解

如果引入中介者模式,那么同事類之間的關(guān)系將變?yōu)樾切徒Y(jié)構(gòu),從圖中可以看到,任何一個類的變動,只會影響的類本身,以及中介者,這樣就減小了系統(tǒng)的耦合。一個好的設(shè)計,必定不會把所有的對象關(guān)系處理邏輯封裝在本類中,而是使用一個專門的類來管理那些不屬于自己的行為。

Java設(shè)計模式之java中介者模式詳解

 

介紹

中介者模式(Mediator Pattern):用一個中介對象(中介者)來封裝一系列的對象交互,中介者使各對象不需要顯式地相互引用,從而使其耦合松散,而且可以獨立地改變它們之間的交互。中介者模式又稱為調(diào)停者模式,它是一種對象行為型模式。

 

角色

  • Mediator(抽象中介者):它定義一個接口,該接口用于與各同事對象之間進(jìn)行通信。
  • ConcreteMediator(具體中介者):它是抽象中介者的子類,通過協(xié)調(diào)各個同事對象來實現(xiàn)協(xié)作行為,它維持了對各個同事對象的引用。
  • Colleague(抽象同事類):它定義各個同事類公有的方法,并聲明了一些抽象方法來供子類實現(xiàn),同時它維持了一個對抽象中介者類的引用,其子類可以通過該引用來與中介者通信。
  • ConcreteColleague(具體同事類):它是抽象同事類的子類;每一個同事對象在需要和其他同事對象通信時,先與中介者通信,通過中介者來間接完成與其他同事類的通信;在具體同事類中實現(xiàn)了在抽象同事類中聲明的抽象方法。

中介者模式的核心在于中介者類的引入,在中介者模式中,中介者類承擔(dān)了兩方面的職責(zé):

  • 中轉(zhuǎn)作用(結(jié)構(gòu)性):通過中介者提供的中轉(zhuǎn)作用,各個同事對象就不再需要顯式引用其他同事,當(dāng)需要和其他同事進(jìn)行通信時,可通過中介者來實現(xiàn)間接調(diào)用。該中轉(zhuǎn)作用屬于中介者在結(jié)構(gòu)上的支持。
  • 協(xié)調(diào)作用(行為性):中介者可以更進(jìn)一步的對同事之間的關(guān)系進(jìn)行封裝,同事可以一致的和中介者進(jìn)行交互,而不需要指明中介者需要具體怎么做,中介者根據(jù)封裝在自身內(nèi)部的協(xié)調(diào)邏輯,對同事的請求進(jìn)行進(jìn)一步處理,將同事成員之間的關(guān)系行為進(jìn)行分離和封裝。

開發(fā)中常見的場景

  • MVC模式(Controller 是中介者,根據(jù) View 層的請求來操作 Model 層)
  • 窗口游戲程序,窗口軟件開發(fā)中窗口對象也是一個中介者對象
  • 圖形界面開發(fā)GUI中,多個組件之間的交互,可以通過引入一個中介者對象來解決,可以是整體的窗口對象或者DOM對象
  • Java.lang.reflect.Method#invoke()

 

數(shù)據(jù)庫同步數(shù)據(jù)案例

我們來實現(xiàn)一個簡化版的數(shù)據(jù)同步方案,有三種數(shù)據(jù)庫 MysqlRedisElasticsearch

  • 其中的 Mysql 作為主數(shù)據(jù)庫,當(dāng)增加一條數(shù)據(jù)時需要同步到另外兩個數(shù)據(jù)庫中;
  • Redis 作為緩存數(shù)據(jù)庫,當(dāng)增加一條數(shù)據(jù)時不需要同步到另外另個數(shù)據(jù)庫;
  • 而 Elasticsearch 作為大數(shù)據(jù)查詢數(shù)據(jù)庫,有一個統(tǒng)計功能,當(dāng)增加一條數(shù)據(jù)時只需要同步到 Mysql,

所以它們之間的關(guān)系圖如下所示。

Java設(shè)計模式之java中介者模式詳解

 

不使用中介者模式的數(shù)據(jù)同步方案,各數(shù)據(jù)源維護(hù)各自的同步作業(yè)

抽象數(shù)據(jù)庫

public abstract class AbstractDatabase
{
    //存儲數(shù)據(jù)
    protected LinkedList<String> datas=new LinkedList<>();
    //向自己的數(shù)據(jù)庫中增加數(shù)據(jù)的方法
    public abstract void addData(String data);
    //同步數(shù)據(jù)的方法--默認(rèn)空實現(xiàn)
    public void DataStore(String data){}
    //展示當(dāng)前數(shù)據(jù)庫所有數(shù)據(jù)
    public void display()
    {
        datas.forEach(x->System.out.println(x));
    }
}

具體數(shù)據(jù)庫 Mysql,維護(hù)同步到 Redis和Elasticsearch 的同步作業(yè)

public class MySql extends AbstractDatabase
{
    @Setter
     private Elasticsearch elasticsearch;
    @Setter
    private Redis redis;
     //向自己的數(shù)據(jù)庫增加數(shù)據(jù)
    @Override
    public void addData(String data)
    {
        System.out.println("====向Mysql數(shù)據(jù)庫增加一條數(shù)據(jù)====");
        System.out.println("增加的數(shù)據(jù)為:"+data);
        System.out.println("=====================================");
        datas.add(data);
    }
     //重寫父類數(shù)據(jù)同步的方法
    @Override
    public void DataStore(String data)
    {
        addData(data);
        elasticsearch.addData(data);
        redis.addData(data);
    }
}

Elasticsearch ,只需要同步到Mysql

public class Elasticsearch  extends AbstractDatabase
{
    @Setter
    private  MySql mySql;
    //給自己增加數(shù)據(jù)的方法
    @Override
    public void addData(String data)
    {
        System.out.println("====向Elasticsearch數(shù)據(jù)庫增加一條數(shù)據(jù)====");
        System.out.println("增加的數(shù)據(jù)為:"+data);
        System.out.println("=====================================");
        datas.add(data);
    }
    //重寫父類數(shù)據(jù)同步的方法
    @Override
    public void DataStore(String data) {
        addData(data);
        //數(shù)據(jù)同步
        mySql.addData(data);
    }
}

具體數(shù)據(jù)庫 Redis,不需要同步到其它數(shù)據(jù)庫

public class Redis extends AbstractDatabase
{
 //給自己增加數(shù)據(jù)的方法
    @Override
    public void addData(String data)
    {
        System.out.println("====向Redis數(shù)據(jù)庫增加一條數(shù)據(jù)====");
        System.out.println("增加的數(shù)據(jù)為:"+data);
        System.out.println("=====================================");
        datas.add(data);
    }
}

客戶端測試:

public class Client
{
    public static void main(String[] args) {
        Elasticsearch elasticsearch=new Elasticsearch();
        MySql mySql=new MySql();
        Redis redis=new Redis();
        elasticsearch.setMySql(mySql);
        mySql.setElasticsearch(elasticsearch);
        mySql.setRedis(redis);
        //增加數(shù)據(jù)
        mySql.DataStore("大忽悠");
        elasticsearch.DataStore("李窈");
        redis.addData("小朋友");
        System.out.println("mysql數(shù)據(jù)庫中的數(shù)據(jù)如下:");
        mySql.display();
        System.out.println("elasticsearch數(shù)據(jù)庫中的數(shù)據(jù)如下:");
        elasticsearch.display();
        System.out.println("redis數(shù)據(jù)庫中數(shù)據(jù)如下:");
        redis.display();
    }
}

Java設(shè)計模式之java中介者模式詳解

 

其實這樣已經(jīng)實現(xiàn)了我們的需求,但是存在一些問題

  • 系統(tǒng)結(jié)構(gòu)復(fù)雜且耦合度高。數(shù)據(jù)源需要維護(hù)目標(biāo)端數(shù)據(jù)庫的引用,以便完成數(shù)據(jù)同步
  • 組件的可重用性差。由于每一個數(shù)據(jù)源和目標(biāo)端之間具有很強(qiáng)的關(guān)聯(lián),若沒有目標(biāo)端的支持,這個組件很難被另一個系統(tǒng)或模塊重用
  • 系統(tǒng)的可擴(kuò)展性差:如果需要增加、修改或刪除其中一個數(shù)據(jù)庫、將導(dǎo)致多個類的源代碼需要修改,這違反了“開閉原則”,可擴(kuò)展性和靈活性欠佳。

 

中介者模式來重構(gòu),將數(shù)據(jù)同步的功能遷移到中介者中,由中介者來管理數(shù)據(jù)同步作業(yè)

抽象中介者:

//抽象中介者
@Data
public abstract class AbstractMediator {
    protected MySql mySql;
    protected Elasticsearch elasticsearch;
    protected Redis redis;
    public abstract void sync(String databaseName, String data);
}

首先還是抽象數(shù)據(jù)庫類(抽象同事類),維護(hù)了一個中介者

public abstract class AbstractDatabase
{
    public static final String MYSQL="mysql";
    public static final String Elasticsearch="elasticsearch";
    public static final String REDIS="redis";
    //保存一個中介者對象
    @Setter
    protected AbstractMediator Mediator;
    //存儲數(shù)據(jù)
    protected LinkedList<String> datas=new LinkedList<>();
    //向自己的數(shù)據(jù)庫中增加數(shù)據(jù)的方法
    public abstract void addData(String data);
    //同步數(shù)據(jù)的方法--默認(rèn)空實現(xiàn)
    public void DataStore(String data){}
    //展示當(dāng)前數(shù)據(jù)庫所有數(shù)據(jù)
    public void display()
    {
        datas.forEach(x->System.out.println(x));
    }
}

Mysql 數(shù)據(jù)庫(具體同事類)

public class MySql extends AbstractDatabase
{
     //向自己的數(shù)據(jù)庫增加數(shù)據(jù)
    @Override
    public void addData(String data)
    {
        System.out.println("====向Mysql數(shù)據(jù)庫增加一條數(shù)據(jù)====");
        System.out.println("增加的數(shù)據(jù)為:"+data);
        System.out.println("=====================================");
        datas.add(data);
    }
     //重寫父類數(shù)據(jù)同步的方法
    @Override
    public void DataStore(String data)
    {
        addData(data);
       //將數(shù)據(jù)同步到redis和elasticsearch的工作由中介完成
        mediator.sync(AbstractDatabase.MYSQL,data);
    }
}

Redis 數(shù)據(jù)庫(具體同事類)

public class Redis extends AbstractDatabase
{
 //給自己增加數(shù)據(jù)的方法
    @Override
    public void addData(String data)
    {
        System.out.println("====向Redis數(shù)據(jù)庫增加一條數(shù)據(jù)====");
        System.out.println("增加的數(shù)據(jù)為:"+data);
        System.out.println("=====================================");
        datas.add(data);
    }
 //重新父類同步數(shù)據(jù)的方法
    @Override
    public void DataStore(String data) {
        addData(data);
        //同步數(shù)據(jù)的工作交給中介
        mediator.sync(AbstractDatabase.REDIS,data);
    }
}

Elasticsearch(具體同事類)

public class Elasticsearch  extends AbstractDatabase
{
    //給自己增加數(shù)據(jù)的方法
    @Override
    public void addData(String data)
    {
        System.out.println("====向Elasticsearch數(shù)據(jù)庫增加一條數(shù)據(jù)====");
        System.out.println("增加的數(shù)據(jù)為:"+data);
        System.out.println("=====================================");
        datas.add(data);
    }
    //重寫父類數(shù)據(jù)同步的方法
    @Override
    public void DataStore(String data) {
        addData(data);
        //數(shù)據(jù)同步
        mediator.sync(AbstractDatabase.Elasticsearch,data);
    }
}

具體中介者:

public class SyncMediator extends AbstractMediator {
    @Override
    public void sync(String databaseName, String data) {
        if (AbstractDatabase.MYSQL.equals(databaseName)) {
            // mysql 同步到 redis 和 Elasticsearch
            this.redis.addData(data);
            this.elasticsearch.addData(data);
        } else if (AbstractDatabase.REDIS.equals(databaseName)) {
            // redis 緩存同步,不需要同步到其他數(shù)據(jù)庫
        } else if (AbstractDatabase.Elasticsearch.equals(databaseName)) {
            // Elasticsearch 同步到 Mysql
            this.mySql.addData(data);
        }
    }
}

測試客戶端

public class Client
{
    public static void main(String[] args) {
        AbstractMediator mediator=new SyncMediator();

        Elasticsearch elasticsearch=new Elasticsearch();
        MySql mySql=new MySql();
        Redis redis=new Redis();

        elasticsearch.setMediator(mediator);
        mySql.setMediator(mediator);
        redis.setMediator(mediator);
        mediator.setMySql(mySql);
        mediator.setElasticsearch(elasticsearch);
        mediator.setRedis(redis);

        //增加數(shù)據(jù)
        mySql.DataStore("大忽悠");
        elasticsearch.DataStore("李窈");
        redis.DataStore("小朋友");
        System.out.println("mysql數(shù)據(jù)庫中的數(shù)據(jù)如下:");
        mySql.display();
        System.out.println("elasticsearch數(shù)據(jù)庫中的數(shù)據(jù)如下:");
        elasticsearch.display();
        System.out.println("redis數(shù)據(jù)庫中數(shù)據(jù)如下:");
        redis.display();
    }
}

Java設(shè)計模式之java中介者模式詳解

 

小結(jié)

 

主要優(yōu)點

  • 中介者模式簡化了對象之間的交互,它用中介者和同事的一對多交互代替了原來同事之間的多對多交互,一對多關(guān)系更容易理解、維護(hù)和擴(kuò)展,將原本難以理解的網(wǎng)狀結(jié)構(gòu)轉(zhuǎn)換成相對簡單的星型結(jié)構(gòu)。
  • 中介者模式可將各同事對象解耦。中介者有利于各同事之間的松耦合,我們可以獨立的改變和復(fù)用每一個同事和中介者,增加新的中介者和新的同事類都比較方便,更好地符合 “開閉原則”。
  • 可以減少子類生成,中介者將原本分布于多個對象間的行為集中在一起,改變這些行為只需生成新的中介者子類即可,這使各個同事類可被重用,無須對同事類進(jìn)行擴(kuò)展。

 

中介者模式的主要缺點

  • 在具體中介者類中包含了大量同事之間的交互細(xì)節(jié),可能會導(dǎo)致具體中介者類非常復(fù)雜,使得系統(tǒng)難以維護(hù)。(也就是把具體同事類之間的交互復(fù)雜性集中到了中介者類中,結(jié)果中介者成了最復(fù)雜的類)

 

適用場景

  • 系統(tǒng)中對象之間存在復(fù)雜的引用關(guān)系,系統(tǒng)結(jié)構(gòu)混亂且難以理解。
  • 一個對象由于引用了其他很多對象并且直接和這些對象通信,導(dǎo)致難以復(fù)用該對象。
  • 想通過一個中間類來封裝多個類中的行為,而又不想生成太多的子類。可以通過引入中介者類來實現(xiàn),在中介者中定義對象交互的公共行為,如果需要改變行為則可以增加新的具體中介者類

 

具體應(yīng)用

 

Java Timer 中的中介者模式

敲一個 java.util.Timer 的Demo

兩個任務(wù)類

public class MyOneTask extends TimerTask {
    private static int num = 0;
    @Override
    public void run() {
        System.out.println("I"m MyOneTask " + ++num);
    }
}
public class MyTwoTask extends TimerTask {
    private static int num = 1000;
    @Override
    public void run() {
        System.out.println("I"m MyTwoTask " + num--);
    }
}

客戶端測試,3秒后開始執(zhí)行,循環(huán)周期為 1秒

public class TimerTest {
    public static void main(String[] args) {
        // 注意:多線程并行處理定時任務(wù)時,Timer運行多個TimeTask時,只要其中之一沒有捕獲拋出的異常,
        // 其它任務(wù)便會自動終止運行,使用ScheduledExecutorService則沒有這個問題
        Timer timer = new Timer();
        timer.schedule(new MyOneTask(), 3000, 1000); // 3秒后開始運行,循環(huán)周期為 1秒
        timer.schedule(new MyTwoTask(), 3000, 1000);
    }
}

Timer 的部分關(guān)鍵源碼如下

public class Timer {
    private final TaskQueue queue = new TaskQueue();
    private final TimerThread thread = new TimerThread(queue);
    public void schedule(TimerTask task, long delay) {
        if (delay < 0)
            throw new IllegalArgumentException("Negative delay.");
        sched(task, System.currentTimeMillis()+delay, 0);
    }
    public void schedule(TimerTask task, Date time) {
        sched(task, time.getTime(), 0);
    }
    private void sched(TimerTask task, long time, long period) {
        if (time < 0)
            throw new IllegalArgumentException("Illegal execution time.");
        if (Math.abs(period) > (Long.MAX_VALUE >> 1))
            period >>= 1;
        // 獲取任務(wù)隊列的鎖(同一個線程多次獲取這個鎖并不會被阻塞,不同線程獲取時才可能被阻塞)
        synchronized(queue) {
            // 如果定時調(diào)度線程已經(jīng)終止了,則拋出異常結(jié)束
            if (!thread.newTasksMayBeScheduled)
                throw new IllegalStateException("Timer already cancelled.");
            // 再獲取定時任務(wù)對象的鎖(為什么還要再加這個鎖呢?想不清)
            synchronized(task.lock) {
                // 判斷線程的狀態(tài),防止多線程同時調(diào)度到一個任務(wù)時多次被加入任務(wù)隊列
                if (task.state != TimerTask.VIRGIN)
                    throw new IllegalStateException(
                        "Task already scheduled or cancelled");
                // 初始化定時任務(wù)的下次執(zhí)行時間
                task.nextExecutionTime = time;
                // 重復(fù)執(zhí)行的間隔時間
                task.period = period;
                // 將定時任務(wù)的狀態(tài)由TimerTask.VIRGIN(一個定時任務(wù)的初始化狀態(tài))設(shè)置為TimerTask.SCHEDULED
                task.state = TimerTask.SCHEDULED;
            }
            // 將任務(wù)加入任務(wù)隊列
            queue.add(task);
            // 如果當(dāng)前加入的任務(wù)是需要第一個被執(zhí)行的(也就是他的下一次執(zhí)行時間離現(xiàn)在最近)
            // 則喚醒等待queue的線程(對應(yīng)到上面提到的queue.wait())
            if (queue.getMin() == task)
                queue.notify();
        }
    }
    // cancel會等到所有定時任務(wù)執(zhí)行完后立刻終止定時線程
    public void cancel() {
        synchronized(queue) {
            thread.newTasksMayBeScheduled = false;
            queue.clear();
            queue.notify();  // In case queue was already empty.
        }
    }
    // ...
}

Timer 中在 schedulexxx 方法中通過 TaskQueue 協(xié)調(diào)各種 TimerTask 定時任務(wù),Timer 是中介者,TimerTask 是抽象同事類,而我們自己寫的任務(wù)則是具體同事類

TimerThread Timer 中定時調(diào)度線程類的定義,這個類會做為一個線程一直運行來執(zhí)行 Timer 中任務(wù)隊列中的任務(wù)。

Timer 這個中介者的功能就是定時調(diào)度我們寫的各種任務(wù),將任務(wù)添加到 TaskQueue 任務(wù)隊列中,給 TimerThread 執(zhí)行,讓任務(wù)與執(zhí)行線程解耦

 

參考文章

設(shè)計模式之中介者模式

23種設(shè)計模式(7):中介者模式

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注服務(wù)器之家的更多內(nèi)容!

原文鏈接:https://blog.csdn.net/m0_53157173/article/details/120212092

延伸 · 閱讀

精彩推薦
  • Java教程Java BufferWriter寫文件寫不進(jìn)去或缺失數(shù)據(jù)的解決

    Java BufferWriter寫文件寫不進(jìn)去或缺失數(shù)據(jù)的解決

    這篇文章主要介紹了Java BufferWriter寫文件寫不進(jìn)去或缺失數(shù)據(jù)的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望...

    spcoder14552021-10-18
  • Java教程小米推送Java代碼

    小米推送Java代碼

    今天小編就為大家分享一篇關(guān)于小米推送Java代碼,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧...

    富貴穩(wěn)中求8032021-07-12
  • Java教程升級IDEA后Lombok不能使用的解決方法

    升級IDEA后Lombok不能使用的解決方法

    最近看到提示IDEA提示升級,尋思已經(jīng)有好久沒有升過級了。升級完畢重啟之后,突然發(fā)現(xiàn)好多錯誤,本文就來介紹一下如何解決,感興趣的可以了解一下...

    程序猿DD9332021-10-08
  • Java教程xml與Java對象的轉(zhuǎn)換詳解

    xml與Java對象的轉(zhuǎn)換詳解

    這篇文章主要介紹了xml與Java對象的轉(zhuǎn)換詳解的相關(guān)資料,需要的朋友可以參考下...

    Java教程網(wǎng)2942020-09-17
  • Java教程Java使用SAX解析xml的示例

    Java使用SAX解析xml的示例

    這篇文章主要介紹了Java使用SAX解析xml的示例,幫助大家更好的理解和學(xué)習(xí)使用Java,感興趣的朋友可以了解下...

    大行者10067412021-08-30
  • Java教程Java實現(xiàn)搶紅包功能

    Java實現(xiàn)搶紅包功能

    這篇文章主要為大家詳細(xì)介紹了Java實現(xiàn)搶紅包功能,采用多線程模擬多人同時搶紅包,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙...

    littleschemer13532021-05-16
  • Java教程Java8中Stream使用的一個注意事項

    Java8中Stream使用的一個注意事項

    最近在工作中發(fā)現(xiàn)了對于集合操作轉(zhuǎn)換的神器,java8新特性 stream,但在使用中遇到了一個非常重要的注意點,所以這篇文章主要給大家介紹了關(guān)于Java8中S...

    阿杜7482021-02-04
  • Java教程20個非常實用的Java程序代碼片段

    20個非常實用的Java程序代碼片段

    這篇文章主要為大家分享了20個非常實用的Java程序片段,對java開發(fā)項目有所幫助,感興趣的小伙伴們可以參考一下 ...

    lijiao5352020-04-06
675
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25
主站蜘蛛池模板: 国产91亚洲精品一区二区三区 | 亚洲精品日韩欧美 | 日韩精品一区二区免费视频 | 国产精品久久久久久久久久久久午夜 | 18欧美性xxxx极品hd | 日韩欧美视频一区二区三区 | 久久久精品综合 | 国内精品久久久久久久影视红豆 | 国产精品久久久久久久亚洲按摩 | 久久精品片 | 永久久久 | 亚洲一区二区免费 | 日韩精品久久一区二区三区 | 免费毛片电影 | 欧美一级做一级爱a做片性 毛片电影网址 | 久久综合久久综合久久综合 | 一级黄色影院 | 欧美精品一级 | 91av久久| 国产日本在线 | 欧美激情天堂 | 亚洲99影视一区二区三区 | 久久久久久亚洲综合影院红桃 | 最近日本电影hd免费观看 | 视频一区二区三区免费观看 | 久久久久亚洲视频 | 91性高湖久久久久久久久网站 | 亚洲第一成人久久网站 | 成人免费一区二区三区视频网站 | 天天看天天摸天天操 | 久久成人视屏 | 亚洲欧美日韩久久精品第一区 | 在线播放免费人成毛片乱码 | h色在线观看 | 视频一区二区中文字幕 | av国语 | 99精美视频 | 136福利视频 | 成人三区四区 | 亚洲欧美日韩精品久久亚洲区 | 黄色毛片免费视频 |