虛擬代理模式-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();
}
}

