青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

積木

No sub title

  C++博客 :: 首頁 :: 聯系 :: 聚合  :: 管理
  140 Posts :: 1 Stories :: 11 Comments :: 0 Trackbacks

常用鏈接

留言簿(1)

我參與的團隊

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

轉載自:http://patmusing.blog.163.com/blog/static/13583496020101410329439/


Proxy also a.k.a. Surrogate

對于復雜的軟件系統常常有一種處理手法,即增加一層間接層,從而使得系統獲得一種更為靈活、滿足特定需求的解決方案。在面向對象的系統中,有些對象由于某種原因,比如對象創建的開銷很大,或者某些操作需要安全控制,或者需要進程外的訪問等,直接訪問會給使用者或者系統結構帶來很多麻煩。

Proxy設計模式就是在不失去透明操作對象的同時,通過增加一層間接層來管理、控制這些對象特有的復雜性。

14. C++實現Structural - Proxy模式  - 玄機逸士 - 玄機逸士博客

1

14. C++實現Structural - Proxy模式  - 玄機逸士 - 玄機逸士博客

2

表示不同的進程

1中假定AB位于不同的進程,典型的情況是AB位于互聯網上兩臺不同的機器上,如果A要訪問B三次,那么A就要如上圖調用B三次。

2中增加一個B的代理,該代理和A位于同一個進程內,當A要調用B的功能時,A僅需要調用B的代理即可,然后B的代理和B之間進行通信。另外如果A3次調用B的功能,那么A僅需要3此調用B的代理即可,而B的代理和B之間有可能只需要一次通信就夠了,由此可見,B的代理有一定的緩沖功能。

Provide a surrogate or placeholder for another object to control access to it. (為其他對象提供一種代理以控制對這個對象的訪問) -GoF

Proxy設計模式之靜態結構UML類圖:

14. C++實現Structural - Proxy模式  - 玄機逸士 - 玄機逸士博客

3

說明:

Service

The interface that both the proxy and the real object will implement. (代理和實際對象必須實現的接口)

ServiceProxy

ServiceProxy implements Service and forwards method calls to the real object (ServiceImplemention) when appropriate.

(ServiceProxy實現了Service接口,并在合適的時候,將請求傳遞給實際對象ServiceImplementation)

ServiceImplementation

The real, full implementation of the interface. This object will be represented by the Proxy object.

(真正、完整的接口實現,該對象由Proxy對象代表)

A proxy (or stub) is a representative for another object. To enable the proxy to represent the real object, the proxy has to implement the exact same interface as the real object. Furthermore, the proxy keeps a reference to the real object. The proxy needs the reference to the real object so that it can call methods on the real object if necessary. The clients will be interacting with the proxy, but the proxy can delegate the execution to the real object. The proxy implements the same interface as the real object, but can perform tasks that the real object does not, such as remote communication or security.

Use the Proxy pattern when you need a more elaborate reference to an object instead of just a regular one:

- Remote proxy: When you need a local representative for an object in another address space(e.g. JVM)

- Virtual proxy: Acts as a placeholder and delays creating expensive objects.

- Protection proxy: Determines access rights to the real object.

Remote Proxy C++模擬代碼

// Proxy.h

#include <string>

#include <iostream>

#include <string>

using namespace std;

class IEmployee

{

public:

virtual string get_name(int ID) = 0;

virtual int get_age(int ID) = 0;

virtual double get_salary(int ID) = 0;

public:

virtual ~IEmployee();

};

IEmployee::~IEmployee()

{

cout << "in the destructor of IEmployee..." << endl;

}

class Employee : public IEmployee

{

public:

string get_name(int ID);

int get_age(int ID);

double get_salary(int ID);

~Employee();

};

string Employee::get_name(int ID)

{

// ... 假定此處查詢數據庫,獲得ID對應員工的姓名

string name = "玄機逸士";

return name;

}

int Employee::get_age(int ID)

{

// ... 假定此處查詢數據庫,獲得ID對應員工的年齡

int age = 27;

return age;

}

double Employee::get_salary(int ID)

{

// ... 假定此處查詢數據庫,獲得ID對應員工的工資

double salary = 50000.1;

return salary;

}

Employee::~Employee()

{

cout << "in the destructor of Employee..." << endl;

}

class EmployeeProxy : public IEmployee

{

public:

string get_name(int ID);

int get_age(int ID);

double get_salary(int ID);

~EmployeeProxy();

};

string EmployeeProxy::get_name(int ID)

{

// ...假定此處通過socket或者RPC等其他方式訪問Employee中的get_name(int ID)方法,并接受相應的返回值

string name = "玄機逸士";

return name;

}

int EmployeeProxy::get_age(int ID)

{

// ...假定此處通過socket或者RPC等其他方式訪問Employee中的get_age(int ID)方法,并接受相應的返回值

int age = 27;

return age;

}

double EmployeeProxy::get_salary(int ID)

{

// ...假定此處通過socket或者RPC等其他方式訪問Employee中的get_salary(int ID)方法,并接受相應的返回值

double salary = 50000.1;

return salary;

}

EmployeeProxy::~EmployeeProxy()

{

cout << "in the destructor of EmployeeProxy..." << endl;

}

// Proxy.cpp

#include "Proxy.h"

int main(int argc, char **argv)

{

IEmployee *employee = new EmployeeProxy;

cout << employee->get_name(10) << endl;

cout << employee->get_age(10) << endl;

cout << employee->get_salary(10) << endl;

delete employee;

return 0;

}

輸出結果:

玄機逸士

27

50000.1

in the destructor of EmployeeProxy…

in the destructor of IEmployee…

說明:

- IEmployee是接口,相當于圖3中的Service

- Employee是在遠程地址空間中對接口IEmployee的實現;

- EmployeeProxy是在本地地址空間中對IEmployee的實現,同時它通過網絡依賴Employee

- main函數(HRSystem)是客戶程序。它向EmployeeProxy發出請求,EmployeeProxy得到HRSystem發出的請求后,通過網絡將請求提交給遠程的EmployeeEmployee接受請求并做出相關處理,將處理的結果返回給EmployeeProxyEmployeeProxy將結果返回給HRSystem

14. C++實現Structural - Proxy模式  - 玄機逸士 - 玄機逸士博客

4

* 要完整實現一個Remote Proxy需要比較多的代碼,在此就用程序中的部分注釋來代替了。

Virtual Proxy C++示例代碼

// Proxy.h

#define FILENAME "contacts.cbf"

// 一個簡單的聯系人類

class Contact

{

private:

string name;

string email;

public:

Contact()

{

}

Contact(string name, string email) : name(name), email(email)

{

}

~Contact()

{

cout << "in the destructor of Contact..." << endl;

}

public:

// 下面幾個成員函數都是getter

string get_name() const

{

return name;

}

string get_email() const

{

return email;

}

};

// 聯絡本:一個抽象類,用作接口,它規定了聯絡本的相關方法

class IContactBook

{

protected:

public:

virtual void add(const Contact& contact) = 0; // 增加一個聯系人

virtual vector<Contact> get_contact(const string& name) = 0; // 查詢聯系人,有可能重名

virtual multimap<string, Contact> get_all_contacts() = 0; // 獲取所有聯系人

virtual void save() = 0; // 保存數據

public:

virtual ~IContactBook()

{

cout << "in the destructor of IContactBook..." << endl;

}

};

// ContactBook繼承IContactBook,該類實現了IContactBook中所有規定的方法,

// 它是一個“real object”(真實對象),將由ContactBookProxy來代理

class ContactBook : public IContactBook

{

private:

multimap<string, Contact> contacts;

public:

ContactBook()

{

Contact *contact = new Contact;

ifstream file(FILENAME, ios::in|ios::binary); // 打開文件

if(!file)

{

cout << "can not open file..." << endl;

return;

}

Else // 將文件中的數據讀入contacts

{

file.seekg (0, ios::end);

int length = file.tellg();

file.seekg (0, ios::beg);

int element_number = length / sizeof(Contact);

cout << "element_number = " << element_number << endl;

for(int i = 0; i < element_number; i++)

{

file.seekg(sizeof(Contact) * i, ios::beg);

file.read((char *)contact, sizeof(Contact));

contacts.insert(pair<string, Contact>(contact->get_name(), *contact));

}

}

file.close();

delete contact;

contact = 0;

}

~ContactBook()

{

//save();

cout << "in the destructor of ContactBook..." << endl;

}

public:

// 根據名字獲取聯系人,由于有可能重名,因此返回值是一個vector<Contact>

vector<Contact> get_contact(const string& name)

{

multimap<string, Contact>::iterator it;

pair<multimap<string, Contact>::iterator, multimap<string, Contact>::iterator> ret;

ret = contacts.equal_range(name);

vector<Contact> contact_found;

for(it = ret.first; it != ret.second; it++)

{

contact_found.push_back(it->second);

}

return contact_found;

}

// 增加一個聯系人

void add(const Contact& contact)

{

string email;

vector<Contact> vcontact = get_contact(contact.get_name());

// 如果multimap contacts中不存在該聯系人

if(vcontact.empty())

{

// 則將聯系人contact加入到multimap中,聯系人contactname作為key

contacts.insert(pair<string, Contact>(contact.get_name(), contact));

}

else // 同名的聯系人

{

email = contact.get_email();

int i = 0;

for(vector<Contact>::iterator it = vcontact.begin(); it != vcontact.end(); it++)

{

if(!(email == it->get_email())) // 同名的聯系人,但email不同。在這里,

{ // 我們假定email是唯一的,實際情況大多如此

i++;

}

}

if(i == vcontact.size()) // 和找出來所有同名的人的email地址都不一樣

{

contacts.insert(pair<string, Contact>(contact.get_name(), contact));

return;

}

}

}

// contacts中的所有聯系人存入到文件中

void save()

{

ofstream file(FILENAME, ios::out|ios::binary);

if(!file)

{

cout << "can not open file..." << endl;

return;

}

for(multimap<string, Contact>::iterator it = contacts.begin(); it != contacts.end(); it++)

{

file.write((const char *)(&(it->second)), sizeof(Contact));

}

file.close();

}

// 獲取所有聯系人

multimap<string, Contact> get_all_contacts()

{

return contacts;

}

// 一個輔助函數,將被Proxy調用

void set_contacts(const multimap<string, Contact>& lcontacts)

{

contacts.erase(contacts.begin(), contacts.end());

contacts = lcontacts;

}

};

// 代理

class ContactBookProxy : public IContactBook

{

private:

IContactBook *contact_book; // 存放真實對象

multimap<string, Contact> local_contacts; // 本地聯系人數據

public:

ContactBookProxy()

{

contact_book = new ContactBook; // 創建真實對象

local_contacts = contact_book->get_all_contacts(); // 將真實對象中的數據取到本地

delete contact_book; // 取出數據后,立即銷毀真實對象

contact_book = 0; // 此后,均指操作本地聯系人數據local_contacts

}

~ContactBookProxy()

{

cout << "in the destructor of ContactBookProxy..." << endl;

if(!contact_book)

{

delete contact_book;

contact_book = 0;

}

}

vector<Contact> get_contact(const string& name)

{

// 只操作本地數據local_contacts,因為此時local_contacts已經包含了真實對象中的所有數據

multimap<string, Contact>::iterator it;

pair<multimap<string, Contact>::iterator, multimap<string, Contact>::iterator> ret;

ret = local_contacts.equal_range(name);

vector<Contact> contact_found;

for(it = ret.first; it != ret.second; it++)

{

contact_found.push_back(it->second);

}

return contact_found;

}

void add(const Contact& contact)

{

string email;

vector<Contact> vcontact = get_contact(contact.get_name());

// 如果multimap contacts中不存在該聯系人

if(vcontact.empty())

{

// 則將聯系人contact加入到multimap中,聯系人contactname作為key

local_contacts.insert(pair<string, Contact>(contact.get_name(), contact));

}

else // 同名的聯系人

{

email = contact.get_email();

int i = 0;

for(vector<Contact>::iterator it = vcontact.begin(); it != vcontact.end(); it++)

{

if(!(email == it->get_email())) // 同名的聯系人,但email不同。在這里,

{ // 我們假定email是唯一的,實際情況大多如此

i++;

}

}

if(i == vcontact.size()) // 和找出來所有同名的人的email地址都不一樣

{

local_contacts.insert(pair<string, Contact>(contact.get_name(), contact));

return;

}

}

}

void save()

{

if(!contact_book)

{

contact_book = new ContactBook;

}

ContactBook *cb = dynamic_cast<ContactBook*>(contact_book); // down casting

cb->set_contacts(local_contacts);

contact_book->save();

}

multimap<string, Contact> get_all_contacts()

{

return local_contacts;

}

};

// Proxy.cpp

int main(int argc, char **argv)

{

IContactBook *contact_proxy = new ContactBookProxy;

contact_proxy->add(Contact("玄機逸士", "xjys@pnft.com"));

contact_proxy->add(Contact("玄機逸士", "xjys@pnft.com"));

contact_proxy->add(Contact("上官天野", "sgty@pnft.com"));

contact_proxy->add(Contact("上官天野", "sgty1@pnft.com"));

contact_proxy->add(Contact("上官天野", "sgty2@pnft.com"));

contact_proxy->add(Contact("黃家四娘", "hjsn@pnft.com"));

contact_proxy->save();

vector<Contact> vec_contact = contact_proxy->get_contact("上官天野");

for(vector<Contact>::const_iterator it = vec_contact.begin(); it != vec_contact.end(); it++)

{

cout << it->get_name() << " : " << it->get_email() << endl;

}

cout << "------------------------------------" << endl;

multimap<string, Contact> map_all_contacts(contact_proxy->get_all_contacts());

for(multimap<string, Contact>::iterator it = map_all_contacts.begin(); it != map_all_contacts.end(); it++)

{

cout << it->first << " : " << (it->second).get_email() << endl;

}

delete contact_proxy;

return 0;

}

輸出結果:

element_number = 5

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of ContactBook...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of IContactBook...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

element_number = 5

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

上官天野 : sgty@pnft.com

上官天野 : sgty1@pnft.com

上官天野 : sgty2@pnft.com

------------------------------------

黃家四娘 : hjsn@pnft.com

上官天野 : sgty@pnft.com

上官天野 : sgty1@pnft.com

上官天野 : sgty2@pnft.com

玄機逸士 : xjys@pnft.com

in the destructor of ContactBookProxy...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of IContactBook...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

in the destructor of Contact...

上述代碼的要點是:首先將真實對象中的數據拷貝到代理,并立即銷毀真實對象,然后客戶端程序一直對代理進行操作,直到所需要的操作完成后,將代理中的結果返回給真實對象,并由真實對象保存到文件中。嚴格地說,這個示例代碼并不是真正意義上的Virtual Proxy,因為它并沒有延遲真實對象的創建。不過要實現真正意義上Virtual Proxy也并不困難。

Protection proxy的示例代碼,和前面的代碼差不多,只是在proxy的成員函數在調用與之對應的真實對象的成員函數之前,進行保護性檢查。如果通過了檢查則調用真實對象的對應成員函數,否則,不調用并提示相關信息。具體代碼略。



posted on 2013-03-07 23:43 Jacc.Kim 閱讀(266) 評論(0)  編輯 收藏 引用 所屬分類: 設計模式
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久精品国亚洲| 亚洲欧美日韩区| 欧美成人精品1314www| 亚洲国产精品悠悠久久琪琪| 亚洲精品国精品久久99热一| 欧美经典一区二区三区| 99精品国产福利在线观看免费 | 国产精品毛片| 欧美一区二区精品在线| 免费成人黄色片| 亚洲精品无人区| 国产精品久久久一区麻豆最新章节| 亚洲午夜高清视频| 久久久噜噜噜久久久| 亚洲精品网址在线观看| 国产精品久久一卡二卡| 久久久久国产精品厨房| 99国产精品久久久久老师| 久久精品亚洲热| 亚洲国产综合视频在线观看| 欧美日精品一区视频| 欧美中在线观看| 亚洲精品麻豆| 久久久亚洲国产美女国产盗摄| 亚洲精品永久免费精品| 国产伦精品一区二区三区免费 | 一区二区久久| 久久这里只有| 亚洲天堂成人在线观看| 黄色工厂这里只有精品| 欧美日韩一区二区在线观看视频| 久久不射网站| 99精品视频免费| 蜜桃久久av一区| 先锋影音网一区二区| 亚洲精品综合久久中文字幕| 国产欧美欧美| 欧美三日本三级少妇三2023| 久久久免费av| 午夜精品福利电影| 9色国产精品| 欧美好骚综合网| 久久精品免费播放| 亚洲天堂av电影| 亚洲日本中文字幕免费在线不卡| 国产一区二区三区四区| 国产精品久久91| 欧美日韩精品| 欧美成人精品1314www| 久久精品72免费观看| 亚洲欧美国产精品桃花| 亚洲另类春色国产| 亚洲电影在线| 欧美91视频| 美女爽到呻吟久久久久| 久久精品日韩欧美| 羞羞色国产精品| 亚洲一区3d动漫同人无遮挡| 亚洲精品影视| 亚洲精品在线观| 亚洲人成在线播放网站岛国| 在线色欧美三级视频| 国内成人精品2018免费看 | 久久久一区二区三区| 香蕉av福利精品导航| 亚洲欧美精品在线| 亚洲欧美激情四射在线日 | 亚洲网友自拍| 亚洲午夜av电影| 一本色道久久综合| 国产精品99久久久久久www| 亚洲乱码国产乱码精品精可以看| 亚洲黄色av一区| 亚洲片国产一区一级在线观看| 亚洲高清久久| 亚洲精品国产精品乱码不99按摩 | 欧美日韩在线播放三区| 欧美日本韩国一区| 欧美性大战久久久久| 国产精品欧美风情| 国产欧美日本一区二区三区| 国产一区二区三区精品久久久| 国产一区二区三区久久久久久久久| 国产一区二区三区久久悠悠色av| 国产一区二区视频在线观看 | 欧美一区二区三区另类| 欧美一级淫片播放口| 久久九九电影| 欧美激情第三页| 亚洲肉体裸体xxxx137| 日韩一区二区电影网| 亚洲一区二区三区高清不卡| 亚洲欧美日韩精品一区二区| 久久国产精品久久久久久电车| 久久久999成人| 欧美成人免费全部| 欧美性事在线| 国产一区二区三区高清在线观看| 在线观看欧美精品| 中文在线不卡| 久久狠狠亚洲综合| 欧美激情视频在线播放 | 久久精品视频va| 欧美好吊妞视频| 亚洲视频碰碰| 久久久www| 欧美日本中文| 国产婷婷色一区二区三区在线| 亚洲福利在线观看| 亚洲先锋成人| 久久亚洲影院| 亚洲免费av网站| 欧美亚洲系列| 欧美日韩国产一区二区| 国产亚洲一区精品| 日韩午夜中文字幕| 久久久91精品国产一区二区精品| 欧美激情网友自拍| 午夜精品剧场| 欧美日韩高清在线一区| 好看的av在线不卡观看| 亚洲伊人第一页| 美女网站在线免费欧美精品| 亚洲视频免费观看| 你懂的亚洲视频| 国产日韩精品一区| 亚洲婷婷国产精品电影人久久| 另类春色校园亚洲| 亚洲伊人伊色伊影伊综合网| 欧美国产第一页| 激情偷拍久久| 欧美一二三区精品| 亚洲福利视频二区| 欧美一区二区三区免费观看视频 | 亚洲激情精品| 久久精品国产一区二区三区免费看| 欧美婷婷六月丁香综合色| 亚洲国产高清自拍| 久久久国产一区二区| 亚洲性人人天天夜夜摸| 欧美精品免费观看二区| 亚洲国产精品va在看黑人| 久久精品72免费观看| 在线一区亚洲| 欧美日韩亚洲综合在线| 亚洲精品之草原avav久久| 美女黄网久久| 久久精品国产亚洲5555| 国产日韩一区二区三区| 午夜久久tv| 亚洲少妇自拍| 国产精品豆花视频| 亚洲一区www| 日韩一级在线观看| 欧美日韩国产色站一区二区三区| 亚洲国产日韩欧美一区二区三区| 久久亚洲二区| 久久亚洲综合| 伊人久久成人| 欧美黄色视屏| 欧美成人精品h版在线观看| 亚洲人成在线观看| 亚洲国内自拍| 欧美精品电影在线| 亚洲视屏在线播放| 在线综合亚洲| 国产精品女主播在线观看| 香蕉乱码成人久久天堂爱免费 | 狠狠干狠狠久久| 久久综合精品一区| 久久久综合香蕉尹人综合网| 狠狠久久亚洲欧美专区| 欧美a级大片| 欧美成人免费网| 正在播放亚洲| 亚洲午夜激情| 国产一区导航| 欧美成人一区二区三区在线观看| 麻豆9191精品国产| 亚洲美女尤物影院| 一区二区三区日韩欧美| 国产欧美一区二区视频| 久久久爽爽爽美女图片| 久久免费视频观看| 亚洲免费观看高清完整版在线观看| 亚洲精品国产精品国自产观看| 欧美日韩美女| 久久av红桃一区二区小说| 久久久亚洲国产天美传媒修理工| 亚洲日本成人| 在线综合视频| 揄拍成人国产精品视频| 亚洲人成人一区二区在线观看| 欧美性猛交xxxx乱大交退制版| 性色av一区二区三区在线观看 | 国产一区二区三区在线观看精品| 欧美不卡福利| 国产精品观看| 麻豆久久婷婷| 国产精品国产馆在线真实露脸 |