1. 程式人生 > >虛擬代理模式-Virtual Proxy(Java實現)

虛擬代理模式-Virtual Proxy(Java實現)

brush ola 跳轉 true invite ace 實現 tile 缺點

虛擬代理模式-Virtual Proxy

虛擬代理模式(Virtual PRoxy)會推遲真正所需對象實例化時間. 在需要真正的對象工作之前, 如果代理對象能夠處理, 那麽暫時不需要真正對象來出手.

優點: 這種方法的優點是,在應用程序啟動時,由於不需要創建和裝載所有的對象,因此加速了應用程序的啟動。

缺點: 因為不能保證特定的應用程序對象被創建,在訪問這個對象的任何地方,都需要檢測確認它不是空(null)。性能的降低上不僅僅是多了一句代碼這麽簡單, ` if ` 這種跳轉類語句的很有可能會阻塞CPU的指令流水, 雖然有分值預測技術, 但是分支預測也是有命中率的....

還是回過頭講講本文的主題吧....

舉個例子: 有一批人來找老板談事情, 談事情之前需要預約, 將這些預約添加到計劃列表裏. "將預約添加到計劃列表裏"這件事, 本身並不需要老板親自現身, 老板不再的時候完全可以找一個助手來代做, 只有執行任務計劃列表裏的任務時, 老板才需現身處理(場景就是: 大家都是來找老板做事的, 並不是來找助手做事的, 助手只負責在老板不在的時候幫老板收集大家的需求, 最後收集完了, 他就把老板邀請過來, 老板來處理所有的事情).

Approvable接口

老板和助手都需要實現這個接口.

助手實現這個接口, 當調用助手的approve方法時, 助手就會去邀請老板過來, 讓老板處理清單.

老板實現這個接口, 是因為這些清單就需要老板來處理(approve)

public interface Approvable {
    void approve() ;
}

Boss類

老板是有身價的, 來一趟不容易, 所以小事交給助手做(就比如: 收集訪客們找老板有什麽事情, 並統計出一個清單). 沒必要一上來就把老板叫出來.

import java.util.LinkedList;
import java.util.List;

public class Boss implements Approvable {
    List<String> orders;

    {
        System.out.println("\nBoss出現...\n");

    }

    public Boss() {
        this.orders = new LinkedList<>();
    }

    public Boss(List<String> orders) {
        if (orders != null) {
            this.orders = orders;
        } else {
            this.orders = new LinkedList<>();
        }
    }

    public void addOrder(String order) {
        this.orders.add(order);
    }

    @Override
    public void approve() {
        while(orders.size()>0){
            String order = orders.remove(0);
            System.out.println("Boss處理了任務<" + order + ">");
        }
        System.out.println();
    }
}

Assistant類

Boss的代理類, 老板的助手.

import java.util.LinkedList;
import java.util.List;

/**
 * Boss的代理
 * 負責收集orders列表, 處理清單之前的收集工作就不用老板現身了,
 * 老板可以晚一點出現
 */
public class Assistant implements Approvable {
    List<String> orders;
    volatile Boss boss;

    public Assistant() {
        orders = new LinkedList<>();
    }

    public void addOrder(String order) {
        if (boss != null) {
            System.out.println("Boss親自將<" + order + ">任務添加到列表");
            boss.addOrder(order);
        } else {
            System.out.println("助手將<" + order + ">任務添加到列表");
            this.orders.add(order);
        }
    }

    @Override
    public void approve() {
        inviteBoss();
        boss.approve();
    }

    private void inviteBoss() {
        if (boss == null) {
            synchronized (this) {
                if (boss == null) {
                    boss = new Boss(orders);
                }
            }
        }
    }
}

Main

用於運行, 場景模擬

public class Main {
    public static void main(String[] args) {
        // 有很多人來找老板, 老板在忙, 助手先把所有事情安置好
        Assistant assistant = new Assistant();
        assistant.addOrder("我找Boss面試");
        assistant.addOrder("我找Boss借錢");
        assistant.addOrder("我找Boss聊天");

        // 收集好了, 助手的職責就完成了, 把Boss叫出來, 讓Boss處理. 或者說approve這件事,助手是做不了的, 只能叫出Boss來做.
        assistant.approve();

        // Boss剛才就被邀請過來, 現在就在現場. 所以就不需要助手轉告給Boss了. 大家告訴助手的事情, Boss也會聽到
        assistant.addOrder("我找Boss吃飯");
        assistant.addOrder("我找Boss喝酒");
        assistant.approve();
    }
}

技術分享圖片

虛擬代理模式-Virtual Proxy(Java實現)