描述:
計(jì)數(shù)代理模式在客戶(hù)對(duì)象調(diào)用服務(wù)提供者對(duì)象上方法的前后執(zhí)行諸如日志(logging)和計(jì)數(shù)(counting)一系列附加
功能時(shí)很有用。計(jì)數(shù)代理模式建議把這些附加功能封裝在一個(gè)單獨(dú)的對(duì)象,這個(gè)對(duì)象就是指計(jì)數(shù)代理對(duì)象,而不是把這些附加的功能實(shí)現(xiàn)放到服務(wù)提供者的內(nèi)部。良
好的對(duì)象設(shè)計(jì)的一個(gè)特征就是對(duì)象要專(zhuān)注于提供特定的功能。換句話(huà)說(shuō),理想的對(duì)象不應(yīng)該做各種不相干的事情。把諸如日志(logging)和計(jì)數(shù)
(counting)等類(lèi)似的功能封裝為一個(gè)單獨(dú)的對(duì)象,而讓服務(wù)提供者對(duì)象僅提供它自己的特定功能。也就是說(shuō),只允許服務(wù)提供者對(duì)象執(zhí)行定義良好、特定
的任務(wù)。
計(jì)數(shù)代理被設(shè)計(jì)成可以被客戶(hù)訪(fǎng)問(wèn)的與服務(wù)提供者具有相同接口的對(duì)象。客戶(hù)對(duì)象不是直接訪(fǎng)問(wèn)服務(wù)提供者,而是調(diào)用計(jì)數(shù)代理對(duì)象上的方法,計(jì)數(shù)代理執(zhí)行必要的紀(jì)錄日志(logging)和計(jì)數(shù)(counting)功能后,再把方法調(diào)用傳遞給服務(wù)提供著對(duì)象。如圖1
 Figure1: Generic Class Association When the Counting Proxy Pattern Is Applied |
下面的例子說(shuō)明了如何在應(yīng)用程序中利用計(jì)數(shù)代理。
例子:
讓我們?cè)O(shè)計(jì)一個(gè)Order類(lèi),類(lèi)層次如圖2,OrderIF接口聲明了getAllOrders讀取數(shù)據(jù)庫(kù)中所有訂單的簡(jiǎn)單方法。
 Figure2: Order Class Hierarchy |
public interface OrderIF { public Vector getAllOrders(); } |
作為getAllOrders方法實(shí)現(xiàn)的一部分,Order類(lèi)實(shí)用了FileUtil工具類(lèi)從order.txt文件中讀取訂單項(xiàng)。
public class Order implements OrderIF { public Vector getAllOrders() { FileUtil fileUtil = new FileUtil(); Vector v = fileUtil.fileToVector("orders.txt"); return v; } } |
讓我們假定在調(diào)用getAllOrders()時(shí),需要把取數(shù)據(jù)文件所花費(fèi)的時(shí)間和記錄條數(shù)要記錄的log日志文件中。
這個(gè)附加的功能可以設(shè)計(jì)一個(gè)單獨(dú)的OrderProxy類(lèi)來(lái)實(shí)現(xiàn),它與真實(shí)對(duì)象Order一樣實(shí)現(xiàn)OrderIF接口。這樣保證了OrderProxy對(duì)象提供給客戶(hù)與真實(shí)對(duì)象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; } } |
客戶(hù)對(duì)象MainApp就想調(diào)用真實(shí)對(duì)象Order一樣調(diào)用OrderProxy對(duì)象上的getAllOrders()方法,OrderProxy對(duì)象
傳遞這個(gè)調(diào)用給真實(shí)對(duì)象Order,計(jì)算讀取所有訂單所花費(fèi)的時(shí)間并使用FileUtil幫助類(lèi)將其紀(jì)錄的log日志文件中。在這個(gè)過(guò)程中,
OrderProxy扮演者計(jì)數(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();
}
}