成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

給女朋友講解什么是代理模式

stormgens / 3410人閱讀

摘要:受知乎文章和設(shè)計模式之禪的啟發(fā),我也來搞一篇腦洞小開的文章由標(biāo)題可知,這篇文章是寫給我女朋友看的。于是這就讓經(jīng)紀(jì)人對粉絲說只有萬,我才會寫代碼。

前言
只有光頭才能變強(qiáng)

回顧前面:

ThreadLocal就是這么簡單

多線程三分鐘就可以入個門了!

多線程基礎(chǔ)必要知識點!看了學(xué)習(xí)多線程事半功倍

Java鎖機(jī)制了解一下

AQS簡簡單單過一遍

Lock鎖子類了解一下

線程池你真不來了解一下嗎?

多線程之死鎖就是這么簡單

多線程就先告一段落了,昨天寫完多線程,本來打算是看IO的知識點的,后來看了一下IO的幾種模型,又翻了一下《Java編程思想》。不知道從哪下手~~

在看到FilterInputStreamFilterOutputStream時看到了之前常聽見的裝飾模式(對IO一定了解的同學(xué)可能都會知道那么一句話:在IO用得最多的就是裝飾模式了)!

看到這里你以為我要講裝飾模式了么?不是,今天我們來講講什么是代理模式(就是這么皮,裝飾模式明天講吧~)。

受知乎@Beautiful Java文章和《設(shè)計模式之禪》的啟發(fā),我也來搞一篇腦洞小開的文章..

由標(biāo)題可知,這篇文章是寫給我女朋友看的。自從她知道我開了公眾號以后就每天看我寫的文章,之前寫點小算法的時候她覺得編程還是挺有意思,想去學(xué)學(xué)。可是,從我開始寫Java容器、多線程,她說一點都看不懂了。于是乎,現(xiàn)在來寫點既高大尚、又容易懂的東西

    GirlFriend girlFriend = new GirlFriend();
    sayingProxy(girlFriend);

那么接下來就開始吧,如果文章有錯誤的地方請大家多多包涵,不吝在評論區(qū)指正哦~

聲明:本文使用JDK1.8
一、代理模式介紹

代理模式是一種非常好理解的一種設(shè)計模式,生活中處處都有代理

王寶強(qiáng)作為一個明星,不可能什么事都由他自己干(約電視劇、排期之類的),于是他請了經(jīng)紀(jì)人

去醫(yī)院掛號很麻煩怎么辦?找黃牛幫我們掛號

王者榮耀技術(shù)水平不夠,想要上分怎么辦?請游戲代練

寫點不正經(jīng)的代碼被警察捉走了怎么辦?請律師幫我們打官司

無論是經(jīng)紀(jì)人、黃牛、游戲代練、律師他們都是得幫我們干活。但是他們不能一手包辦的,僅僅在“我”的基礎(chǔ)上處理一些雜碎的東西(我們不愿意干、或者干不了的東西)。

導(dǎo)演找了黃寶強(qiáng)的經(jīng)紀(jì)人讓王寶強(qiáng)去拍電影

黃牛去排隊讓我們能掛上號!

游戲代練上分是我的微信賬號

律師幫我處理法律上的問題,如果打官司失敗,牢還是由我來坐!

再舉個例子:

現(xiàn)在我是一個網(wǎng)紅,擁有很多粉絲。粉絲希望我天天寫代碼給他們看,那我肯定不能天天寫代碼啊,我豈不是很忙....于是乎,我就去找了個經(jīng)紀(jì)人。這個經(jīng)紀(jì)人就代表了我。當(dāng)忠實粉絲想要我寫代碼的時候,應(yīng)該是先找經(jīng)紀(jì)人,告訴經(jīng)紀(jì)人想讓我寫代碼。

十年過去了,我越來越紅了,頭發(fā)也越來越少。不是粉絲想要我寫代碼,我就寫了。我要收費了。但是呢,作為一個公眾人物,不可能是我自己說:我要收10000萬,我才會去寫代碼。于是這就讓經(jīng)紀(jì)人對粉絲說:只有10000萬,我才會寫代碼。

無論外界是想要我干什么,都要經(jīng)過我的經(jīng)紀(jì)人。我的經(jīng)紀(jì)人也會在其中考慮收費、推脫它們的請求。

經(jīng)紀(jì)人就是代理,實際寫代碼的還是我

所以說代理模式就是:當(dāng)前對象不愿意干的,沒法干的東西委托給別的對象來做,我只要做好本分的東西就好了!

二、用代碼描述代理模式(靜態(tài)代理)

這里有一個程序員接口,他們每天就是寫代碼

public interface Programmer {

    // 程序員每天都寫代碼
    void coding();

}

Java3y也是一個程序員,他也寫代碼(每個程序員寫的代碼都不一樣,所以分了接口和實現(xiàn)類)

public class Java3y implements Programmer {

    @Override
    public void coding() {
        System.out.println("Java3y最新文章:......給女朋友講解什么是代理模式.......");
    }
}

此時Java3y已經(jīng)是一個網(wǎng)紅了,他不想枯燥地寫代碼。他在想:“在寫代碼時能賺錢就好咯,有人給我錢,我才寫代碼”。但是,Java3y的文筆太爛了,一旦有什么冬瓜豆腐,分分鐘變成過氣網(wǎng)紅,這是Java3y不愿意看到的。

而知乎、博客園這種平臺又不能自己給自己點贊來吸引流量(-->當(dāng)前對象無法做)

所以Java3y去請了一個程序員大V(代理)來實現(xiàn)自己的計劃,這個程序員大V會每次讓Java3y發(fā)文章時,就給Java3y點贊、評論、鼓吹這文章好。只要流量有了,錢就到手了。

public class ProgrammerBigV implements Programmer {
    
    // 指定程序員大V要讓誰發(fā)文章(先發(fā)文章、后點贊)
    private Java3y java3y ;

    public ProgrammerBigV(Java3y java3y) {
        this.java3y = java3y;
    }

    // 程序員大V點贊評論收藏轉(zhuǎn)發(fā)
    public void upvote() {
        System.out.println("程序員大V點贊評論收藏轉(zhuǎn)發(fā)!");
    }

    @Override
    public void coding() {

        // 讓Java3y發(fā)文章
        java3y.coding();

        // 程序員大V點贊評論收藏轉(zhuǎn)發(fā)!
        upvote();
    }
}

文章(代碼)還是由Java3y來發(fā),但每次發(fā)送之后程序員大V都會點贊。

public class Main {

    public static void main(String[] args) {

        // 想要發(fā)達(dá)的Java3y
        Java3y java3y = new Java3y();

        // 受委托程序員大V
        Programmer programmer = new ProgrammerBigV(java3y);

        // 受委托程序員大V讓Java3y發(fā)文章,大V(自己)來點贊
        programmer.coding();
    }  
}

這樣一來,不明真相的路人就覺得Java3y是真厲害,知識付費。

2.1透明代理(普通代理)

經(jīng)過一段時間,Java3y嘗到甜頭了,覺得這是一條財路。于是Java3y給足了程序員大V錢,讓程序員大V只做他的生意,不能做其他人的生意(斷了其他人的財路)。

于是乎,程序員大V做Java3y一個人的生意:

public class ProgrammerBigV implements Programmer {

    // 指定程序員大V要給Java3y點贊
    private Java3y java3y ;

    // 只做Java3y的生意了
    public ProgrammerBigV() {
        this.java3y = new Java3y();
    }

    // 程序員大V點贊評論收藏轉(zhuǎn)發(fā)
    public void upvote() {
        System.out.println("程序員大V點贊評論收藏轉(zhuǎn)發(fā)!");
    }

    @Override
    public void coding() {

        // 讓Java3y發(fā)文章了
        java3y.coding();

        // 程序員大V點贊評論收藏轉(zhuǎn)發(fā)!
        upvote();

    }
}

于是乎,程序員大V想要賺點零花錢的時候直接讓Java3y發(fā)文章就好了。

public class Main {

    public static void main(String[] args) {

        // 受委托程序員大V
        Programmer programmer = new ProgrammerBigV();

        // 受委托程序員大V讓Java3y發(fā)文章,大V來點贊
        programmer.coding();
        
    }
}

此時,真實對象(Java3y)對外界來說是透明的。

2.2代理類自定義方法

程序員大V看到Java3y一直順風(fēng)順?biāo)?,賺大錢了。覺得是時候要加價了,于是在點贊完畢后就跟Java3y說每點完一次贊加100塊

于是乎,程序員大V就增添了另外一個方法:addMoney()

public class ProgrammerBigV implements Programmer {


    // ..省略了上面的代碼

    // 加價啦
    public void addMoney() {
        System.out.println("這次我要加100塊");
    }

    @Override
    public void coding() {

        // 讓Java3y發(fā)文章了
        java3y.coding();

        // 程序員大V點贊評論收藏轉(zhuǎn)發(fā)!
        upvote();

        // 加價
        addMoney();

    }
}

于是乎程序員大V每次都能多100塊:

三、動態(tài)代理

幾年時間過去了,Java3y靠著程序員的大V點贊還是沒發(fā)財(本質(zhì)上Java3y還沒有干貨,沒受到大眾的認(rèn)可)。此時已經(jīng)有很多人晉升成了程序員大V了,但是之前的那個程序員大V還是一直累加著錢...雖然在開始的時候Java3y嘗到了甜頭,但現(xiàn)在Java3y財政已經(jīng)匱乏了。

Java3y將自己的失敗認(rèn)為:一定是那個程序員大V轉(zhuǎn)門為我點贊被識破了,吃瓜群眾都知道了,他收費又那么貴。

于是Java3y不請程序員大V了,請水軍來點贊(水軍便宜,只要能點贊就行了):

public class Main {

    public static void main(String[] args1) {

        // Java3y請水軍
        Java3y java3y = new Java3y();

        Programmer programmerWaterArmy = (Programmer) Proxy.newProxyInstance(java3y.getClass().getClassLoader(), java3y.getClass().getInterfaces(), (proxy, method, args) -> {

            // 如果是調(diào)用coding方法,那么水軍就要點贊了
            if (method.getName().equals("coding")) {
                method.invoke(java3y, args);
                System.out.println("我是水軍,我來點贊了!");

            } else {
                // 如果不是調(diào)用coding方法,那么調(diào)用原對象的方法
                return method.invoke(java3y, args);
            }

            return null;
        });

        // 每當(dāng)Java3y寫完文章,水軍都會點贊
        programmerWaterArmy.coding();

    }

}

每當(dāng)Java3y發(fā)文章的時候,水軍都會點贊。

Java3y感嘆:請水軍真是方便啊~

3.1動態(tài)代理調(diào)用過程

我們來看看究竟是怎么請水軍的:

Java提供了一個Proxy類,調(diào)用它的newInstance方法可以生成某個對象的代理對象,該方法需要三個參數(shù):

參數(shù)一:生成代理對象使用哪個類裝載器【一般我們使用的是被代理類的裝載器】

參數(shù)二:生成哪個對象的代理對象,通過接口指定【指定要被代理類的接口】

參數(shù)三:生成的代理對象的方法里干什么事【實現(xiàn)handler接口,我們想怎么實現(xiàn)就怎么實現(xiàn)】

在編寫動態(tài)代理之前,要明確幾個概念:

代理對象擁有目標(biāo)對象相同的方法【因為參數(shù)二指定了對象的接口,代理對象會實現(xiàn)接口的所有方法】

用戶調(diào)用代理對象的什么方法,都是在調(diào)用處理器的invoke方法?!颈粩r截】

使用JDK動態(tài)代理必須要有接口【參數(shù)二需要接口】

上面也說了:代理對象會實現(xiàn)接口的所有方法,這些實現(xiàn)的方法交由我們的handler來處理!

所有通過動態(tài)代理實現(xiàn)的方法全部通過invoke()調(diào)用

所以動態(tài)代理調(diào)用過程是這樣子的:

3.2靜態(tài)代理和動態(tài)代理的區(qū)別

很明顯的是:

靜態(tài)代理需要自己寫代理類-->代理類需要實現(xiàn)與目標(biāo)對象相同的接口

而動態(tài)代理不需要自己編寫代理類--->(是動態(tài)生成的)

使用靜態(tài)代理時:

如果目標(biāo)對象的接口有很多方法的話,那我們還是得一一實現(xiàn),這樣就會比較麻煩

使用動態(tài)代理時:

代理對象的生成,是利用JDKAPI,動態(tài)地在內(nèi)存中構(gòu)建代理對象(需要我們指定創(chuàng)建 代理對象/目標(biāo)對象 實現(xiàn)的接口的類型),并且會默認(rèn)實現(xiàn)接口的全部方法。

四、典型應(yīng)用

我們之前寫中文過濾器的時候,需要使用包裝設(shè)計模式來設(shè)計一個request類。如果不是Servlet提供了實現(xiàn)類給我們,我們使用包裝設(shè)計模式會比較麻煩

現(xiàn)在我們學(xué)習(xí)了動態(tài)代理了,動態(tài)代理就是攔截直接訪問對象,可以給對象進(jìn)行增強(qiáng)的一項技能

4.1中文過濾器
    public void doFilter(final ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        final HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;

        response.setContentType("text/html;charset=UTF-8");
        request.setCharacterEncoding("UTF-8");


        //放出去的是代理對象
        chain.doFilter((ServletRequest) Proxy.newProxyInstance(CharacterEncodingFilter.class.getClassLoader(), request.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                //判斷是不是getParameter方法
                if (!method.getName().equals("getParameter")) {

                    //不是就使用request調(diào)用
                   return method.invoke(request, args);
                }

                //判斷是否是get類型的
                if (!request.getMethod().equalsIgnoreCase("get")) {
                   return method.invoke(request, args);
                }

                //執(zhí)行到這里,只能是get類型的getParameter方法了。
                String value = (String) method.invoke(request, args);
                if (value == null) {
                    return null;
                }
                return new String(value.getBytes("ISO8859-1"), "UTF-8");
            }

        }), response);

    }
五、總結(jié)
第一次以這種方式寫文章,舉的例子可能會不妥,希望大家見諒~

本文主要講解了代理模式的幾個要點,其實還有一些細(xì)節(jié)的:比如“強(qiáng)制代理”(只能通過被代理對象找到代理對象,不能繞過代理對象直接訪問被代理對象)。只是用得比較少,我就不說了~~

要實現(xiàn)動態(tài)代理必須要有接口的,動態(tài)代理是基于接口來代理的(實現(xiàn)接口的所有方法),如果沒有接口的話我們可以考慮cglib代理。

cglib代理也叫子類代理,從內(nèi)存中構(gòu)建出一個子類來擴(kuò)展目標(biāo)對象的功能!

這里我就不再貼出代碼來了,因為cglib的代理教程也很多,與動態(tài)代理實現(xiàn)差不多~~~

總的來說:代理模式是我們寫代碼中用得很多的一種模式了,Spring的AOP底層其實就是動態(tài)代理來實現(xiàn)的-->面向切面編程。具體可參考我之前寫的那篇文章:

Spring【AOP模塊】就這么簡單

其實只要記住一點:原有的對象需要額外的功能,想想動態(tài)代理這項技術(shù)

參考資料:

《設(shè)計模式之禪》

https://wangjingxin.top/2016/11/16/proxy/

https://www.cnblogs.com/doucheyard/p/5737366.html

如果文章有錯的地方歡迎指正,大家互相交流。習(xí)慣在微信看技術(shù)文章,想要獲取更多的Java資源的同學(xué),可以關(guān)注微信公眾號:Java3y。為了大家方便,剛新建了一下qq群:742919422,大家也可以去交流交流。謝謝支持了!希望能多介紹給其他有需要的朋友

文章的目錄導(dǎo)航

https://zhongfucheng.bitcron.com/post/shou-ji/wen-zhang-dao-hang

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/69294.html

相關(guān)文章

  • 包裝模式這么簡單啦

    摘要:包裝模式是這樣干的首先我們弄一個裝飾器,它實現(xiàn)了接口,以組合的方式接收我們的默認(rèn)實現(xiàn)類。其實裝飾器抽象類的作用就是代理核心的功能還是由最簡單的實現(xiàn)類來做,只不過在擴(kuò)展的時候可以添加一些沒有的功能而已。 前言 只有光頭才能變強(qiáng) 回顧前面: 給女朋友講解什么是代理模式 前一篇已經(jīng)講解了代理模式了,今天要講解的就是裝飾模式啦~ 在看到FilterInputStream和FilterOutpu...

    Developer 評論0 收藏0
  • Spring AOP就這么簡單啦

    摘要:是一種特殊的增強(qiáng)切面切面由切點和增強(qiáng)通知組成,它既包括了橫切邏輯的定義也包括了連接點的定義。實際上,一個的實現(xiàn)被拆分到多個類中在中聲明切面我們知道注解很方便,但是,要想使用注解的方式使用就必須要有源碼因為我們要 前言 只有光頭才能變強(qiáng) 上一篇已經(jīng)講解了Spring IOC知識點一網(wǎng)打盡!,這篇主要是講解Spring的AOP模塊~ 之前我已經(jīng)寫過一篇關(guān)于AOP的文章了,那篇把比較重要的知...

    Jacendfeng 評論0 收藏0
  • 代理模式

    摘要:簡介代理模式委托模式就是使用代理對象來訪問目標(biāo)對象這樣可以在目標(biāo)對象執(zhí)行前后來做一些邏輯處理這里使用到編程中的一個思想不要隨意去修改別人已經(jīng)寫好的代碼或者方法如果需改修改可以通過代理的方式來擴(kuò)展該方法代理模式通用類圖設(shè)計模式之禪文中提到為其 簡介 代理模式(委托模式)就是使用代理對象來訪問目標(biāo)對象, 這樣可以在目標(biāo)對象執(zhí)行前后, 來做一些邏輯處理. 這里使用到編程中的一個思想:不要隨意...

    keithxiaoy 評論0 收藏0
  • 【轉(zhuǎn)】成為Java頂尖程序員 ,看這10本書就夠了

    摘要:實戰(zhàn)高并發(fā)程序設(shè)計這本書是目前點評推薦比較多的書,其特色是案例小,好實踐代碼有場景,實用。想要學(xué)習(xí)多線程的朋友,這本書是我大力推薦的,我的個人博客里面二十多篇的多線程博文都是基于此書,并且在這本書的基礎(chǔ)上進(jìn)行提煉和總結(jié)而寫出來的。 學(xué)習(xí)的最好途徑就是看書,這是我自己學(xué)習(xí)并且小有了一定的積累之后的第一體會。個人認(rèn)為看書有兩點好處:showImg(/img/bVr5S5);  1.能出版出...

    DTeam 評論0 收藏0
  • 《大型網(wǎng)站系統(tǒng)與Java中間件》讀書筆記 (中)

    摘要:文本已收錄至我的倉庫,歡迎回顧上一篇大型網(wǎng)站系統(tǒng)與中間件讀書筆記一這周周末讀了第四章,現(xiàn)在過來做做筆記,希望能幫助到大家。沒錯,我們通過肯定是可以完成兩個系統(tǒng)之間的通信的問題的。 前言 只有光頭才能變強(qiáng)。文本已收錄至我的GitHub倉庫,歡迎Star:https://github.com/ZhongFuCheng3y/3y 回顧上一篇: 《大型網(wǎng)站系統(tǒng)與Java中間件》讀書筆記(一)...

    fredshare 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<