設計模式 -- 靜態代理模式(線程底層原理)

什麼是代理?

在介紹靜態代理模式之前,先來聊聊什麼是代理?
代理在我們的生活中十分的常見,比如 小明 代理 小 A 寫作業(不寫就兩橫一豎幹你,就是這麼豪橫),婚慶公司幫助我們打理婚前婚後的結婚事務。

從這些例子中我們就可以發現,要想實現代理,就必須要有兩個角色: 代理者,被代理者。
或者是: 真實對象、代理對象
。並且這兩個對象中間一定有一個共同的事務將兩者聯繫起來。

比如結婚對象(真實對象)和婚慶公司(代理對象) 是因爲結婚這個條件才聯繫到一起。

靜態代理模式設計:

先想一下這個問題,如何爲一個類增加一些功能(不再內部寫方法的前提下)?

  1. 繼承一個類。
  2. 實現一個接口。
  3. 通過註解。

在開發時我們提倡 面向接口開發,關於這方面的內容,可以點擊藍字進行查看(包您滿意)。所以我們
1、先創建一個接口:

	interface Marry {
		// 結婚的功能
	    void marry();
	}

2、需要有一個真實對象,真實對象要結婚,所以實現 Marry 接口:

class You implements Marry {

    @Override
    public void marry() {
        System.out.println("結婚了,好開心喲。。。。");
    }
}

3、需要有一個代理對象,幫助處理結婚事宜(人生頭一次,不能一個人幹啊)
婚慶公司肯定不止要幫助我們操辦結婚當天,肯定在婚前婚後還要幫助處理一些事情,所以在實現接口的同時還要有一些自己的功能

class WeddingCompany implements Marry{

    // 婚慶公司要幫助的真實對象
    private Marry target;
    // 真實對象作爲參數,和婚慶公司(代理對象)之間進行簽約(建立一種聯繫)
    public WeddingCompany(Marry target) {
        this.target = target;
    }

    @Override
    // 代理對象需要乾的事(需要把真實對象做的事情包括在內)
    public void marry() {
        before();
        // 真實對象在婚前公司的幫助下幹自己的事(接新娘子,親親,嘻嘻)
        this.target.marry();
        after();
    }

    // 婚前
    public void before() {
        System.out.println("結婚前,要讓新娘美美的。。。。。");
    }

    // 婚後
    public void after() {
        System.out.println("結婚後,大家舒舒服服的。。。。。。");
    }

完整代碼:

package thread;

// 靜態代理模式
public class StaticProxy {

    public static void main(String[] args) {
        // 把真實對象交給代理對象(真實對象中的方法就是代理對象中必須要做的事情之一)
        Marry weddingCompany = new WeddingCompany(new You());
        // 代理對象進行操辦
        weddingCompany.marry();
    }

}


// 共同的接口(將兩者聯繫到一起)
interface Marry {
    void marry();
}

class You implements Marry {

    @Override
    public void marry() {
        System.out.println("結婚了,好開心喲。。。。");
    }
}

class WeddingCompany implements Marry{

    // 婚慶公司要幫助的真實對象
    private Marry target;
    // 真實對象作爲參數,和婚慶公司(代理對象)之間進行簽約(建立一種聯繫)
    public WeddingCompany(Marry target) {
        this.target = target;
    }

    @Override
    // 代理對象需要乾的事(需要把真實對象做的事情包括在內)
    public void marry() {
        before();
        // 真實對象在婚前公司的幫助下幹自己的事(接新娘子,親親,嘻嘻)
        this.target.marry();
        after();
    }

    // 婚前
    public void before() {
        System.out.println("結婚前,要讓新娘美美的。。。。。");
    }

    // 婚後
    public void after() {
        System.out.println("結婚後,大家舒舒服服的。。。。。。");
    }
}

靜態代理模式和線程之間的關係:

在這裏插入圖片描述
看一下上圖,是不是神似呢?
再看一下線程中的對象是不是實現的同一個接口:
在這裏插入圖片描述
在這裏插入圖片描述
可以看到,我們創建的線程類和 Thread 類都實現了 Runnable 接口,而Runnable 接口中又有
run() 方法,所以說 我們的 StaticProxy new 出的對象就是一個真實對象,而 Thread 是一個代理對象(因爲 Thread 中不止 run() 一個方法)。

效果圖:
在這裏插入圖片描述

靜態代理的優缺點:

優點:
1.代理使客戶端不需要知道實現類是什麼,怎麼做的,而客戶端只需知道代理即可(解耦合)
2.業務類只需要關注業務邏輯本身,保證了業務類的重用性。這是代理的共有優點。
缺點:
1.代理類和委託類實現了相同的接口,代理類通過委託類實現了相同的方法。這樣就出現了大量的代碼重複。如果接口增加一個方法,除了所有實現類需要實現這個方法外,所有代理類也需要實現此方法。增加了代碼維護的複雜度。
2.代理對象只服務於一種類型的對象,如果要服務多類型的對象。勢必要爲每一種對象都進行代理,靜態代理在程序規模稍大時就無法勝任了

小結:

第一步:要有一個共同使用的接口.
第二步:代理角色和真實角色共同實現該接口,代理角色實現需要的功能。
第三步:創建真實角色的對象和代理角色的對象,並將真實角色對象的引用傳給代理角色,讓代理角色去執行功能。

後記:

設計模式是一種思想,要想真正的運用到自己的項目中,還需要多加的練習,本人也在不在的鍛鍊和學習中,各位有興趣的小夥伴可以一起交流,共同進步。
如果文章對您有幫助,別忘了來個三連哦,嘻嘻,萬分感謝。

參考博客和狂神的視頻講解:
激情的狼王 :https://www.jianshu.com/p/fa6a3ec68e1d
那麼長的代碼:https://www.cnblogs.com/yxiaooutlook/p/7798563.html
狂神Java說大佬的視頻講解:https://www.bilibili.com/video/BV1c64y1M7qN

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章