真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

什么是代理模式

本篇內(nèi)容介紹了“什么是代理模式”的有關(guān)知識(shí),在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

烏達(dá)ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場(chǎng)景,ssl證書未來市場(chǎng)廣闊!成為成都創(chuàng)新互聯(lián)的ssl證書銷售渠道,可以享受市場(chǎng)價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:13518219792(備注:SSL證書合作)期待與您的合作!

代理模式

整個(gè)過程用代碼展示如下:

/**
 * 鞋廠接口
 */
public interface IShoesFactory {

    /**
     * 參觀工廠
     */
    void visitFactory();

    /**
     * 下訂單
     * @param price 金額
     */
    void placeOrder(double price);

    /**
     * 發(fā)貨
     */
    void ship();
}
/**
 * 鞋廠類
 */
public class ShoesFactory implements IShoesFactory{

    private String name;

    public ShoesFactory(String name) {
        this.name = name;
    }

    /**
     * 參觀工廠
     */
    @Override
    public void visitFactory() {
        System.out.println("帶客戶參觀" + name);
    }

    /**
     * 下訂單
     *
     * @param price 金額
     */
    @Override
    public void placeOrder(double price) {
        System.out.println("接到" + price + "元的訂單");
    }

    /**
     * 發(fā)貨
     */
    @Override
    public void ship() {
        System.out.println("開始發(fā)貨");
    }
}
/**
 * 代理鞋廠類
 */
public class ShoesFactoryProxy implements IShoesFactory{

    private IShoesFactory shoesFactory;

    public ShoesFactoryProxy(IShoesFactory shoesFactory) {
        this.shoesFactory = shoesFactory;
    }

    /**
     * 參觀工廠
     */
    @Override
    public void visitFactory() {
        shoesFactory.visitFactory();
    }

    /**
     * 下訂單
     *
     * @param price 金額
     */
    @Override
    public void placeOrder(double price) {
        shoesFactory.placeOrder(price);
    }

    /**
     * 發(fā)貨
     */
    @Override
    public void ship() {
        shoesFactory.ship();
    }
}

客戶類:

public class Client {
    public static void main(String[] args) {
        IShoesFactory factory = new ShoesFactory("劉望星的工廠");
        IShoesFactory factoryProxy = new ShoesFactoryProxy(factory);
        // 參觀工廠
        factoryProxy.visitFactory();
        // 下訂單
        factoryProxy.placeOrder(10000);
        // 發(fā)貨
        factoryProxy.ship();
    }
}

輸出結(jié)果:

帶客戶參觀劉望星的工廠
接到10000.0元的訂單
開始發(fā)貨

客戶要參觀工廠,小帥就帶客戶去參觀劉望星的工廠,和客戶說這就是自己的工廠??蛻粝蛐浵聠危浘桶延唵蜗陆o劉望星生產(chǎn)。

客戶類調(diào)用代理的方法,代理類再調(diào)用業(yè)務(wù)類的方法完成工作。

代理模式定義

代理模式(Proxy Pattern) :給某一個(gè)對(duì)象提供一個(gè)代理,并由代理對(duì)象控制對(duì)原對(duì)象的引用。 代理模式的英語叫Proxy,它是一種結(jié)構(gòu)型模式。

什么是代理模式

代理背后一般至少有一個(gè)實(shí)際對(duì)象,代理的外部功能和實(shí)際對(duì)象一般是一樣的,用戶與代理打交道,不直接接觸實(shí)際對(duì)象,甚至不知道實(shí)際對(duì)象的存在。

代理模式到底有什么用呢?難道僅僅是通過代理類做個(gè)轉(zhuǎn)發(fā)嗎?

當(dāng)然不是的,雖然外部功能和實(shí)際對(duì)象一樣,但代理有它存在的價(jià)值,代理也分為多種類型比如:

  • 遠(yuǎn)程(Remote)代理:適用于調(diào)用遠(yuǎn)程服務(wù)器對(duì)象的情況,代理通過網(wǎng)絡(luò)傳遞客戶端請(qǐng)求, 負(fù)責(zé)處理所有與網(wǎng)絡(luò)相關(guān)的復(fù)雜細(xì)節(jié),簡(jiǎn)化了客戶端的調(diào)用。

  • 虛擬(Virtual)代理:如果需要?jiǎng)?chuàng)建一個(gè)資源消耗較大的對(duì)象,先創(chuàng)建一個(gè)消耗相對(duì)較小的對(duì)象來表示,真實(shí)對(duì)象只在需要時(shí)才會(huì)被真正創(chuàng)建。

  • Copy-on-Write代理:它是虛擬代理的一種,把復(fù)制(克?。┎僮餮舆t到只有在客戶端真正需要時(shí)才執(zhí)行。一般來說,對(duì)象的深克隆是一個(gè) 開銷較大的操作,Copy-on-Write代理可以讓這個(gè)操作延遲,只有對(duì)象被用到的時(shí)候才被克隆。

  • 保護(hù)(Protect or Access)代理:控制對(duì)一個(gè)對(duì)象的訪問,可以給不同的用戶提供不同級(jí)別的使用權(quán)限。

  • 緩沖(Cache)代理:為某一個(gè)目標(biāo)操作的結(jié)果提供臨時(shí)的存儲(chǔ)空間,以便多個(gè)客戶端可以共享這些結(jié)果。

  • 防火墻(Firewall)代理:保護(hù)目標(biāo)不讓惡意用戶接近。

  • 同步化(Synchronization)代理:使幾個(gè)用戶能夠同時(shí)使用一個(gè)對(duì)象而沒有沖突。

  • 智能引用(Smart Reference)代理:當(dāng)一個(gè)對(duì)象被引用時(shí),提供一些額外的操作,如將此對(duì)象被調(diào)用的次數(shù)記錄下來等。

我們來看看幾個(gè)例子:

保護(hù)代理

保護(hù)(Protect or Access)代理的作用是,控制對(duì)一個(gè)對(duì)象的訪問,可以給不同的用戶提供不同級(jí)別的使用權(quán)限。

如果我們不想客戶訪問某個(gè)功能,就可以在代理類里做手腳,畢竟業(yè)務(wù)類都是通過代理類調(diào)用的嘛。

比如,小帥怕露餡,不想讓客戶參觀工廠,就可以改寫參觀工廠的方法:

什么是代理模式

輸出:

工廠禁止參觀
接到10000.0元的訂單
開始發(fā)貨

智能引用代理

智能引用(Smart Reference)代理的作用是,當(dāng)一個(gè)對(duì)象被引用時(shí),提供一些額外的操作,如將此對(duì)象被調(diào)用的次數(shù)記錄下來等。

比如,小帥作為代理商,肯定是要賺錢的,客戶下了一個(gè)10000元的訂單,小帥就和劉望星談好提成10%,就可以在代理類中把金額扣掉。

還有,小帥的工廠有自己的品牌,發(fā)貨之前還要貼上自己的牌子。

什么是代理模式

輸出:

工廠禁止參觀
接到9000.0元的訂單
貼上小帥牌標(biāo)簽。
開始發(fā)貨

代理模式的幾種應(yīng)用

  • 圖片代理:一個(gè)很常見的代理模式的應(yīng)用實(shí)例就是對(duì)大圖瀏覽的控制。用戶通過瀏覽器訪問網(wǎng)頁時(shí)先不加載真實(shí)的大圖,而是通過代理對(duì)象的方法來進(jìn)行處理。
    在代理對(duì)象的方法中,先使用一個(gè)線程向客戶端瀏覽器加載一個(gè)小圖片,然后在后臺(tái)使用另一個(gè)線程來調(diào)用大圖片的加載方法將大圖片加載到客戶端。當(dāng)需要瀏覽大圖片時(shí),再將大圖片在新網(wǎng)頁中顯示。

    如果用戶在瀏覽大圖時(shí)加載工作還沒有完成,可以再啟動(dòng)一個(gè)線程來顯示相應(yīng)的提示信息。通過代理技術(shù)結(jié)合多線程編程將真實(shí)圖片的加載放到后臺(tái)來操作,不影響前臺(tái)圖片的瀏覽。

  • 遠(yuǎn)程代理:遠(yuǎn)程代理可以將網(wǎng)絡(luò)的細(xì)節(jié)隱藏起來,使得客戶端不必考慮網(wǎng)絡(luò)的存在。客戶完全可以認(rèn)為被代理的遠(yuǎn)程業(yè)務(wù)對(duì)象是局域的而不是遠(yuǎn)程的,而遠(yuǎn)程代理對(duì)象承擔(dān)了大部分的網(wǎng)絡(luò)通信工作。

  • 虛擬代理:當(dāng)一個(gè)對(duì)象的加載十分耗費(fèi)資源的時(shí)候,虛擬代理的優(yōu)勢(shì)就非常明顯地體現(xiàn)出來了。虛擬代理模式是一種內(nèi)存節(jié)省技術(shù),那些占用大量?jī)?nèi)存或處理復(fù)雜的對(duì)象將推遲到使用它的時(shí)候才創(chuàng)建。

動(dòng)態(tài)代理

上面說的這些方法是靜態(tài)代理模式,真實(shí)的業(yè)務(wù)類必須是事先已經(jīng)創(chuàng)建好的的,并把它傳給代理對(duì)象,作為一個(gè)內(nèi)部成員。

靜態(tài)代理是這樣子的:

什么是代理模式

什么是代理模式

如果一個(gè)真實(shí)業(yè)務(wù)類必須對(duì)應(yīng)一個(gè)代理類,這將導(dǎo)致系統(tǒng)中的代理類的個(gè)數(shù)急劇增加,比如有10個(gè)不同的業(yè)務(wù)類,那么必須要有10個(gè)對(duì)應(yīng)的代理類,因此需要想辦法減少系統(tǒng)中類的個(gè)數(shù)。

動(dòng)態(tài)代理可以在事先不知道真實(shí)業(yè)務(wù)類的情況下使用代理類,在程序運(yùn)行期間由JVM根據(jù)反射等機(jī)制動(dòng)態(tài)的生成,動(dòng)態(tài)代理的典型應(yīng)用就是Spring AOP。

下面我們看一下Java SDK動(dòng)態(tài)代理的例子:

/**
 * 鞋廠接口
 */
public interface IShoesFactory {

    /**
     * 參觀工廠
     */
    void visitFactory();

    /**
     * 下訂單
     * @param price 金額
     */
    void placeOrder(double price);

    /**
     * 發(fā)貨
     */
    void ship();
}
/**
 * 鞋廠類
 */
public class ShoesFactory implements IShoesFactory {

    private String name;

    public ShoesFactory(String name) {
        this.name = name;
    }

    /**
     * 參觀工廠
     */
    @Override
    public void visitFactory() {
        System.out.println("帶客戶參觀" + name);
    }

    /**
     * 下訂單
     *
     * @param price 金額
     */
    @Override
    public void placeOrder(double price) {
        System.out.println("接到" + price + "元的訂單");
    }

    /**
     * 發(fā)貨
     */
    @Override
    public void ship() {
        System.out.println("開始發(fā)貨");
    }
}

InvocationHandler接口是proxy代理實(shí)例的調(diào)用處理程序?qū)崿F(xiàn)的一個(gè)接口,代理類每調(diào)用一次方法就會(huì)進(jìn)入這里的invoke方法。

public class ShoesFactoryHandler implements InvocationHandler {

    /**
     * 被代理的對(duì)象,實(shí)際的方法執(zhí)行者
     */
    private Object proxiedObject;

    public ShoesFactoryHandler(Object proxiedObject) {
        this.proxiedObject = proxiedObject;
    }

    /**
     * 代理類每調(diào)用一次方法就會(huì)進(jìn)入這里
     * @param proxy 表示代理對(duì)象本身,需要注意,它不是被代理的對(duì)象
     * @param method 表示正在被調(diào)用的方法
     * @param args 表示方法的參數(shù)
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        /*if(method.getName().equals("visitFactory")) {
            System.out.println("工廠禁止參觀");
        }*/
        if(method.getName().equals("placeOrder")) {
            // 如果是下訂單方法,給代工廠9折的價(jià)格
            method.invoke(proxiedObject, Double.parseDouble(String.valueOf(args[0])) * 0.9);
        }
        else if(method.getName().equals("ship")) {
            // 如果是發(fā)貨方法,發(fā)貨之前先貼上標(biāo)簽
            System.out.println("貼上小帥牌標(biāo)簽");
            method.invoke(proxiedObject, args);
        } else {
            // 其他方法,直接調(diào)用
            method.invoke(proxiedObject, args);
        }
        return null;
    }
}

Proxy類調(diào)用newProxyInstance方法來創(chuàng)建一個(gè)代理對(duì)象,上面的InvocationHandler對(duì)象作為參數(shù)之一。

public class ShoesFactoryProxy {
    /**
     * 生成動(dòng)態(tài)代理
     * @param proxiedObject 被代理的對(duì)象,實(shí)際的方法執(zhí)行者
     * @return
     */
    public Object createProxy(Object proxiedObject) {
        // 獲取對(duì)應(yīng)的ClassLoader
        ClassLoader classLoader = proxiedObject.getClass().getClassLoader();
        // 獲取所有的接口
        Class[] interfaces = proxiedObject.getClass().getInterfaces();
        // 創(chuàng)建一個(gè)傳給代理類的調(diào)用請(qǐng)求處理器
        ShoesFactoryHandler handler = new ShoesFactoryHandler(proxiedObject);
        return Proxy.newProxyInstance(classLoader, interfaces, handler);
    }
}

客戶端類:

public class Client {
    public static void main(String[] args) {
        IShoesFactory factory = new ShoesFactory("劉望星的工廠");
        ShoesFactoryProxy shoesFactoryProxy = new ShoesFactoryProxy();
        IShoesFactory factoryProxy = (IShoesFactory)shoesFactoryProxy.createProxy(factory);
        // 參觀工廠
        factoryProxy.visitFactory();
        // 下訂單
        factoryProxy.placeOrder(10000);
        // 發(fā)貨
        factoryProxy.ship();
    }
}

輸出結(jié)果:

帶客戶參觀劉望星的工廠
接到9000.0元的訂單
貼上小帥牌標(biāo)簽
開始發(fā)貨

通用性更強(qiáng)些的動(dòng)態(tài)代理類一般是這樣的:

public class NormalHandler implements InvocationHandler {

    /**
     * 被代理的對(duì)象,實(shí)際的方法執(zhí)行者
     */
    private Object proxiedObject;

    public NormalHandler(Object proxiedObject) {
        this.proxiedObject = proxiedObject;
    }

    /**
     * 代理類每調(diào)用一次方法就會(huì)進(jìn)入這里
     * @param proxy 表示代理對(duì)象本身,需要注意,它不是被代理的對(duì)象
     * @param method 表示正在被調(diào)用的方法
     * @param args 表示方法的參數(shù)
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
           // 調(diào)用實(shí)際方法之前的操作
        preRequest();
        // 調(diào)用實(shí)際方法
           Object result = method.invoke(proxiedObject, args);
           // 調(diào)用實(shí)際方法之后的操作
           afterRequest();
        }
        return result;
    }
}

這樣,我們就能在preRequest()和afterRequest()方法中做很多事情了,比如記錄日志,記錄調(diào)用時(shí)間等等。

總結(jié)

代理模式看上去和裝飾者模式很像,不過它們的意圖是不一樣的,裝飾者模式是為對(duì)象加上新的行為,而代理模式是作為真實(shí)對(duì)象的替身,控制對(duì)象的訪問。

比如,保護(hù)代理,進(jìn)行權(quán)限控制,不讓客戶訪問某些功能;比如,虛擬代理,在真實(shí)的對(duì)象創(chuàng)建之前,先返回預(yù)定設(shè)定好的信息。

下面我們來看看代理模式的優(yōu)點(diǎn)和缺點(diǎn):

優(yōu)點(diǎn)

  • 代理模式能夠協(xié)調(diào)調(diào)用者和被調(diào)用者,在一定程度上降低了系統(tǒng)的耦合度。

  • 你可以在客戶端毫無察覺的情況下控制服務(wù)對(duì)象。

  • 即使服務(wù)對(duì)象還未準(zhǔn)備好或不存在, 代理也可以正常工作。

  • 符合開閉原則, 你可以在不對(duì)服務(wù)或客戶端做出修改的情況下創(chuàng)建新代理。

缺點(diǎn)

  • 由于在客戶端和真實(shí)業(yè)務(wù)類之間增加了代理對(duì)象,因此有些類型的代理模式可能會(huì)造成請(qǐng)求的處理速度變慢。

  • 實(shí)現(xiàn)代理模式需要額外的工作,增加了程序的復(fù)雜度。

“什么是代理模式”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!


本文標(biāo)題:什么是代理模式
文章起源:http://weahome.cn/article/gojggs.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部