描述:
計數(shù)代理模式在客戶對象調(diào)用服務(wù)提供者對象上方法的前后執(zhí)行諸如日志(logging)和計數(shù)(counting)一系列附加
功能時很有用。計數(shù)代理模式建議把這些附加功能封裝在一個單獨的對象,這個對象就是指計數(shù)代理對象,而不是把這些附加的功能實現(xiàn)放到服務(wù)提供者的內(nèi)部。良
好的對象設(shè)計的一個特征就是對象要專注于提供特定的功能。換句話說,理想的對象不應該做各種不相干的事情。把諸如日志(logging)和計數(shù)
(counting)等類似的功能封裝為一個單獨的對象,而讓服務(wù)提供者對象僅提供它自己的特定功能。也就是說,只允許服務(wù)提供者對象執(zhí)行定義良好、特定
的任務(wù)。
計數(shù)代理被設(shè)計成可以被客戶訪問的與服務(wù)提供者具有相同接口的對象。客戶對象不是直接訪問服務(wù)提供者,而是調(diào)用計數(shù)代理對象上的方法,計數(shù)代理執(zhí)行必要的紀錄日志(logging)和計數(shù)(counting)功能后,再把方法調(diào)用傳遞給服務(wù)提供著對象。如圖1
 Figure1: Generic Class Association When the Counting Proxy Pattern Is Applied |
下面的例子說明了如何在應用程序中利用計數(shù)代理。
例子:
讓我們設(shè)計一個Order類,類層次如圖2,OrderIF接口聲明了getAllOrders讀取數(shù)據(jù)庫中所有訂單的簡單方法。
 Figure2: Order Class Hierarchy |
public interface OrderIF { public Vector getAllOrders(); } |
作為getAllOrders方法實現(xiàn)的一部分,Order類實用了FileUtil工具類從order.txt文件中讀取訂單項。
public class Order implements OrderIF { public Vector getAllOrders() { FileUtil fileUtil = new FileUtil(); Vector v = fileUtil.fileToVector("orders.txt"); return v; } } |
讓我們假定在調(diào)用getAllOrders()時,需要把取數(shù)據(jù)文件所花費的時間和記錄條數(shù)要記錄的log日志文件中。
這個附加的功能可以設(shè)計一個單獨的OrderProxy類來實現(xiàn),它與真實對象Order一樣實現(xiàn)OrderIF接口。這樣保證了OrderProxy對象提供給客戶與真實對象Order一樣的接口。如圖3
 Figure3: Order Class Hierarchy with the Counting Proxy |
public class OrderProxy implements OrderIF { private int counter = 0; public Vector getAllOrders() { Order order = new Order(); counter++; long t1 = System.currentTimeMillis (); Vector v = order.getAllOrders(); long t2 = System.currentTimeMillis(); long timeDiff = t2 ? t1; String msg = "Iteration=" + counter + "::Time=" + timeDiff + "ms"; //log the message FileUtil fileUtil = new FileUtil(); fileUtil.writeToFile("log.txt”,msg, true, true); return v; } } |
客戶對象MainApp就想調(diào)用真實對象Order一樣調(diào)用OrderProxy對象上的getAllOrders()方法,OrderProxy對象
傳遞這個調(diào)用給真實對象Order,計算讀取所有訂單所花費的時間并使用FileUtil幫助類將其紀錄的log日志文件中。在這個過程中,
OrderProxy扮演者計數(shù)代理的角色。
public class MainApp {
public static void main(String[] args) {
OrderIF order = new OrderProxy();
Vector v = order.getAllOrders();
v = order.getAllOrders();
v = order.getAllOrders();
v = order.getAllOrders();
}
}