国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

java設計模式之 Proxy(代理)

2019-11-18 12:14:56
字體:
來源:轉載
供稿:網友

  理解并使用設計模式,能夠培養我們良好的面向對象編程習慣,同時在實際應用中,可以如魚得水,享受游刃有余的樂趣.
  
  PRoxy是比較有用途的一種模式,而且變種較多,應用場合覆蓋從小結構到整個系統的大結構,Proxy是代理的意思,我們也許有代理服務器等概念,代理概念可以解釋為:在出發點到目的地之間有一道中間層,意為代理.
  
  設計模式中定義: 為其他對象提供一種代理以控制對這個對象的訪問.
  
  為什么要使用Proxy?
  1.授權機制 不同級別的用戶對同一對象擁有不同的訪問權利,如Jive論壇系統中,就使用Proxy進行授權機制控制,訪問論壇有兩種人:注冊用戶和游客(未注冊用戶),Jive中就通過類似ForumProxy這樣的代理來控制這兩種用戶對論壇的訪問權限.
  
  2.某個客戶端不能直接操作到某個對象,但又必須和那個對象有所互動.
  舉例兩個具體情況:
  (1)假如那個對象是一個是很大的圖片,需要花費很長時間才能顯示出來,那么當這個圖片包含在文檔中時,使用編輯器或瀏覽器打開這個文檔,打開文檔必須很迅速,不能等待大圖片處理完成,這時需要做個圖片Proxy來代替真正的圖片.
  
  (2)假如那個對象在Internet的某個遠端服務器上,直接操作這個對象因為網絡速度原因可能比較慢,那我們可以先用Proxy來代替那個對象.
  
  總之原則是,對于開銷很大的對象,只有在使用它時才創建,這個原則可以為我們節省很多寶貴的java內存. 所以,有些人認為Java耗費資源內存,我以為這和程序編制思路也有一定的關系.
  
  如何使用Proxy?
  以Jive論壇系統為例,訪問論壇系統的用戶有多種類型:注冊普通用戶 論壇治理者 系統治理者 游客,注冊普通用戶才能發言;論壇治理者可以治理他被授權的論壇;系統治理者可以治理所有事務等,這些權限劃分和治理是使用Proxy完成的.
  
  Forum是Jive的核心接口,在Forum中陳列了有關論壇操作的主要行為,如論壇名稱 論壇描述的獲取和修改,帖子發表刪除編輯等.
  
  在ForumPermissions中定義了各種級別權限的用戶:
  
  [code]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]);
  }
  
  .....
  
  }[/code]
  
  因此,Forum中各種操作權限是和ForumPermissions定義的用戶級別有關系的,作為接口Forum的實現:ForumProxy正是將這種對應關系聯系起來.比如,修改Forum的名稱,只有論壇治理者或系統治理者可以修改,代碼如下:
  
  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
  {
    //只有是系統或論壇治理者才可以修改名稱
    if (permissions.isSystemOrForumAdmin()) {
      forum.setName(name);
    }
    else {
      throw new UnauthorizedException();
    }
  }
  
  ...
  
  }
  
  而DbForum才是接口Forum的真正實現,以修改論壇名稱為例:
  
  public class DbForum implements Forum, Cacheable {
  ...
  
  public void setName(String name) throws ForumAlreadyExistsException {
  
    ....
  
    this.name = name;
    //這里真正將新名稱保存到數據庫
    saveToDb();
  
    ....
  }
  
  ...
  
  }
  
  凡是涉及到對論壇名稱修改這一事件,其他程序都首先得和ForumProxy打交道,由ForumProxy決定是否有權限做某一樣事情,ForumProxy是個名副其實的"網關","安全代理系統".
  
  在平時應用中,無可避免總要涉及到系統的授權或安全體系,不管你有無意識的使用Proxy,實際你已經在使用Proxy了.
  
  我們繼續結合Jive談入深一點,下面要涉及到工廠模式了,假如你不了解工廠模式,請看我的另外一篇文章:設計模式之Factory
  
  我們已經知道,使用Forum需要通過ForumProxy,Jive中創建一個Forum是使用Factory模式,有一個總的抽象類ForumFactory,在這個抽象類中,調用ForumFactory是通過getInstance()方法實現,這里使用了Singleton(也是設計模式之一,由于介紹文章很多,我就不寫了,看這里),getInstance()返回的是ForumFactoryProxy.
  
  為什么不返回ForumFactory,而返回ForumFactory的實現ForumFactoryProxy?
  原因是明顯的,需要通過代理確定是否有權限創建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
    {
      //只有系統治理者才可以創建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交互操作.
  
  注重到這里有兩個Proxy:ForumProxy和ForumFactoryProxy. 代表兩個不同的職責:使用Forum和創建Forum;
  至于為什么將使用對象和創建對象分開,這也是為什么使用Factory模式的原因所在:是為了"封裝" "分派";換句話說,盡可能功能單一化,方便維護修改.
  
  Jive論壇系統中其他如帖子的創建和使用,都是按照Forum這個思路而來的.
  
  以上我們討論了如何使用Proxy進行授權機制的訪問,Proxy還可以對用戶隱藏另外一種稱為copy-on-write的優化方式.拷貝一個龐大而復雜的對象是一個開銷很大的操作,假如拷貝過程中,沒有對原來的對象有所修改,那么這樣的拷貝開銷就沒有必要.用代理延遲這一拷貝過程.
  
  比如:我們有一個很大的Collection,具體如hashtable,有很多客戶端會并發同時訪問它.其中一個非凡的客戶端要進行連續的數據獲取,此時要求其他客戶端不能再向hashtable中增加或刪除 東東.
  
  最直接的解決方案是:使用collection的lock,讓這非凡的客戶端獲得這個lock,進行連續的數據獲取,然后再釋放lock.
  public void foFetches(Hashtable ht){
    synchronized(ht){
      //具體的連續數據獲取動作..
    }
  
  }
  
  但是這一辦法可能鎖住Collection會很長時間,這段時間,其他客戶端就不能訪問該Collection了.
  
  第二個解決方案是clone這個Collection,然后讓連續的數據獲取針對clone出來的那個Collection操作.這個方案前提是,這個Collection是可clone的,而且必須有提供深度clone的方法.Hashtable就提供了對自己的clon

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 拉孜县| 喀喇| 汨罗市| 萨嘎县| 赤城县| 望奎县| 孟州市| 揭东县| 邯郸县| 南投市| 津南区| 乐清市| 锡林浩特市| 甘谷县| 京山县| 大连市| 仁怀市| 景东| 永和县| 隆尧县| 宁德市| 定结县| 通道| 新津县| 郯城县| 微山县| 青海省| 抚松县| 汾阳市| 正宁县| 咸阳市| 普格县| 鲁山县| 彩票| 梓潼县| 永昌县| 周至县| 香格里拉县| 西华县| 大方县| 寿阳县|