设计模式 结构模型 代理模式
代理模式
案例: 某公司已有查询模块. 需开发带用户验证和日志记录的新收费查询模块,并且不改变原查询的客户端调用.
一开始的思路就想到了用另 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();
再看书上的结构:
只有一个地方不同,即 client 调用时的 Subject 是父类,而 Proxy 和 Realsubject 是子类, 上面自己的思路是直接调用 Realsubject 的假定,因而也是是直接使用 Proxy.
这也是针对抽象编程的思想.
分的更细的类,借用以前的笔记好了:
远程代理
java 里用的多,需要在本地的 JVM 上调用其他 JVM 上对象的方法时,即得客户端程序可以访问在远程主机上的对象,远程主机可能具有更好的计算性能与处理速度,可以快速响应并处理客户端的请求。远程代理将网络的细节隐藏,客户端不必考虑网络,完全可以认为被代理的远程业务对象是在本地而不是在远程,而远程代理对象承担了网络通信工作,并负责对远程业务方法的调用,并返回结果.
Java RMI(Remote Method Invocation)调用流程:
涉及的技术有反射
,序列化
,网络通信
,代理模式
等等.
当然实现远程通信来讲,不止 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)也是一种较为常用的代理模式,它为某一个操作的结果提供临时的缓存存储空间,以便在后续使用中能够共享这些结果,从而可以避免某些方法的重复执行,优化系统性能。
智能引用代理
智能指针就是经典的代理