為什么不返回ForumFactory,而返回ForumFactory 的實(shí)現(xiàn)ForumFactoryProxy?
原因是明顯的,需要通過代理確定是否有權(quán)限創(chuàng)建forum。
在ForumFactoryProxy 中我們看到代碼如下:
public class ForumFactoryProxy extends ForumFactory {
protected ForumFactory factory;
protected Authorization authorization;
protected ForumPermissions permissions;
public ForumFactoryProxy(Authorization authorization, ForumFactory factory,
ForumPermissions permissions)
{
this.factory = factory;
this.authorization = authorization;
this.permissions = permissions;
}
public Forum createForum(String name, String description)
throws UnauthorizedException, ForumAlreadyExistsException
{
//只有系統(tǒng)管理者才可以創(chuàng)建forum
if (permissions.get(ForumPermissions.SYSTEM_ADMIN)) {
Forum newForum = factory.createForum(name, description);
return new ForumProxy(newForum, authorization, permissions);
}
else {
throw new UnauthorizedException();
}
}
方法createForum 返回的也是ForumProxy, Proxy 就象一道墻,其他程序只能和Proxy 交互操作。
注意到這里有兩個(gè)Proxy:ForumProxy 和ForumFactoryProxy。代表兩個(gè)不同的職責(zé):使用Forum 和創(chuàng)建Forum;至于為什么將使用對(duì)象和創(chuàng)建對(duì)象分開,這也是為什么使用Factory 模式的原因所在:是為了“封裝”、“分派”;換句話說,盡可能功能單一化,方便維護(hù)修改。
以上我們討論了如何使用Proxy 進(jìn)行授權(quán)機(jī)制的訪問,Proxy 還可以對(duì)用戶隱藏另外一種稱為copy-on-write 的優(yōu)化方式?截愐粋(gè)龐大而復(fù)雜的對(duì)象是一個(gè)開銷很大的操作,如果拷貝過程中,沒有對(duì)原來的對(duì)象有所修改,那么這樣的拷貝開銷就沒有必要。用代理延遲這一拷貝過程。
比如:我們有一個(gè)很大的Collection,具體如hashtable,有很多客戶端會(huì)并發(fā)同時(shí)訪問它。
其中一個(gè)特別的客戶端要進(jìn)行連續(xù)的數(shù)據(jù)獲取,此時(shí)要求其他客戶端不能再向hashtable 中增加或刪除東東。
最直接的解決方案是:使用collection 的lock,讓這特別的客戶端獲得這個(gè)lock,進(jìn)行連續(xù)的數(shù)據(jù)獲取,然后再釋放lock。
public void foFetches(Hashtable ht){
synchronized(ht){
//具體的連續(xù)數(shù)據(jù)獲取動(dòng)作..
}
}
但是這一辦法可能鎖住Collection 會(huì)很長時(shí)間,這段時(shí)間,其他客戶端就不能訪問該Collection 了。
第二個(gè)解決方案是clone 這個(gè)Collection,然后讓連續(xù)的數(shù)據(jù)獲取針對(duì)clone 出來的那個(gè)Collection 操作。這個(gè)方案前提是:這個(gè)Collection 是可clone 的,而且必須有提供深度clone 的方法。Hashtable 就提供了對(duì)自己的clone 方法,但不是Key 和value 對(duì)象的clone,關(guān)于Clone 含義可以參考專門文章。
public void foFetches(Hashtable ht){
Hashttable newht=(Hashtable)ht.clone();
}
問題又來了,由于是針對(duì)clone 出來的對(duì)象操作,如果原來的母體被其他客戶端操作修改了,那么對(duì)clone 出來的對(duì)象操作就沒有意義了。
最后解決方案:我們可以等其他客戶端修改完成后再進(jìn)行clone,也就是說,這個(gè)特別的客戶端先通過調(diào)用一個(gè)叫clone 的方法來進(jìn)行一系列數(shù)據(jù)獲取操作。但實(shí)際上沒有真正的進(jìn)行對(duì)象拷貝,直至有其他客戶端修改了這個(gè)對(duì)象Collection。
使用Proxy 實(shí)現(xiàn)這個(gè)方案.這就是copy-on-write 操作。
北京 | 天津 | 上海 | 江蘇 | 山東 |
安徽 | 浙江 | 江西 | 福建 | 深圳 |
廣東 | 河北 | 湖南 | 廣西 | 河南 |
海南 | 湖北 | 四川 | 重慶 | 云南 |
貴州 | 西藏 | 新疆 | 陜西 | 山西 |
寧夏 | 甘肅 | 青海 | 遼寧 | 吉林 |
黑龍江 | 內(nèi)蒙古 |