java Source

            BlogJava :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
            14 Posts :: 24 Stories :: 8 Comments :: 0 Trackbacks

          虛擬代理模式(Virtual Proxy)是一種節(jié)省內(nèi)存的技術(shù),它建議創(chuàng)建那些占用大量內(nèi)存或處理復(fù)雜的對象時,把創(chuàng)建這類對象推遲到使用它的時候。在特定的應(yīng)用中,不同部分的功能 由不同的對象組成,應(yīng)用啟動的時候,不會立即使用所有的對象。在這種情況下,虛擬代理模式建議推遲對象的創(chuàng)建直到應(yīng)用程序需要它為止。對象被應(yīng)用第一次引 用時創(chuàng)建并且同一個實例可以被重用。這種方法優(yōu)缺點并存。

            優(yōu)點:

            這種方法的優(yōu)點是,在應(yīng)用程序啟動時,由于不需要創(chuàng)建和裝載所有的對象,因此加速了應(yīng)用程序的啟動。

            缺點:

            因為不能保證特定的應(yīng)用程序?qū)ο蟊粍?chuàng)建,在訪問這個對象的任何地方,都需要檢測確認它不是空(null)。也就是,這種檢測的時間消耗是最大的缺點。

             應(yīng)用虛擬代理模式,需要設(shè)計一個與真實對象具有相同接口的單獨對象(指虛擬代理)。不同的客戶對象可以在創(chuàng)建和使用真實對象地方用相應(yīng)的虛擬對象來代 替。虛擬對象把真實對象的引用作為它的實例變量維護。代理對象不要自動創(chuàng)建真實對象,當(dāng)客戶需要真實對象的服務(wù)時,調(diào)用虛擬代理對象上的方法,并且檢測真 實對象是否被創(chuàng)建。

            如果真實對象已經(jīng)創(chuàng)建,代理把調(diào)用轉(zhuǎn)發(fā)給真實對象,如果真實對象沒有被創(chuàng)建:

            1) 代理對象創(chuàng)建真實對象

            2) 代理對象把這個對象分配給引用變量。

            3) 代理把調(diào)用轉(zhuǎn)發(fā)給真實對象

             按照這種安排,驗證對象存在和轉(zhuǎn)發(fā)方法調(diào)用這些細節(jié)對于客戶是不可見的。客戶對象就像和真實對象一樣與代理對象進行交互。因此客戶從檢測真實對象是否為 null中解脫出來,另外,由于創(chuàng)建代理對象在時間和處理復(fù)雜度上要少于創(chuàng)建真實對象。因此,在應(yīng)用程序啟動的時候,用代理對象代替真實對象初始化。

            例子:

             假設(shè)我們建立一個JAVA程序的集成開發(fā)環(huán)境(Integrated Development Environment),這個環(huán)境包括三個功能:編譯、運行、生成JavaDoc文檔。在新建和編輯Java程序時,最為常用的是編譯和運行。至于生成 JavaDoc文檔對于每一個Java程序不是必需的。因此,在Java開發(fā)環(huán)境啟動時,不要創(chuàng)建和裝載實現(xiàn)集成開發(fā)環(huán)境全部功能的所有對象,僅創(chuàng)建那些 在編輯、編譯、運行時用到的對象,保留提供生成JavaDoc文檔的對象,這是一個好的設(shè)計思想。這種對象創(chuàng)建策略能夠高效地利用內(nèi)存空間并且加快了集成 開發(fā)環(huán)境的啟動速度。

            假設(shè)編譯、運行、生成JavaDoc文檔這些功能分別由三個工具類提供??Compiler、Runtime和JavaDoc。客戶對象可以訪問的不同IDE操作的接口以抽象類IDEOperation的形式定義。

          public abstract class IDEOperation {
           private Compiler cmp;
           private Runtime rtime;
           public void compile(String javaFile) {
            cmp.compile(javaFile);
           }
           public void run(String classFile) {
            rtime.run (classFile);
           }
           //to be delayed until needed.
           public abstract void generateDocs(String javaFile);
           public IDEOperation() {
            cmp = new Compiler();
            rtime = new Runtime();
           }
          }

             類IDEOperation提供了編譯、運行java程序方法的實現(xiàn),作為它構(gòu)造函數(shù)的一部分,IDEOperation創(chuàng)建和裝載了進行編譯和執(zhí)行操 作的Compiler和Runtime對象。生成JavaDoc文檔的方法generateDocs方法被設(shè)計成抽象的方法,由它的子類來實現(xiàn)。

            讓我們定義抽象類IDEOperation的一個具體子類RealProcessor。作為RealProcessor構(gòu)造函數(shù)的一部分,創(chuàng)建JavaDoc對象來提供生成JavaDoc文檔的服務(wù),通過使用JavaDoc對象功能實現(xiàn)generateDocs方法。

          public class RealProcessor extends IDEOperation {
           JavaDoc jdoc;
           public RealProcessor() {
            super();
            jdoc = new JavaDoc();
           }
           public void generateDocs(String javaFile) {
            jdoc.generateDocs(javaFile);
           }
          }

             通過上面的實現(xiàn),RealProcessor類包含了編譯、運行和生成JavaDoc文檔的所有功能。像我們原來討論的,生成JavaDoc文檔的功能 不是每一個Java程序所必須的,當(dāng)RealProcessor實例化的時候,包括負責(zé)生成JavaDoc文檔的JavaDoc對象的一系列對象被創(chuàng)建。 推遲創(chuàng)建JavaDoc對象有以下優(yōu)點:

            1) 加速了RealProcessor對象的創(chuàng)建時間,因為它的構(gòu)造函數(shù)創(chuàng)建的很少的對象。

            2) 高效地利用內(nèi)存,因為在不需要對象服務(wù)的時候,不需要把對象保持在內(nèi)存中。

             在不改變RealProcessor實現(xiàn)的前提下,可以通過定義IDEOperation的另外一個子類ProxyProcessor來實現(xiàn)虛擬代理。 因為RealProcessor和ProxyProcessor共享相同的接口,客戶對象可以用ProxyProcessor代替 RealProcessor。圖25.1展示了類層次;

           

          Figure 25.1: IDEOperation Class Hierarchy

          public class ProxyProcessor extends IDEOperation {
           private RealProcessor realProcessor;
           public void generateDocs(String javaFile) {
            /*
            In order to generate javadocs
            the proxy loads the actual object and
            invokes its methods.
            */
            if (realProcessor == null) {
             realProcessor = new RealProcessor();
            }
            realProcessor.generateDocs(javaFile);
           }
          }

             作為自己的實例變量,ProxyProcessor維護了RealProcessor對象的一個引用。作為generateDocs方法的一部分, ProxyProcessor檢測引用變量是否被初始化為RealProcessor對象。如果沒有被初始化,它創(chuàng)建一個RealProcessor對象 并把這個對象分配給它的實例變量。一旦RealProcessor對象已經(jīng)被創(chuàng)建,就調(diào)用其上的generateDocs方法。

            實際上,也就是當(dāng)客戶對象第一次請求產(chǎn)生javadoc文檔時,RealProcessor才被初始化裝入內(nèi)存中。反過來,直到客戶需要為Java程序生成javadocs時,JavaDoc對象才會被創(chuàng)建和裝入內(nèi)存中。

            客戶對象像調(diào)用真實處理對象一樣調(diào)用ProxyProcessor上的方法,并不需要關(guān)心(知道)RealProcessor對象是否存在。 至于驗證、檢測和ProxyProcessor和RealProcessor之間的交互、這樣的細節(jié)對于客戶對象是透明的。

          public class Client {
           public static void main(String[] args) {
            /*
            At this point objects required for
            the compile and run operations are
            created, but not the objects that provide the
            generate Javadoc functionality.
            */
            IDEOperation IDE = new ProxyProcessor();
            IDE.compile("test.java");
            IDE.run("test.class");
            /*
            The Javadoc functionality is accessed
            For the first time and hence the
            Object offering the Javadoc generation
            Functionality is loaded at this point.
            */
            IDE.generateDocs("test.java");
           }
          }
          posted on 2005-11-15 14:21 JustinLei 閱讀(263) 評論(0)  編輯  收藏 所屬分類: Java
          主站蜘蛛池模板: 江永县| 高阳县| 独山县| 准格尔旗| 泗水县| 右玉县| 乌鲁木齐市| 湾仔区| 崇义县| 新晃| 睢宁县| 芦溪县| 江津市| 拉孜县| 大同市| 枝江市| 西林县| 施甸县| 南澳县| 化州市| 平顶山市| 扶余县| 酉阳| 威远县| 嘉祥县| 霍林郭勒市| 宁国市| 元氏县| 大埔县| 辛集市| 连州市| 隆化县| 洪湖市| 定结县| 黑河市| 祁东县| 开江县| 阿拉善盟| 修水县| 巩留县| 东丽区|