欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java設(shè)計(jì)模式之代理模式(Proxy模式)介紹

 更新時(shí)間:2015年03月11日 09:58:45   投稿:junjie  
這篇文章主要介紹了Java設(shè)計(jì)模式之代理模式(Proxy模式)介紹,本文講解了為什么要使用代理模式、如何使用代理模式等內(nèi)容,需要的朋友可以參考下

理解并使用設(shè)計(jì)模式,能夠培養(yǎng)我們良好的面向?qū)ο缶幊塘?xí)慣,同時(shí)在實(shí)際應(yīng)用中,可以如魚得水,享受游刃有余的樂趣。

Proxy是比較有用途的一種模式,而且變種較多,應(yīng)用場合覆蓋從小結(jié)構(gòu)到整個(gè)系統(tǒng)的大結(jié)構(gòu),Proxy是代理的意思,我們也許有代理服務(wù)器等概念,代理概念可以解釋為:在出發(fā)點(diǎn)到目的地之間有一道中間層,意為代理。

設(shè)計(jì)模式中定義:為其他對象提供一種代理以控制對這個(gè)對象的訪問。

為什么要使用代理模式

1.授權(quán)機(jī)制 不同級別的用戶對同一對象擁有不同的訪問權(quán)利,如Jive論壇系統(tǒng)中,就使用Proxy進(jìn)行授權(quán)機(jī)制控制,訪問論壇有兩種人:注冊用戶和游客(未注冊用戶),Jive中就通過類似ForumProxy這樣的代理來控制這兩種用戶對論壇的訪問權(quán)限。
2.某個(gè)客戶端不能直接操作到某個(gè)對象,但又必須和那個(gè)對象有所互動(dòng)。

舉例兩個(gè)具體情況:

1.如果那個(gè)對象是一個(gè)是很大的圖片,需要花費(fèi)很長時(shí)間才能顯示出來,那么當(dāng)這個(gè)圖片包含在文檔中時(shí),使用編輯器或?yàn)g覽器打開這個(gè)文檔,打開文檔必須很迅速,不能等待大圖片處理完成,這時(shí)需要做個(gè)圖片Proxy來代替真正的圖片。
2.如果那個(gè)對象在Internet的某個(gè)遠(yuǎn)端服務(wù)器上,直接操作這個(gè)對象因?yàn)榫W(wǎng)絡(luò)速度原因可能比較慢,那我們可以先用Proxy來代替那個(gè)對象。

總之原則是,對于開銷很大的對象,只有在使用它時(shí)才創(chuàng)建,這個(gè)原則可以為我們節(jié)省很多寶貴的Java內(nèi)存。所以,有些人認(rèn)為Java耗費(fèi)資源內(nèi)存,我以為這和程序編制思路也有一定的關(guān)系。

如何使用代理模式

以Jive論壇系統(tǒng)為例,訪問論壇系統(tǒng)的用戶有多種類型:注冊普通用戶、論壇管理者、系統(tǒng)管理者、游客。注冊普通用戶才能發(fā)言,論壇管理者可以管理他被授權(quán)的論壇,系統(tǒng)管理者可以管理所有事務(wù)等,這些權(quán)限劃分和管理是使用Proxy完成的。

Forum是Jive的核心接口,在Forum中陳列了有關(guān)論壇操作的主要行為,如論壇名稱,論壇描述的獲取和修改,帖子發(fā)表刪除編輯等。

在ForumPermissions中定義了各種級別權(quán)限的用戶:

復(fù)制代碼 代碼如下:

public class ForumPermissions implements Cacheable {
/**
* Permission to read object.
*/
public static final int READ = 0;

/**
* Permission to administer the entire sytem.
*/
public static final int SYSTEM_ADMIN = 1;

/**
* Permission to administer a particular forum.
*/
public static final int FORUM_ADMIN = 2;

/**
* Permission to administer a particular user.
*/
public static final int USER_ADMIN = 3;

/**
* Permission to administer a particular group.
*/
public static final int GROUP_ADMIN = 4;

/**
* Permission to moderate threads.
*/
public static final int MODERATE_THREADS = 5;

/**
* Permission to create a new thread.
*/
public static final int CREATE_THREAD = 6;

/**
* Permission to create a new message.
*/
public static final int CREATE_MESSAGE = 7;

/**
* Permission to moderate messages.
*/
public static final int MODERATE_MESSAGES = 8;

.....

public boolean isSystemOrForumAdmin() {
 return (values[FORUM_ADMIN] || values[SYSTEM_ADMIN]);
}

.....

}

因此,F(xiàn)orum中各種操作權(quán)限是和ForumPermissions定義的用戶級別有關(guān)系的,作為接口Forum的實(shí)現(xiàn):ForumProxy正是將這種對應(yīng)關(guān)系聯(lián)系起來。比如,修改Forum的名稱,只有論壇管理者或系統(tǒng)管理者可以修改,代碼如下:

復(fù)制代碼 代碼如下:

public class ForumProxy implements Forum {
    private ForumPermissions permissions;
    private Forum forum;
    this.authorization = authorization;

    public ForumProxy(Forum forum, Authorization authorization,
    ForumPermissions permissions){
        this.forum = forum;
        this.authorization = authorization;
        this.permissions = permissions;
    }
    .....
    public void setName(String name) throws UnauthorizedException,
        ForumAlreadyExistsException{
  //只有是系統(tǒng)或論壇管理者才可以修改名稱
  if (permissions.isSystemOrForumAdmin()) {
   forum.setName(name);
  }
  else {
   throw new UnauthorizedException();
  }
    }
    ...

}

而DbForum才是接口Forum的真正實(shí)現(xiàn),以修改論壇名稱為例:

復(fù)制代碼 代碼如下:

public class DbForum implements Forum, Cacheable {
    ...
    public void setName(String name) throws ForumAlreadyExistsException {
  ....
  this.name = name;
  //這里真正將新名稱保存到數(shù)據(jù)庫中
  saveToDb();
  ....
    }
    ...
}

凡是涉及到對論壇名稱修改這一事件,其他程序都首先得和ForumProxy打交道,由ForumProxy決定是否有權(quán)限做某一樣事情,F(xiàn)orumProxy是個(gè)名副其實(shí)的"網(wǎng)關(guān)","安全代理系統(tǒng)"。

在平時(shí)應(yīng)用中,無可避免總要涉及到系統(tǒng)的授權(quán)或安全體系,不管你有無意識的使用Proxy,實(shí)際你已經(jīng)在使用Proxy了。

我們繼續(xù)結(jié)合Jive談入深一點(diǎn),下面要涉及到工廠模式了。

我們已經(jīng)知道,使用Forum需要通過ForumProxy,Jive中創(chuàng)建一個(gè)Forum是使用Factory模式,有一個(gè)總的抽象類ForumFactory,在這個(gè)抽象類中,調(diào)用ForumFactory是通過getInstance()方法實(shí)現(xiàn),這里使用了Singleton(也是設(shè)計(jì)模式之一),getInstance()返回的是ForumFactoryProxy。

為什么不返回ForumFactory,而返回ForumFactory的實(shí)現(xiàn)ForumFactoryProxy?原因是明顯的,需要通過代理確定是否有權(quán)限創(chuàng)建forum。

在ForumFactoryProxy中我們看到代碼如下:

復(fù)制代碼 代碼如下:

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。至于為什么將使用對象和創(chuàng)建對象分開,這也是為什么使用Factory模式的原因所在:是為了"封裝" "分派"。換句話說,盡可能功能單一化,方便維護(hù)修改。

Jive論壇系統(tǒng)中其他如帖子的創(chuàng)建和使用,都是按照Forum這個(gè)思路而來的。

以上我們討論了如何使用Proxy進(jìn)行授權(quán)機(jī)制的訪問,Proxy還可以對用戶隱藏另外一種稱為copy-on-write的優(yōu)化方式。拷貝一個(gè)龐大而復(fù)雜的對象是一個(gè)開銷很大的操作,如果拷貝過程中,沒有對原來的對象有所修改,那么這樣的拷貝開銷就沒有必要。用代理延遲這一拷貝過程。

比如:我們有一個(gè)很大的Collection,具體如hashtable,有很多客戶端會并發(fā)同時(shí)訪問它。其中一個(gè)特別的客戶端要進(jìn)行連續(xù)的數(shù)據(jù)獲取,此時(shí)要求其他客戶端不能再向hashtable中增加或刪除 東東。

最直接的解決方案是:使用collection的lock,讓這特別的客戶端獲得這個(gè)lock,進(jìn)行連續(xù)的數(shù)據(jù)獲取,然后再釋放lock。

復(fù)制代碼 代碼如下:

public void foFetches(Hashtable ht){
 synchronized(ht){
  //具體的連續(xù)數(shù)據(jù)獲取動(dòng)作..
 }
}

但是這一辦法可能鎖住Collection會很長時(shí)間,這段時(shí)間,其他客戶端就不能訪問該Collection了。

第二個(gè)解決方案是clone這個(gè)Collection,然后讓連續(xù)的數(shù)據(jù)獲取針對clone出來的那個(gè)Collection操作。這個(gè)方案前提是,這個(gè)Collection是可clone的,而且必須有提供深度clone的方法。Hashtable就提供了對自己的clone方法,但不是Key和value對象的clone。

復(fù)制代碼 代碼如下:

public void foFetches(Hashtable ht){
 Hashttable newht=(Hashtable)ht.clone();
}

問題又來了,由于是針對clone出來的對象操作,如果原來的母體被其他客戶端操作修改了,那么對clone出來的對象操作就沒有意義了。

最后解決方案:我們可以等其他客戶端修改完成后再進(jìn)行clone,也就是說,這個(gè)特別的客戶端先通過調(diào)用一個(gè)叫clone的方法來進(jìn)行一系列數(shù)據(jù)獲取操作。但實(shí)際上沒有真正的進(jìn)行對象拷貝,直至有其他客戶端修改了這個(gè)對象Collection。

使用Proxy實(shí)現(xiàn)這個(gè)方案,這就是copy-on-write操作。

Proxy應(yīng)用范圍很廣,現(xiàn)在流行的分布計(jì)算方式RMI和Corba等都是Proxy模式的應(yīng)用。

相關(guān)文章

  • 實(shí)例講解Java讀取一般文本文件和word文檔的方法

    實(shí)例講解Java讀取一般文本文件和word文檔的方法

    讀取一般文本文件很好辦,調(diào)用Java自帶的io包里的類即可,富文本的doc文件我們可以用Apache的poi項(xiàng)目中的WordExtractor,這里我們一起來以實(shí)例講解Java讀取一般文本文件和word文檔的方法
    2016-06-06
  • java讀取excel文件的兩種方法

    java讀取excel文件的兩種方法

    這篇文章主要為大家詳細(xì)介紹了java讀取excel文件的兩種方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • java獲取日期的方法

    java獲取日期的方法

    這篇文章介紹了java獲取日期的方法,有需要的朋友可以參考一下
    2013-10-10
  • 如何在Spring Boot項(xiàng)目中使用Spring AI

    如何在Spring Boot項(xiàng)目中使用Spring AI

    Spring AI是Spring框架中用于集成和使用人工智能和機(jī)器學(xué)習(xí)功能的組件,它提供了一種簡化的方式來與AI模型進(jìn)行交互,這篇文章主要介紹了Spring Boot 在項(xiàng)目中使用Spring AI,需要的朋友可以參考下
    2024-05-05
  • 解決idea配置Tomcat Deployment沒有artifact選項(xiàng)的問題

    解決idea配置Tomcat Deployment沒有artifact選項(xiàng)的問題

    今天在配置的時(shí)候tomcat deployment中卻找不到artifact,沒有artifact就不能打成war包上傳到服務(wù)器了,那么怎么解決沒有artifact選項(xiàng)的問題呢,今天通過本文給大家分享idea配置Tomcat Deployment沒有artifact選項(xiàng)的解決方案,一起看看吧
    2023-10-10
  • SpringBoot設(shè)置Session失效時(shí)間的解決方案

    SpringBoot設(shè)置Session失效時(shí)間的解決方案

    當(dāng)過期時(shí)間是大于1分鐘的時(shí)候是沒有什么問題的,但是如果設(shè)置過期時(shí)間小于1分鐘,就會失效,這篇文章主要介紹了SpringBoot設(shè)置Session失效時(shí)間的解決方案,需要的朋友可以參考下
    2024-05-05
  • IDE Eval Reset忘了重置進(jìn)不去的完美解決方法

    IDE Eval Reset忘了重置進(jìn)不去的完美解決方法

    這篇文章主要介紹了IDE Eval Reset忘了重置進(jìn)不去的完美解決方法,插件安裝方式包括離線安裝和在線安裝方式,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2023-12-12
  • Java中l(wèi)ength,length(),size()詳解及區(qū)別

    Java中l(wèi)ength,length(),size()詳解及區(qū)別

    這篇文章主要介紹了Java中l(wèi)ength,length(),size()詳解及區(qū)別的相關(guān)資料,需要的朋友可以參考下
    2016-11-11
  • Spring容器獲取Bean的9種方式總結(jié)

    Spring容器獲取Bean的9種方式總結(jié)

    本文為大家整理匯總了常見的獲取Bean的方式,并提供一些優(yōu)劣分析,方便大家在使用到時(shí)有更好的選擇,同時(shí),也會為大家適當(dāng)?shù)钠占昂屯卣挂恍┫嚓P(guān)知識,需要的可以參考一下
    2023-07-07
  • Java文件分級目錄打包下載zip的實(shí)例代碼

    Java文件分級目錄打包下載zip的實(shí)例代碼

    這篇文章主要介紹了Java文件分級目錄打包下載zip的實(shí)例代碼,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08

最新評論