首页 > 代码库 > 设计模式之代理模式

设计模式之代理模式

1.定义
代理模式(Proxy),为其他对象提供一种代理以控制对这个对象的方位。
2.结构图

运行时一种可能的 Proxy 结构的对象图:

3.类说明

抽象角色:声明真实对象和代理对象的共同接口;

代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。

真实角色:代理角色所代表的真实对象,是我们最终要引用的对象。

4.应用

  • 远程代理(Remote Proxy)为一个对象在不同的地址空间提供局部代表。(WebService在.net中的应用)
  • 虚拟代理(Virtual Proxy)根据需要创建开销很大的对象。(HTML中图片的加载)
  • 安全代理(Protection Proxy)控制对原始对象的访问。(不同访问权限)
  • 智能代理(Smart Proxy)在访问对象时执行一些附加操作。

5.实例

1、控制对象访问:一个对象只有有限的访问权限,代理模式(Proxy)可以验证用户的权限。 

例:我们在网购时知道订单一旦被创建,只有订单创建者才可以修改订单中的数据,其他人则无权修改。下面是通过Proxy设计模式控制对象的访问的类图。

实现如下:

class Order_AbstractClass {    public:  string getProductName();void setProductName(string productName,string consumer);    int getOrderID();    void setOrderID(int orderID, string consumer);    string getOrderCreater ();    void setOrderCreater (string orderCreater, string consumer);}class Order: Order_AbstractClass {private:string productName;     int orderID;     string orderCreater;public :Order(string productName,int orderID,string orderCreater)    {        productName=productName;        orderID = orderID;        orderCreater = orderCreater;    }    int getOrderID () {        return orderID;    }     string getOrderCreater() {        return orderCreater;    }    string getProductName() {        return productName;    }void setOrderID(int orderID, string consumer) {        OrderID = orderID;    }    void setOrderCreater (string orderCreater, string consumer) {        orderCreater=orderCreater;    }     void setProductName(string productName, string consumer) {        productName=productName;    }}class OrderProxy: Order_AbstractClass {    private: Order order;    public:OrderProxy(Order realorder) {        order=realorder;    }       int getOrderID() {        return order.getOrderID ();    }       string getOrderCreater() {        return order.getOrderCreater ();    }       string getProductName() {        return order.getProductName();    }void setOrderID(int orderID, string consumer) {    if(consumer!=NULL && consumer.equals(this.getOrderCreater())){            order.setOrderID(orderID, consumer);cout<<"恭喜您修改成功"<<endl;        }else{            cout<<"您无权修改订单号"<<endl;        }}    void setOrderCreater(string orderCreater, string consumer) {    if(consumer!=null && consumer.equals(this.getOrderCreater ())){            order.setOrderCreater(orderCreater, consumer);cout<<"恭喜您修改成功"<<endl;         }else{            cout<<"您无权修改订单创建者"<<endl;        }}    void setProductName(string productName, string consumer) {    if(consumer!=null && consumer.equals(this.getOrderCreater ())){        order.setProductName(productName, consumer);cout<<"恭喜您修改成功"<<endl;        }else{            cout<<"您无权修改产品名称"<<endl;        }}void main(){    Order_AbstractClass order=new OrderProxy(new Order("C++设计模式",2,"小四"));        order.setOrderID(123, "小五");        order.setOrderID(123, "小四");order.setProductName("C++编程", "小四");order.setOrderCreater("小七", "小六");}

 

2、作为远程代理使用外域的对象:有些情况下,一个客户不想或者不能够直接引用一个对象,使用Proxy代理模式的代理对象可以在客户端和目标对象之间起到中介的作用。

例:代理服务器的功能就是代理网络用户去取得网络信息。在一般情况下,我们使用网络浏览器直接去连接其他Internet站点取得网络信息时,须送出Request信号来得到回答,然后对方再把信息以bit方式传送回来。代理服务器是介于浏览器和Web服务器之间的一台服务器,有了它之后,浏览器不是直接到Web服务器去取回网页而是向代理服务器发出请求,Request信号会先送到代理服务器,由代理服务器来取回浏览器所需要的信息并传送给你的浏览器。如果浏览器所请求的数据在它本机的存储器上已经存在而且是最新的,那么它就不重新从Web服务器取数据,而直接将存储器上的数据传送给用户的浏览器,否则,通过从Web服务器获取所需信息,这样能显著提高浏览速度和效率。如下图所示: