代理模式

案例: 某公司已有查询模块. 需开发带用户验证和日志记录的新收费查询模块,并且不改变原查询的客户端调用.

一开始的思路就想到了用另 1 个新对象, 在新对象里,包含原对象指针,并新增加 2 新成员对象,在构造里实现用户登录,并在每次查询动作后,增加日志记录

class Query {};
class NewQuery {
    NewQuery(Query *q) {
        base = q;
        logger = new Logger();
        login = new UsrLoggin)();

        loggin->usr_login();
        expires = 0;
    }
    Query * base;
    UsrLoggin* login;
    Logger* logger;
    int expires ;
    ...

    query_by_time() {
        flag = logger->check_loggin();
        if (flag != 0 ) {
            if (expires < 10000) {
                base->query_by_time();
                logger->record();
                expires ++;
            } else {
                cout << "Expire query times!";
            }
        }
    }
    query_xxxx() {...}
    ...
}

这里的 NewQuery 就可以理解为一种代理模式了, 客户端只用将原来的query = new Query()改为query = new NewQuery(),就像是访问原来的 query 一样,不过会提示登录,会记录日志,并且超过次数有告警等等.

  • 桥接模式的区别?

桥接模式更强调 Logger 和 Loggin 的变化.比如 Logger 有 n 种,Loggin 有 m 种..这更体现桥接的优势,即不需要去多重继承产生 mxn 个子类,桥接需要增加下面 2 个接口.

set_logger();
set_usr_loggin();

再看书上的结构:

2018-08-08-13-18-30

只有一个地方不同,即 client 调用时的 Subject 是父类,而 Proxy 和 Realsubject 是子类, 上面自己的思路是直接调用 Realsubject 的假定,因而也是是直接使用 Proxy.

这也是针对抽象编程的思想.

分的更细的类,借用以前的笔记好了:

远程代理

java 里用的多,需要在本地的 JVM 上调用其他 JVM 上对象的方法时,即得客户端程序可以访问在远程主机上的对象,远程主机可能具有更好的计算性能与处理速度,可以快速响应并处理客户端的请求。远程代理将网络的细节隐藏,客户端不必考虑网络,完全可以认为被代理的远程业务对象是在本地而不是在远程,而远程代理对象承担了网络通信工作,并负责对远程业务方法的调用,并返回结果.

Java RMI(Remote Method Invocation)调用流程:

2018-08-08-13-45-13

涉及的技术有反射,序列化,网络通信,代理模式等等.

当然实现远程通信来讲,不止 RMI 技术, 常用的还有 RPC,消息队列等…

虚拟代理

跟单例模式里的懒汉模式非常像,当代理的对象 new 出来很复杂时,先 new 出代理,真正用的时候才 new 出真正的对象。

class BigImageProxy: public Image
{
private:
    BigImage *m_bigImage;
public:
    BigImageProxy(string name):Image(name),m_bigImage(0) {}
    ~BigImageProxy() { delete m_bigImage; }
    void Show()
    {
        if(m_bigImage == NULL)
            m_bigImage = new BigImage(m_imageName);
        m_bigImage->Show();
    }
};
int main()
{
    Image *image = new BigImageProxy("proxy.jpg"); //代理
    image->Show(); //需要时由代理负责打开
    delete image;
    return 0;
}

保护代理

控制被代理对象的访问权限,为不同用户提供不同权限.

缓冲代理

缓冲代理(Cache Proxy)也是一种较为常用的代理模式,它为某一个操作的结果提供临时的缓存存储空间,以便在后续使用中能够共享这些结果,从而可以避免某些方法的重复执行,优化系统性能。

智能引用代理

智能指针就是经典的代理