Proxy模式

本文介绍了代理模式的概念及其在软件设计中的应用。详细解释了多种代理模式,包括远程代理、虚拟代理、写时复制代理等,并提供了访问保护代理的具体实现示例。
                   
Proxy模式是 构造型的设计模式之一.
所谓代理,是指具有与代理元(被代理的对象)具有相同的接口的类,客户端必须通过代理与被代理的目标类交互,而代理一般在交互的过程中(交互前后),进行某些特别的处理。
 
根据这些“特别处理”的不同, 有以下几种常见的代理模式
Remote proxy:远程代理。该代理可以让客户端透明地引用一个存在于不同地址空间(远程或本地)的对象。
-   Virtual proxy:虚拟代理。该代理允许一个对象只有在真正被用到时才被创建。
-   Copy-on-write proxy:对象拷贝延迟代理。该代理可以延迟一个对象的拷贝(clone)操作到客户调用里,它是virtual proxy模式的一种特殊情况。一般来说,对象的深度克隆是一个高开销的动作,该代理可以让这个动作延迟,只有对象被用到的时候才被克隆。
Protection (access) proxy:访问保护代理。该代理可以在访问一个对象时附加一些检查操作,比如权限验证等。
Cache proxy:缓存代理。主要为那些创建时高开销的对象提供缓存,以供多客户端共享。
-   Firewall proxy:防火墙代理。保护目标对象不受某些不良客户端的侵害。
-   Synchronization proxy:为非同步的目标对象提供并发控制。
Smart reference proxy:当一个对象被引用时提供某些额外的操作。比如对象被引用时,记录对象被引用的次数等。
==========================================================================================================
上面对proxy模式的阐述来自网络
下面是我对 Protection (access) proxy的一个实现。
 
#ifndef FILEOPERATOR_H
#define FILEOPERATOR_H
#include <iostream>
using namespace std;
class FileOperator
{
public:
    enum  permission {READ ,ALL};
    FileOperator();
    FileOperator(permission _p);
    virtual ~FileOperator() = 0;
    virtual string getFileName()const = 0;
    virtual int getLength() const = 0;
    virtual string modify(string context) = 0;
protected:
    permission getPermission() const {return p;}
private:
    permission p;
};
#endif // FILEOPERATOR_H
#include "fileoperator.h"
FileOperator::FileOperator(permission _p):p(_p)
{
}
FileOperator::FileOperator()
{
    p = FileOperator::READ;
}
FileOperator::~FileOperator()
{
}
#ifndef PROXYFILEOPERATOR_H
#define PROXYFILEOPERATOR_H
#include "fileoperator.h"
#include "realfileoperator.h"
class ProxyFileOperator: public FileOperator
{
public:
    ProxyFileOperator(string _name);
    ProxyFileOperator(string _name,permission _p);
    ~ProxyFileOperator(){delete real;}
    string getFileName() const{return real->getFileName();}
    int getLength()const {return real->getLength();}
    string modify(string context) {return real->modify(context);}
private:
    RealFileOperator *real;
};
#endif // PROXYFILEOPERATOR_H
#include "proxyfileoperator.h"
ProxyFileOperator::ProxyFileOperator(string _name, permission _p):FileOperator(_p)
{
    real = new RealFileOperator(_name,getPermission());
}
ProxyFileOperator::ProxyFileOperator(string _name):FileOperator()
{
    real = new RealFileOperator(_name);
}
#ifndef REALFILEOPERATOR_H
#define REALFILEOPERATOR_H
#include "fileoperator.h"
class RealFileOperator : public FileOperator
{
public:
    RealFileOperator(string _name);
    RealFileOperator(string _name,permission _P);
    ~RealFileOperator(){}
    string getFileName()const {return fileName;}
    int getLength()const {return fileName.length();}
    string modify(string context);
private:
    string fileName;
};
#endif // REALFILEOPERATOR_H
#include "realfileoperator.h"
RealFileOperator::RealFileOperator(string _name, permission _P):FileOperator(_P),fileName(_name)
{
}
RealFileOperator::RealFileOperator(string _name):FileOperator(),fileName(_name)
{
}
string RealFileOperator::modify(string context)
{
    if(getPermission() == FileOperator::ALL) {
        fileName += context;
        return "ok";
    }
    else {
        return "no";
    }
}
#include <iostream>
using namespace std;
#include "proxyfileoperator.h"
int main()
{
    FileOperator *p = new ProxyFileOperator("I am zhou xiang!");
    cout << p->getFileName()<<'\n';
    if (p->modify("Love ChenChen!\n") == "ok") {
        cout << p->getFileName();
    }
    else {
        cout<<"ERROR Permission denied!";
    }
    delete p;
    return 0;
}
默认只有读的权限,输出为
修给之后, FileOperator *p = new ProxyFileOperator("I am zhou xiang!",FileOperator::ALL);
输出结果,
====================================================================================================
        
      
        
      
        
      
         

Proxy模式在访问对象时引入了一定程度的间接性。根据代理的类型,附加的间接性有多种用途: 1) Remote Proxy可以隐藏一个对象存在于不同地址空间的事实。也使得客户端可以访问在远程机器上的对象,远程机器可能具有更好的计算性能与处理速度,可以快速响应并处理客户端请求。 2) Virtual Proxy 可以进行最优化,例如根据要求创建对象。即通过使用一个小对象来代表一个大对象,可以减少系统资源的消耗。 3) Protection Proxies和Smart Reference都允许在访问一个对象时有一些附加的内务处理(Housekeeping task) 。

Proxy模式还可以对用户隐藏另一种称之为写时复制(copy-on-write)的优化方式,该优化与根据需要创建对象有关。拷贝一个庞大而复杂的对象是一种开销很大的操作,如果这个拷贝根本没有被修改,那么这些开销就没有必要。用代理延迟这一拷贝过程,我们可以保证只有当这个对象被修改的时候才对它进行拷贝。在实现copy-on-write时必须对实体进行引用计数。拷贝代理仅会增加引用计数。只有当用户请求一个修改该实体的操作时,代理才会真正的拷贝它。在这种情况下,代理还必须减 少实体的引用计数。当引用的数目为零时,这个实体将被删除。copy-on-write可以大幅度的降低拷贝庞大实体时的开销。

代理模式能够 协调调用者和被调用者 ,在一定程度上降低了系统的耦合度。
代理模式的缺点 由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。 实现代理模式需要额外的工作,有些代理模式的实现非常复杂。
 
 

转载于:https://my.oschina.net/u/854744/blog/418218

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值